Skip to content

Commit dcaf1ea

Browse files
committed
Merge branch 1.6 into 1.7
2 parents f0de1de + 18becc3 commit dcaf1ea

File tree

9 files changed

+128
-25
lines changed

9 files changed

+128
-25
lines changed

driver/src/main/java/org/neo4j/driver/internal/async/HandshakeHandler.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,18 +165,23 @@ private static Throwable protocolNoSupportedByDriverError( int suggestedProtocol
165165

166166
private static Throwable transformError( Throwable error )
167167
{
168-
Throwable cause = error instanceof DecoderException ? error.getCause() : error;
169-
if ( cause instanceof ServiceUnavailableException )
168+
if ( error instanceof DecoderException && error.getCause() != null )
170169
{
171-
return cause;
170+
// unwrap the DecoderException if it has a cause
171+
error = error.getCause();
172172
}
173-
else if ( cause instanceof SSLHandshakeException )
173+
174+
if ( error instanceof ServiceUnavailableException )
175+
{
176+
return error;
177+
}
178+
else if ( error instanceof SSLHandshakeException )
174179
{
175-
return new SecurityException( "Failed to establish secured connection with the server", cause );
180+
return new SecurityException( "Failed to establish secured connection with the server", error );
176181
}
177182
else
178183
{
179-
return new ServiceUnavailableException( "Failed to establish connection with the server", cause );
184+
return new ServiceUnavailableException( "Failed to establish connection with the server", error );
180185
}
181186
}
182187
}

driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChannelErrorHandler.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ private void fail( ChannelHandlerContext ctx, Throwable error )
103103

