Skip to content

Commit

Permalink
Added more tests according to review
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhen Li authored and zhenlineo committed Aug 1, 2018
1 parent afd8b02 commit 83e0068
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 20 deletions.
Expand Up @@ -25,15 +25,16 @@
import org.neo4j.bolt.runtime.BoltQuerySource; import org.neo4j.bolt.runtime.BoltQuerySource;
import org.neo4j.bolt.runtime.StateMachineContext; import org.neo4j.bolt.runtime.StateMachineContext;
import org.neo4j.bolt.runtime.StatementProcessor; import org.neo4j.bolt.runtime.StatementProcessor;
import org.neo4j.bolt.security.auth.AuthenticationResult;
import org.neo4j.values.storable.Values; import org.neo4j.values.storable.Values;


public class BoltAuthenticationResult public class BoltAuthenticationHelper
{ {
public static boolean processAuthentication( String userAgent, Map<String,Object> authToken, StateMachineContext context ) throws BoltConnectionFatality public static boolean processAuthentication( String userAgent, Map<String,Object> authToken, StateMachineContext context ) throws BoltConnectionFatality
{ {
try try
{ {
org.neo4j.bolt.security.auth.AuthenticationResult authResult = context.boltSpi().authenticate( authToken ); AuthenticationResult authResult = context.boltSpi().authenticate( authToken );
String username = authResult.getLoginContext().subject().username(); String username = authResult.getLoginContext().subject().username();
context.authenticatedAsUser( username ); context.authenticatedAsUser( username );


Expand All @@ -56,7 +57,7 @@ public static boolean processAuthentication( String userAgent, Map<String,Object
} }
} }


private static StatementProcessor newStatementProcessor( String username, String userAgent, org.neo4j.bolt.security.auth.AuthenticationResult authResult, private static StatementProcessor newStatementProcessor( String username, String userAgent, AuthenticationResult authResult,
StateMachineContext context ) StateMachineContext context )
{ {
TransactionStateMachine statementProcessor = new TransactionStateMachine( context.boltSpi().transactionSpi(), authResult, context.clock() ); TransactionStateMachine statementProcessor = new TransactionStateMachine( context.boltSpi().transactionSpi(), authResult, context.clock() );
Expand Down
Expand Up @@ -27,7 +27,7 @@
import org.neo4j.bolt.runtime.StateMachineContext; import org.neo4j.bolt.runtime.StateMachineContext;
import org.neo4j.bolt.v1.messaging.request.InitMessage; import org.neo4j.bolt.v1.messaging.request.InitMessage;


import static org.neo4j.bolt.v1.runtime.BoltAuthenticationResult.processAuthentication; import static org.neo4j.bolt.v1.runtime.BoltAuthenticationHelper.processAuthentication;
import static org.neo4j.util.Preconditions.checkState; import static org.neo4j.util.Preconditions.checkState;


/** /**
Expand Down
Expand Up @@ -28,7 +28,7 @@
import org.neo4j.bolt.v3.messaging.request.HelloMessage; import org.neo4j.bolt.v3.messaging.request.HelloMessage;
import org.neo4j.values.storable.Values; import org.neo4j.values.storable.Values;


import static org.neo4j.bolt.v1.runtime.BoltAuthenticationResult.processAuthentication; import static org.neo4j.bolt.v1.runtime.BoltAuthenticationHelper.processAuthentication;
import static org.neo4j.util.Preconditions.checkState; import static org.neo4j.util.Preconditions.checkState;


/** /**
Expand Down
Expand Up @@ -278,6 +278,33 @@ public void describeTo( Description description )
}; };
} }


public static Matcher<TransportConnection> serverImmediatelyDisconnects()
{
return new TypeSafeMatcher<TransportConnection>()
{
@Override
protected boolean matchesSafely( TransportConnection connection )
{
try
{
connection.recv( 1 );
}
catch ( Exception e )
{
// take an IOException on send/receive as evidence of disconnection
return e instanceof IOException;
}
return false;
}

@Override
public void describeTo( Description description )
{
description.appendText( "Eventually Disconnects" );
}
};
}

public interface MessageEncoder public interface MessageEncoder
{ {
byte[] encode( Neo4jPack neo4jPack, RequestMessage... messages ) throws IOException; byte[] encode( Neo4jPack neo4jPack, RequestMessage... messages ) throws IOException;
Expand Down
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2002-2018 "Neo4j,"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.bolt.v3.messaging.decoder;

import org.junit.jupiter.api.Test;

import org.neo4j.bolt.messaging.RequestMessageDecoder;
import org.neo4j.bolt.runtime.BoltConnection;
import org.neo4j.bolt.runtime.BoltResponseHandler;
import org.neo4j.bolt.v3.messaging.request.GoodbyeMessage;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.neo4j.bolt.v3.messaging.decoder.HelloMessageDecoderTest.assertOriginalMessageEqualsToDecoded;
import static org.neo4j.bolt.v3.messaging.request.GoodbyeMessage.GOODBYE_MESSAGE;

class GoodbyeMessageDecoderTest
{
private final BoltResponseHandler responseHandler = mock( BoltResponseHandler.class );
private final BoltConnection connection = mock( BoltConnection.class );
private final RequestMessageDecoder decoder = new GoodbyeMessageDecoder( connection, responseHandler );

@Test
void shouldReturnCorrectSignature()
{
assertEquals( GoodbyeMessage.SIGNATURE, decoder.signature() );
}

@Test
void shouldReturnConnectResponseHandler()
{
assertEquals( responseHandler, decoder.responseHandler() );
}

@Test
void shouldDecodeGoodbyeMessage() throws Exception
{
assertOriginalMessageEqualsToDecoded( GOODBYE_MESSAGE, decoder );
verify( connection ).stop();
}
}
Expand Up @@ -19,19 +19,24 @@
*/ */
package org.neo4j.bolt.v3.runtime.integration; package org.neo4j.bolt.v3.runtime.integration;


import org.hamcrest.Description;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher; import org.hamcrest.TypeSafeMatcher;
import org.junit.Test; import org.junit.Test;


import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.BooleanSupplier;


import org.neo4j.bolt.v1.messaging.request.ResetMessage; import org.neo4j.bolt.v1.messaging.request.ResetMessage;
import org.neo4j.bolt.v1.transport.socket.client.TransportConnection; import org.neo4j.bolt.v1.transport.integration.Neo4jWithSocket;
import org.neo4j.bolt.v3.messaging.request.BeginMessage; import org.neo4j.bolt.v3.messaging.request.BeginMessage;
import org.neo4j.bolt.v3.messaging.request.RunMessage; import org.neo4j.bolt.v3.messaging.request.RunMessage;
import org.neo4j.function.Predicates;
import org.neo4j.kernel.api.KernelTransactionHandle;
import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.api.exceptions.Status;
import org.neo4j.kernel.impl.api.KernelTransactions;
import org.neo4j.kernel.internal.GraphDatabaseAPI;


import static java.util.Arrays.asList; import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.allOf;
Expand All @@ -43,6 +48,7 @@
import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgFailure; import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgFailure;
import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgSuccess; import static org.neo4j.bolt.v1.messaging.util.MessageMatchers.msgSuccess;
import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.eventuallyReceives; import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.eventuallyReceives;
import static org.neo4j.bolt.v1.transport.integration.TransportTestUtil.serverImmediatelyDisconnects;
import static org.neo4j.bolt.v3.messaging.request.GoodbyeMessage.GOODBYE_MESSAGE; import static org.neo4j.bolt.v3.messaging.request.GoodbyeMessage.GOODBYE_MESSAGE;


public class GoodbyeMessageIT extends BoltV3TransportBase public class GoodbyeMessageIT extends BoltV3TransportBase
Expand Down Expand Up @@ -90,6 +96,7 @@ public void shouldCloseConnectionInStreaming() throws Throwable


// Then // Then
assertThat( connection, serverImmediatelyDisconnects() ); assertThat( connection, serverImmediatelyDisconnects() );
assertThat( server, eventuallyClosesTransaction() );
} }


@Test @Test
Expand Down Expand Up @@ -126,6 +133,7 @@ public void shouldCloseConnectionInTxReady() throws Throwable


// Then // Then
assertThat( connection, serverImmediatelyDisconnects() ); assertThat( connection, serverImmediatelyDisconnects() );
assertThat( server, eventuallyClosesTransaction() );
} }


@Test @Test
Expand All @@ -138,11 +146,12 @@ public void shouldCloseConnectionInTxStreaming() throws Throwable
connection.send( util.chunk( new BeginMessage(), new RunMessage( "UNWIND [1,2,3] AS a RETURN a, a * a AS a_squared" ) ) ); connection.send( util.chunk( new BeginMessage(), new RunMessage( "UNWIND [1,2,3] AS a RETURN a, a * a AS a_squared" ) ) );
Matcher<Map<? extends String,?>> entryFieldMatcher = hasEntry( is( "fields" ), equalTo( asList( "a", "a_squared" ) ) ); Matcher<Map<? extends String,?>> entryFieldMatcher = hasEntry( is( "fields" ), equalTo( asList( "a", "a_squared" ) ) );
assertThat( connection, util.eventuallyReceives( msgSuccess(), msgSuccess( allOf( entryFieldMatcher, hasKey( "t_first" ) ) ) ) ); assertThat( connection, util.eventuallyReceives( msgSuccess(), msgSuccess( allOf( entryFieldMatcher, hasKey( "t_first" ) ) ) ) );

// you shall be in the tx_streaming state now // you shall be in the tx_streaming state now
connection.send( util.chunk( GOODBYE_MESSAGE ) ); connection.send( util.chunk( GOODBYE_MESSAGE ) );

// Then // Then
assertThat( connection, serverImmediatelyDisconnects() ); assertThat( connection, serverImmediatelyDisconnects() );
assertThat( server, eventuallyClosesTransaction() );
} }


