Skip to content

Commit d3bb70a

Browse files
committed
Couple more unit tests for HandshakeHandler
1 parent 709fc45 commit d3bb70a

File tree

2 files changed

+119
-2
lines changed

2 files changed

+119
-2
lines changed

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ public void exceptionCaught( ChannelHandlerContext ctx, Throwable error )
9696
{
9797
failed = true;
9898

99-
// todo: test this unwrapping and SSLHandshakeException propagation
10099
Throwable cause = error instanceof DecoderException ? error.getCause() : error;
101100
if ( cause instanceof SSLHandshakeException )
102101
{
@@ -140,7 +139,7 @@ protected void decode( ChannelHandlerContext ctx, ByteBuf in, List<Object> out )
140139

141140
private void fail( ChannelHandlerContext ctx, Throwable error )
142141
{
143-
ctx.close().addListener( future -> handshakeCompletedPromise.setFailure( error ) );
142+
ctx.close().addListener( future -> handshakeCompletedPromise.tryFailure( error ) );
144143
}
145144

146145
private static Throwable protocolNoSupportedByServerError()

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

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,23 @@
2020

2121
import io.netty.channel.ChannelPromise;
2222
import io.netty.channel.embedded.EmbeddedChannel;
23+
import io.netty.handler.codec.DecoderException;
2324
import org.junit.After;
2425
import org.junit.Before;
2526
import org.junit.Test;
2627

28+
import java.io.IOException;
29+
import javax.net.ssl.SSLHandshakeException;
30+
2731
import org.neo4j.driver.internal.async.inbound.ChunkDecoder;
2832
import org.neo4j.driver.internal.async.inbound.InboundMessageDispatcher;
2933
import org.neo4j.driver.internal.async.inbound.InboundMessageHandler;
3034
import org.neo4j.driver.internal.async.inbound.MessageDecoder;
3135
import org.neo4j.driver.internal.async.outbound.OutboundMessageHandler;
36+
import org.neo4j.driver.internal.util.ErrorUtil;
3237
import org.neo4j.driver.v1.exceptions.ClientException;
38+
import org.neo4j.driver.v1.exceptions.SecurityException;
39+
import org.neo4j.driver.v1.exceptions.ServiceUnavailableException;
3340

3441
import static io.netty.buffer.Unpooled.copyInt;
3542
import static org.hamcrest.Matchers.instanceOf;
@@ -87,6 +94,93 @@ public void shouldFailGivenPromiseWhenExceptionCaught()
8794
assertNull( await( channel.closeFuture() ) );
8895
}
8996

97+
@Test
98+
public void shouldFailGivenPromiseWhenMultipleExceptionsCaught()
99+
{
100+
ChannelPromise handshakeCompletedPromise = channel.newPromise();
101+
HandshakeHandler handler = newHandler( handshakeCompletedPromise );
102+
channel.pipeline().addLast( handler );
103+
104+
RuntimeException error1 = new RuntimeException( "Error 1" );
105+
RuntimeException error2 = new RuntimeException( "Error 2" );
106+
channel.pipeline().fireExceptionCaught( error1 );
107+
channel.pipeline().fireExceptionCaught( error2 );
108+
109+
try
110+
{
111+
// promise should fail
112+
await( handshakeCompletedPromise );
113+
fail( "Exception expected" );
114+
}
115+
catch ( RuntimeException e )
116+
{
117+
assertEquals( error1, e );
118+
}
119+
120+
// channel should be closed
121+
assertNull( await( channel.closeFuture() ) );
122+
123+
try
124+
{
125+
channel.checkException();
126+
fail( "Exception expected" );
127+
}
128+
catch ( RuntimeException e )
129+
{
130+
assertEquals( error2, e );
131+
}
132+
}
133+
134+
@Test
135+
public void shouldUnwrapDecoderException()
136+
{
137+
ChannelPromise handshakeCompletedPromise = channel.newPromise();
138+
HandshakeHandler handler = newHandler( handshakeCompletedPromise );
139+
channel.pipeline().addLast( handler );
140+
141+
IOException cause = new IOException( "Error!" );
142+
channel.pipeline().fireExceptionCaught( new DecoderException( cause ) );
143+
144+
try
145+
{
146+
// promise should fail
147+
await( handshakeCompletedPromise );
148+
fail( "Exception expected" );
149+
}
150+
catch ( Exception e )
151+
{
152+
assertEquals( cause, e );
153+
}
154+
155+
// channel should be closed
156+
assertNull( await( channel.closeFuture() ) );
157+
}
158+
159+
@Test
160+
public void shouldTranslateSSLHandshakeException()
161+
{
162+
ChannelPromise handshakeCompletedPromise = channel.newPromise();
163+
HandshakeHandler handler = newHandler( handshakeCompletedPromise );
164+
channel.pipeline().addLast( handler );
165+
166+
SSLHandshakeException error = new SSLHandshakeException( "Invalid certificate" );
167+
channel.pipeline().fireExceptionCaught( error );
168+
169+
try
170+
{
171+
// promise should fail
172+
await( handshakeCompletedPromise );
173+
fail( "Exception expected" );
174+
}
175+
catch ( SecurityException e )
176+
{
177+
assertEquals( error, e.getCause() );
178+
}
179+
180+
// channel should be closed
181+
assertNull( await( channel.closeFuture() ) );
182+
}
183+
90184
@Test
91185
public void shouldSelectProtocolV1WhenServerSuggests()
92186
{
@@ -129,6 +223,30 @@ public void shouldFailGivenPromiseWhenServerSuggestsUnknownProtocol()
129223
testFailure( 42, "Protocol error" );
130224
}
131225

226+
@Test
227+
public void shouldFailGivenPromiseWhenChannelInactive()
228+
{
229+
ChannelPromise handshakeCompletedPromise = channel.newPromise();
230+
HandshakeHandler handler = newHandler( handshakeCompletedPromise );
231+
channel.pipeline().addLast( handler );
232+
233+
channel.pipeline().fireChannelInactive();
234+
235+
try
236+
{
237+
// promise should fail
238+
await( handshakeCompletedPromise );
239+
fail( "Exception expected" );
240+
}
241+
catch ( ServiceUnavailableException e )
242+
{
243+
assertEquals( ErrorUtil.newConnectionTerminatedError().getMessage(), e.getMessage() );
244+
}
245+
246+
// channel should be closed
247+
assertNull( await( channel.closeFuture() ) );
248+
}
249+
132250
private void testFailure( int serverSuggestedVersion, String expectedMessagePrefix )
133251
{
134252
ChannelPromise handshakeCompletedPromise = channel.newPromise();

0 commit comments

Comments
 (0)