104104
private static Throwable transformError( Throwable error )
105105
{
106-
if ( error instanceof CodecException )
106+
if ( error instanceof CodecException && error.getCause() != null )
107107
{
108-
// unwrap exception from message encoder/decoder
108+
// unwrap the CodecException if it has a cause
109109
error = error.getCause();
110110
}
111111

driver/src/main/java/org/neo4j/driver/internal/async/inbound/ChunkDecoder.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@
2929

3030
public class ChunkDecoder extends LengthFieldBasedFrameDecoder
3131
{
32-
private static final int MAX_FRAME_LENGTH = Short.MAX_VALUE;
32+
private static final int MAX_FRAME_BODY_LENGTH = 0xFFFF;
3333
private static final int LENGTH_FIELD_OFFSET = 0;
3434
private static final int LENGTH_FIELD_LENGTH = 2;
3535
private static final int LENGTH_ADJUSTMENT = 0;
3636
private static final int INITIAL_BYTES_TO_STRIP = LENGTH_FIELD_LENGTH;
37+
private static final int MAX_FRAME_LENGTH = LENGTH_FIELD_LENGTH + MAX_FRAME_BODY_LENGTH;
3738

3839
private final Logging logging;
3940
private Logger log;

driver/src/test/java/org/neo4j/driver/internal/async/ChannelErrorHandlerTest.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,18 @@ public void shouldHandleCodecException()
117117
assertFalse( channel.isOpen() );
118118
}
119119

120+
@Test
121+
public void shouldHandleCodecExceptionWithoutCause()
122+
{
123+
CodecException codecException = new CodecException( "Unable to encode or decode message" );
124+
channel.pipeline().fireExceptionCaught( codecException );
125+
126+
Throwable error = messageDispatcher.currentError();
127+
128+
assertEquals( codecException, error );
129+
assertFalse( channel.isOpen() );
130+
}
131+
120132
@Test
121133
public void shouldHandleIOException()
122134
{

driver/src/test/java/org/neo4j/driver/internal/async/HandshakeHandlerTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,31 @@ public void shouldUnwrapDecoderException()
187187
assertNull( await( channel.closeFuture() ) );
188188
}
189189

190+
@Test
191+
public void shouldHandleDecoderExceptionWithoutCause()
192+
{
193+
ChannelPromise handshakeCompletedPromise = channel.newPromise();
194+
HandshakeHandler handler = newHandler( handshakeCompletedPromise );
195+
channel.pipeline().addLast( handler );
196+
197+
DecoderException decoderException = new DecoderException( "Unable to decode a message" );
198+
channel.pipeline().fireExceptionCaught( decoderException );
199+
200+
try
201+
{
202+
// promise should fail
203+
await( handshakeCompletedPromise );
204+
fail( "Exception expected" );
205+
}
206+
catch ( ServiceUnavailableException e )
207+
{
208+
assertEquals( decoderException, e.getCause() );
209+
}
210+
211+
// channel should be closed
212+
assertNull( await( channel.closeFuture() ) );
213+
}
214+
190215
@Test
191216
public void shouldTranslateSSLHandshakeException()
192217
{

driver/src/test/java/org/neo4j/driver/internal/async/inbound/ChunkDecoderTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,22 @@ void shouldLogNonEmptyChunkOnTraceLevel()
182182
assertByteBufEquals( wrappedBuffer( bytes ), channel.readInbound() );
183183
}
184184

185+
@Test
186+
public void shouldDecodeMaxSizeChunk()
187+
{
188+
byte[] message = new byte[0xFFFF];
189+
190+
ByteBuf input = buffer();
191+
input.writeShort( message.length ); // chunk header
192+
input.writeBytes( message ); // chunk body
193+
194+
assertTrue( channel.writeInbound( input ) );
195+
assertTrue( channel.finish() );
196+
197+
assertEquals( 1, channel.inboundMessages().size() );
198+
assertByteBufEquals( wrappedBuffer( message ), channel.readInbound() );
199+
}
200+
185201
private static ChunkDecoder newChunkDecoder()
186202
{
187203
return new ChunkDecoder( DEV_NULL_LOGGING );

driver/src/test/java/org/neo4j/driver/v1/integration/ParametersIT.java

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import java.io.IOException;
2626
import java.util.HashMap;
27+
import java.util.List;
2728
import java.util.Map;
2829
import java.util.concurrent.ThreadLocalRandom;
2930

@@ -35,11 +36,15 @@
3536
import org.neo4j.driver.v1.exceptions.ClientException;
3637
import org.neo4j.driver.v1.exceptions.ServiceUnavailableException;
3738
import org.neo4j.driver.v1.util.TestNeo4jSession;
39+
import org.neo4j.driver.v1.util.TestUtil;
3840

41+
import static java.util.Collections.singletonMap;
42+
import static java.util.stream.Collectors.toList;
3943
import static org.hamcrest.CoreMatchers.containsString;
4044
import static org.hamcrest.CoreMatchers.equalTo;
4145
import static org.hamcrest.CoreMatchers.instanceOf;
4246
import static org.hamcrest.MatcherAssert.assertThat;
47+
import static org.junit.Assert.assertArrayEquals;
4348
import static org.junit.Assert.fail;
4449
import static org.junit.Assume.assumeFalse;
4550
import static org.junit.Assume.assumeTrue;
@@ -52,6 +57,8 @@
5257

5358
public class ParametersIT
5459
{
60+
private static final int LONG_VALUE_SIZE = 1_000_000;
61+
5562
@Rule
5663
public TestNeo4jSession session = new TestNeo4jSession();
5764

@@ -451,6 +458,35 @@ public void shouldNotBePossibleToUsePathAsParameterViaMapValue()
451458
expectIOExceptionWithMessage( mapValue, "Unknown type: PATH" );
452459
}
453460

461+
@Test
462+
public void shouldSendAndReceiveLongString()
463+
{
464+
String string = TestUtil.randomString( LONG_VALUE_SIZE );
465+
testSendAndReceiveValue( string );
466+
}
467+
468+
@Test
469+
public void shouldSendAndReceiveLongListOfLongs()
470+
{
471+
List<Long> longs = ThreadLocalRandom.current()
472+
.longs( LONG_VALUE_SIZE )
473+
.boxed()
474+
.collect( toList() );
475+
476+
testSendAndReceiveValue( longs );
477+
}
478+
479+
@Test
480+
public void shouldSendAndReceiveLongArrayOfBytes()
481+
{
482+
assumeTrue( supportsBytes() );
483+
484+
byte[] bytes = new byte[LONG_VALUE_SIZE];
485+
ThreadLocalRandom.current().nextBytes( bytes );
486+
487+
testSendAndReceiveValue( bytes );
488+
}
489+
454490
private void testBytesProperty( byte[] array )
455491
{
456492
assumeTrue( supportsBytes() );
@@ -509,4 +545,11 @@ private void expectIOExceptionWithMessage( Value value, String message )
509545
fail( "Expecting a ServiceUnavailableException but got " + e );
510546
}
511547
}
548+
549+
private void testSendAndReceiveValue( Object value )
550+
{
551+
StatementResult result = session.run( "RETURN $value", singletonMap( "value", value ) );
552+
Object receivedValue = result.single().get( 0 ).asObject();
553+
assertArrayEquals( new Object[]{value}, new Object[]{receivedValue} );
554+
}
512555
}

