john pfeiffer
  • Home
  • Categories
  • Tags
  • Archives

NirvanixStorageConnectorTest

//2012-12-05 johnpfeiffer
package net.kittyandbear;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URISyntaxException;
import java.rmi.UnexpectedException;
import java.util.Map;
import java.util.Properties;

import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.URIBuilder;
import org.apache.log4j.ConsoleAppender;
import org.apache.log4j.Level;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.PropertyConfigurator;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

import com.acme.storagegateway.adaptor.impl.NirvanixStorageConnector.RuleException;

public class NirvanixStorageConnectorTest {

    private NirvanixStorageConnectorStub defaultTester;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        // Configure and bind slf4j logging to use log4j
        Class<?>[] loggedClasses = { NirvanixStorageConnector.class };
        String loggingLevel = Level.INFO.toString();

        Properties props = new Properties();
        props.put( "log4j.rootLogger", loggingLevel + ", " + "R" );
        props.put( "log4j.appender.R", ConsoleAppender.class.getName() );
        props.put( "log4j.appender.R.encoding", "UTF-8" );
        props.put( "log4j.appender.R.layout", PatternLayout.class.getName() );
        props.put( "log4j.appender.R.layout.ConversionPattern", "%d %5p (%F:%L) - %m%n" );
        for( @SuppressWarnings( "rawtypes" )
        Class clazz : loggedClasses ) {
            props.put( "log4j.logger." + clazz.getName(), loggingLevel );
        }
        PropertyConfigurator.configure( props );
    }

    @Before
    public void setUp() throws Exception {
        defaultTester = new NirvanixStorageConnectorStub( "apiHostname", "https" );
    }

    // High Value Happy Path Tests
    // TODO: verify setting http for data transfer
    // TODO: verify metadata map is created and converted to JSON correctly
    @Test
    public void testValidCredentialsCanSuccessfullyGetSession() throws Exception {
        // Given: valid Nirvanix Response containing a session token
        defaultTester.setExpectedGetResponse( "{\"ResponseCode\":0,\"SessionToken\":\"7f4dcfdc-5952-4d54-8474-55a9bcc9febe\"}" );

        // When
        String sessionToken = defaultTester.getSession( "appKey", "username", "password" );

        // Then
        assertEquals( "7f4dcfdc-5952-4d54-8474-55a9bcc9febe", sessionToken );
    }

    @Test
    public void testPutFile() throws Exception {
        // Given: a good uploadToken the response after the Put should be a success from Nirvanix
        defaultTester
                .setExpectedGetResponse( "{\"ResponseCode\":0,\"GetStorageNode\":{\"UploadHost\":\"node10.nirvanix.com\",\"UploadToken\":\"OWP1_MXr~HaKbzYYef9~FODoYMDq~pS5_E3yjFR~Y6eY99Gs4hWTcptQeQ\"}}" );
        defaultTester
                .setExpectedPutResponse( "<Response>\n\t<ResponseCode>0</ResponseCode>\n\t<FilesUploaded>1</FilesUploaded>\n\t<BytesUploaded>105450</BytesUploaded>\n</Response>" );

        // When
        defaultTester.putFile( "filename", "destFolderPath", null, new ByteArrayInputStream( "testdata".getBytes() ), "sessionToken",
                "testdata".getBytes().length );

        // Then : Should complete with no Exceptions
    }

    @Test( expected = IOException.class )
    public void testPutFileReceivesInvalidPathError() throws Exception {
        // Given: a good uploadToken but Nirvanix response is code "upload aborted" which parses and translates into an IOException
        defaultTester
                .setExpectedGetResponse( "{\"ResponseCode\":0,\"GetStorageNode\":{\"UploadHost\":\"node10.nirvanix.com\",\"UploadToken\":\"OWP1_MXr~HaKbzYYef9~FODoYMDq~pS5_E3yjFR~Y6eY99Gs4hWTcptQeQ\"}}" );
        defaultTester
                .setExpectedPutResponse( "<Response>\n\t<ResponseCode>70122</ResponseCode>\n\t<FilesUploaded>1</FilesUploaded>\n\t<BytesUploaded>105450</BytesUploaded>\n</Response>" );

        // When
        defaultTester.putFile( "filename", "destFolderPath", null, new ByteArrayInputStream( "testdata".getBytes() ), "sessionToken",
                "testdata".getBytes().length );

        // Then : should throw IOException
    }

    @Test
    public void testGetSingleMetadataValueUsingMetadataKeyLengthOneHundredCharacters() throws Exception {
        // Given: a single reponse with metadata "testkey"
        String testKey = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy";
        String testValue = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz";
        defaultTester
                .setExpectedGetResponse( "{\"ResponseCode\":0,\"Metadata\":[{\"Type\":\"MD5\",\"Value\":\"md5stringblahblah\"},{\"Type\":\""
                        + testKey + "\",\"Value\":\"" + testValue + "\"}]}\"" );

        // When
        // Then: verify successfully received a map with the correct metadata
        assertEquals( testValue, defaultTester.getMetadata( "fileId", testKey, "sessionToken" ) );
    }

    @Test( expected = RuleException.class )
    public void testMetadataKeyMissingThrowsRuleException() throws Exception {
        // Given: a single reponse without metadata "testkey"
        defaultTester
                .setExpectedGetResponse( "{\"ResponseCode\":0,\"Metadata\":[{\"Type\":\"MD5\",\"Value\":\"md5stringblahblah\"},{\"Type\":\"NOTtestkey\",\"Value\":\"testvalue\"}]}\"" );

        // When
        // Then: verify successfully received a map with the correct metadata
        assertEquals( "testvalue", defaultTester.getMetadata( "fileId", "testkey", "sessionToken" ) ); // ResponseCategory.GetMetadataValueNotFound.code
    }

    @Test
    public void testGetThreeMetadataOfLengthOneHundredCharacters() throws Exception {
        // Given: a successful reponse with three metadata entries of 100 characters each
        String meta1 = "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";
        String meta2 = "2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222";
        String meta3 = "3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333";
        defaultTester
                .setExpectedGetResponse( "{\"ResponseCode\":0,\"Metadata\":[{\"Type\":\"MD5\",\"Value\":\"0TOiwDQuBcUX9d9EzRwSHA==\"},{\"Type\":\""
                        + meta1
                        + "\",\"Value\":\""
                        + meta1
                        + "\"},{\"Type\":\""
                        + meta2
                        + "\",\"Value\":\""
                        + meta2
                        + "\"},{\"Type\":\""
                        + meta3 + "\",\"Value\":\"" + meta3 + "\"}]} " );

        // When
        Map<String, String> metadataMap = defaultTester.getMetadata( "fileId", "sessionToken" );

        // Then: verify successfully received a map with the correct metadata
        assertEquals( meta1, metadataMap.get( meta1 ) );
        assertEquals( meta2, metadataMap.get( meta2 ) );
        assertEquals( meta3, metadataMap.get( meta3 ) );
    }

    @Test
    public void testGetFile() throws Exception {
        // Given: an inner class to override the expected response when querying for a downloadURL and successful download response
        class NirvanixRestConnectorStubStream extends NirvanixStorageConnector {

            InputStream expectedResult;
            String expectedDownloadUrl;

            public NirvanixRestConnectorStubStream( String apiHostname, String dataTransferProtocol ) throws RuleException {
                super();
            }

            void setExpectedGetResponse( InputStream expected ) {
                this.expectedResult = expected;
            }

            void setExpectedDownloadUrl( String expected ) {
                this.expectedDownloadUrl = expected;
            }

            @Override
            protected URI getDownloadURI( String filePath, String sessionToken ) throws SystemException, UnexpectedException, IOException {
                URI uri = null;
                try {
                    uri = new URI( this.expectedDownloadUrl );
                } catch( URISyntaxException e ) {
                    e.printStackTrace();
                }
                return uri;
            }

            @Override
            protected InputStream executeHttpAndGetResponseAsStream( URI uri ) throws ClientProtocolException, IOException {
                return expectedResult;
            }

        }
        NirvanixRestConnectorStubStream test = new NirvanixRestConnectorStubStream( "apiHostname", "https" );

        // Given: a downloadURL in the correct format
        test.setExpectedDownloadUrl( "https://node10.nirvanix.com/rW_DJwIA~gjwilCCs_n~sxObI6dk~5TZAaSO2B-~l30COJw/Test_QA/TESTQA/acme-test-bucket/f83bdd54-7472-431f-922f-58796d957662" );

        // Given: test data as a stream
        String testdata = "testdatastream\nsecond line\n";
        InputStream testdataInputStream = new ByteArrayInputStream( testdata.getBytes() );
        test.setExpectedGetResponse( testdataInputStream );

        // When
        InputStream testGet = test.getFile( "fileId", "sessionToken" );

        StringBuilder resultData = new StringBuilder();
        BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( testGet ) );
        if( bufferedReader != null ) {
            try {
                String line = null;
                while( (line = bufferedReader.readLine()) != null ) {
                    resultData.append( line ).append( "\n" );
                }
            } finally {
                bufferedReader.close();
            }
        }

        // Then: the stream we read out was the same we started with
        assertEquals( testdata, resultData.toString() );
    }

    @Test
    public void testDeleteExistingFile() throws Exception {
        // Given: a valid success response from Nirvanix
        defaultTester.setExpectedGetResponse( "{\"ResponseCode\":0}" );
        String knownExistingFile = "Test_QA/17aec2e6-d125-4174-8c55-9f70b77269e4";

        // When
        defaultTester.delete( knownExistingFile, "sessionToken" );

        // Then : should complete with no error
    }

    @Test( expected = UnexpectedException.class )
    public void testGetsUnexpectedException() throws Exception {
        // Given: invalid error message code response from Nirvanix, InvalidImageDimensions(70111) has nothing to do with delete
        defaultTester.setExpectedGetResponse( "{\"ResponseCode\":70111}" );
        String knownExistingFile = "Test_QA/17aec2e6-d125-4174-8c55-9f70b77269e4";

        // When
        try {
            defaultTester.delete( knownExistingFile, "sessionToken" );
        } catch( UnexpectedException e ) { // Then: output the Exception to console for manual verification
            System.out.println( "SUCCESSFULLY threw UnexpectedException," + e.getMessage() + "," + e.getClass().getName() );
            defaultTester.delete( "fileId", "sessionToken" ); // repeat in order to pass the test
        }
    }

    @Test( expected = NirvanixStorageConnector.SystemException.class )
    public void testGetsSystemException() throws Exception {
        // Given: error response from Nirvanix RestrictedIPAddress(80104) means the Nirvanix Support must modify the Customer's Account
        defaultTester.setExpectedGetResponse( "{\"ResponseCode\":80104}" );

        // When
        try {
            defaultTester.delete( "fileId", "sessionToken" );
        } catch( NirvanixStorageConnector.SystemException e ) { // Then: output the Exception to console for manual verification
            System.out.println( "SUCCESSFULLY threw SystemException," + e.getMessage() + "," + e.getClass().getName() );
            defaultTester.delete( "fileId", "sessionToken" ); // repeat in order to pass the test
        }
    }

    // Lower Value but still useful (input validation tests and edge case exceptions)

    @Test( expected = UnexpectedException.class )
    public void testJSONExceptionThrownAsUnexpectedException() throws Exception {
        // Given: an invalid JSON Object
        defaultTester.setExpectedGetResponse( "{\"ResponseCode\"::80104}" );

        // When
        try {
            defaultTester.delete( "fileId", "sessionToken" );
        } catch( UnexpectedException e ) { // Then: output the Exception to console for manual verification
            System.out.println( "SUCCESSFULLY threw UnexpectedException," + e.getMessage() + "," + e.getClass().getName() );
            defaultTester.delete( "fileId", "sessionToken" ); // repeat in order to pass the test
        }
    }

    @Test
    @Ignore( "" )
    public void testConstructorInstantiatesAnHttpClient() {
        assertNotNull( NirvanixStorageConnector.httpclient );
    }

    @Test( expected = NirvanixStorageConnector.SystemException.class )
    public void testConstructorApiHostnameNullThrowsSystemException() throws Exception {
        NirvanixStorageConnector connector = new NirvanixStorageConnector();
        connector.setApiHostname( null );
        connector.initialization();
    }

    @Test( expected = NirvanixStorageConnector.SystemException.class )
    public void testConstructorApiHostnameEmptyThrowsSystemException() throws Exception {
        NirvanixStorageConnector connector = new NirvanixStorageConnector();
        connector.setApiHostname( "" );
        connector.initialization();
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    @Ignore( "NirvanixConnector uses https by default for data transfer - setHttps is optional  " )
    public void testConstructorDataTransferProtocolNullThrowsRuleException() throws Exception {
        NirvanixStorageConnector connector = new NirvanixStorageConnector();
        connector.setHttps( true );
        connector.initialization();
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    @Ignore( "NirvanixConnector uses https by default for data transfer - setHttps is optional  " )
    public void testConstructorDataTransferProtocolEmptyThrowsRuleException() throws Exception {
        NirvanixStorageConnector connector = new NirvanixStorageConnector();
        connector.setHttps( false );
        connector.initialization();
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetSessionAppKeyNullThrowsRuleException() throws Exception {
        defaultTester.getSession( null, "username", "password" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetSessionAppKeyEmptyThrowsRuleException() throws Exception {
        defaultTester.getSession( "", "username", "password" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetSessionUsernameNullThrowsRuleException() throws Exception {
        defaultTester.getSession( "appKey", null, "password" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetSessionUsernameEmptyThrowsRuleException() throws Exception {
        defaultTester.getSession( "appKey", "", "password" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetSessionPasswordNullThrowsRuleException() throws Exception {
        defaultTester.getSession( "appKey", "username", null );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetSessionPasswordEmptyThrowsRuleException() throws Exception {
        defaultTester.getSession( "appKey", "username", "" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testPutFileFilenameNull() throws Exception {
        defaultTester.putFile( null, "destFolderPath", null, new ByteArrayInputStream( "testdata".getBytes() ), "sessionToken",
                "testdata".getBytes().length );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testPutFileFilenameEmpty() throws Exception {
        defaultTester.putFile( "", "destFolderPath", null, new ByteArrayInputStream( "testdata".getBytes() ), "sessionToken",
                "testdata".getBytes().length );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testPutFileDestPathNull() throws Exception {
        defaultTester.putFile( "filename", null, null, new ByteArrayInputStream( "testdata".getBytes() ), "sessionToken",
                "testdata".getBytes().length );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testPutFileDestPathEmpty() throws Exception {
        defaultTester.putFile( "filename", "", null, new ByteArrayInputStream( "testdata".getBytes() ), "sessionToken",
                "testdata".getBytes().length );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testPutFileSessionTokenNull() throws Exception {
        defaultTester.putFile( "filename", "destFolderPath", null, new ByteArrayInputStream( "testdata".getBytes() ), null,
                "testdata".getBytes().length );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testPutFileSessionTokenEmpty() throws Exception {
        defaultTester.putFile( "filename", "destFolderPath", null, new ByteArrayInputStream( "testdata".getBytes() ), "",
                "testdata".getBytes().length );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testPutFileDataNull() throws Exception {
        defaultTester.putFile( "filename", "destFolderPath", null, null, "sessionToken", "testdata".getBytes().length );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataFilenameNull() throws Exception {
        defaultTester.getMetadata( null, "key", "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataFilenameEmpty() throws Exception {
        defaultTester.getMetadata( "", "key", "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataKeyNull() throws Exception {
        defaultTester.getMetadata( "", null, "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataKeyEmpty() throws Exception {
        defaultTester.getMetadata( "", "", "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataSessionTokenNull() throws Exception {
        defaultTester.getMetadata( "filename", "key", null );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataSessionTokenEmpty() throws Exception {
        defaultTester.getMetadata( "filename", "key", "" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataMapFilenameNull() throws Exception {
        defaultTester.getMetadata( null, "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataMapFilenameEmpty() throws Exception {
        defaultTester.getMetadata( "", "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataMapSessionTokenNull() throws Exception {
        defaultTester.getMetadata( "filename", null );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetMetadataMapSessionTokenEmpty() throws Exception {
        defaultTester.getMetadata( "filename", "" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetFileFileIdNull() throws Exception {
        defaultTester.getFile( null, "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetFileFileIdEmpty() throws Exception {
        defaultTester.getFile( "", "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetFileSessionTokenNull() throws Exception {
        defaultTester.getFile( "filename", null );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testGetFileSessionTokenEmpty() throws Exception {
        defaultTester.getFile( "filename", "" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testDeleteFileIdNull() throws Exception {
        defaultTester.delete( null, "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testDeleteFileIdEmpty() throws Exception {
        defaultTester.delete( "", "sessionToken" );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testDeleteSessionTokenNull() throws Exception {
        defaultTester.delete( "filename", null );
    }

    @Test( expected = NirvanixStorageConnector.RuleException.class )
    public void testDeleteSessionTokenEmpty() throws Exception {
        defaultTester.delete( "filename", "" );
    }

    // Helper stub used in many test methods to return expected responses
    class NirvanixStorageConnectorStub extends NirvanixStorageConnector {

        String expectedGetResult;
        String expectedPutResult;

        public NirvanixStorageConnectorStub( String apiHostname, String dataTransferProtocol ) throws SystemException {
            super();
            this.setApiHostname( "validApiHostname" );
            this.initialization();
        }

        void setExpectedGetResponse( String expected ) {
            this.expectedGetResult = expected;
        }

        void setExpectedPutResponse( String expected ) {
            this.expectedPutResult = expected;
        }

        @Override
        protected String executeHttp( URIBuilder uriBuilder ) throws ClientProtocolException, IOException {
            return expectedGetResult;
        }

        @Override
        protected String executeHttpPost( HttpUriRequest method ) throws ClientProtocolException, IOException {
            return expectedPutResult;
        }
    }

} // end class

  • « Ip address is valid function
  • NirvanixStorageConnector »

Published

Dec 5, 2012

Category

java-classes

~1325 words

Tags

  • classes 92
  • java 252
  • nirvanixstorageconnectortest 1