@Test @Test
Expand All @@ -158,31 +167,36 @@ public void shouldDropConnectionImmediatelyAfterGoodbye() throws Throwable
assertThat( connection, serverImmediatelyDisconnects() ); assertThat( connection, serverImmediatelyDisconnects() );
} }


private static Matcher<TransportConnection> serverImmediatelyDisconnects() private static Matcher<Neo4jWithSocket> eventuallyClosesTransaction()
{ {
return new TypeSafeMatcher<TransportConnection>() return new TypeSafeMatcher<Neo4jWithSocket>()
{ {
@Override @Override
protected boolean matchesSafely( TransportConnection connection ) public void describeTo( org.hamcrest.Description description )
{
description.appendText( "Eventually close all transactions" );
}

@Override
protected boolean matchesSafely( Neo4jWithSocket server )
{ {
BooleanSupplier condition = () -> getActiveTransactions( server ).size() == 0;
try try
{ {
connection.recv( 1 ); Predicates.await( condition, 2, TimeUnit.SECONDS );
return true;
} }
catch ( Exception e ) catch ( Exception e )
{ {
// take an IOException on send/receive as evidence of disconnection return false;
return e instanceof IOException;
} }
return false;
} }


@Override private Set<KernelTransactionHandle> getActiveTransactions( Neo4jWithSocket server )
public void describeTo( Description description )
{ {
description.appendText( "Eventually Disconnects" ); GraphDatabaseAPI gdb = (GraphDatabaseAPI) server.graphDatabaseService();
return gdb.getDependencyResolver().resolveDependency( KernelTransactions.class ).activeTransactions();
} }
}; };
} }

} }

0 comments on commit 83e0068

Please sign in to comment.