driver/src/test/java/org/neo4j/driver/v1/tck/DriverComplianceSteps.java

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import java.util.HashMap;
3030
import java.util.List;
3131
import java.util.Map;
32-
import java.util.Random;
3332

3433
import org.neo4j.driver.v1.Record;
3534
import org.neo4j.driver.v1.Session;
@@ -39,11 +38,12 @@
3938
import org.neo4j.driver.v1.tck.tck.util.runners.CypherStatementRunner;
4039
import org.neo4j.driver.v1.tck.tck.util.runners.StatementRunner;
4140
import org.neo4j.driver.v1.tck.tck.util.runners.StringRunner;
41+
import org.neo4j.driver.v1.util.TestUtil;
4242

4343
import static org.hamcrest.core.IsEqual.equalTo;
4444
import static org.junit.Assert.assertThat;
45-
import static org.neo4j.driver.v1.tck.Environment.driver;
4645
import static org.neo4j.driver.v1.Values.parameters;
46+
import static org.neo4j.driver.v1.tck.Environment.driver;
4747
import static org.neo4j.driver.v1.tck.Environment.expectedBoltValue;
4848
import static org.neo4j.driver.v1.tck.Environment.expectedJavaValue;
4949
import static org.neo4j.driver.v1.tck.Environment.listOfObjects;
@@ -77,9 +77,9 @@ public void a_value( String value ) throws Throwable
7777
}
7878

7979
@Given( "^a String of size (\\d+)$" )
80-
public void a_String_of_size( long size ) throws Throwable
80+
public void a_String_of_size( int size ) throws Throwable
8181
{
82-
expectedJavaValue = getRandomString( size );
82+
expectedJavaValue = TestUtil.randomString( size );
8383
expectedBoltValue = Values.value( expectedJavaValue );
8484
}
8585

@@ -191,18 +191,6 @@ public void result_should_be_equal_to_a_single_Type_of_Input() throws Throwable
191191
}
192192
}
193193

194-
public String getRandomString( long size )
195-
{
196-
StringBuilder stringBuilder = new StringBuilder();
197-
String alphabet = "abcdefghijklmnopqrstuvwxyz";
198-
Random random = new Random();
199-
while ( size-- > 0 )
200-
{
201-
stringBuilder.append( alphabet.charAt( random.nextInt( alphabet.length() ) ) );
202-
}
203-
return stringBuilder.toString();
204-
}
205-
206194
public List<Object> getListOfRandomsOfTypes( Type type, long size )
207195
{
208196
List<Object> list = new ArrayList<>();

driver/src/test/java/org/neo4j/driver/v1/util/TestUtil.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.concurrent.CompletionStage;
3030
import java.util.concurrent.ExecutionException;
3131
import java.util.concurrent.Future;
32+
import java.util.concurrent.ThreadLocalRandom;
3233
import java.util.concurrent.TimeUnit;
3334
import java.util.concurrent.TimeoutException;
3435
import java.util.function.BooleanSupplier;
@@ -57,6 +58,7 @@
5758
public final class TestUtil
5859
{
5960
private static final long DEFAULT_WAIT_TIME_MS = MINUTES.toMillis( 1 );
61+
private static final String ALPHANUMERICS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz123456789";
6062

6163
private TestUtil()
6264
{
@@ -257,6 +259,17 @@ public static void awaitCondition( BooleanSupplier condition, long value, TimeUn
257259
}
258260
}
259261

262+
public static String randomString( int size )
263+
{
264+
StringBuilder sb = new StringBuilder( size );
265+
ThreadLocalRandom random = ThreadLocalRandom.current();
266+
for ( int i = 0; i < size; i++ )
267+
{
268+
sb.append( ALPHANUMERICS.charAt( random.nextInt( ALPHANUMERICS.length() ) ) );
269+
}
270+
return sb.toString();
271+
}
272+
260273
private static void setupSuccessfulPullAll( Connection connection, String statement )
261274
{
262275
doAnswer( invocation ->

0 commit comments

Comments
 (0)