use of org.neo4j.bolt.v1.runtime.BoltStateMachine in project neo4j by neo4j.
the class TransactionIT method shouldTerminateQueriesEvenIfUsingPeriodicCommit.
@Test
public void shouldTerminateQueriesEvenIfUsingPeriodicCommit() throws Exception {
// Spawns a throttled HTTP server, runs a PERIODIC COMMIT that fetches data from this server,
// and checks that the query able to be terminated
// We start with 3, because that is how many actors we have -
// 1. the http server
// 2. the running query
// 3. the one terminating 2
final DoubleLatch latch = new DoubleLatch(3, true);
// This is used to block the http server between the first and second batch
final Barrier.Control barrier = new Barrier.Control();
// Serve CSV via local web server, let Jetty find a random port for us
Server server = createHttpServer(latch, barrier, 20, 30);
server.start();
int localPort = getLocalPort(server);
final BoltStateMachine[] machine = { null };
Thread thread = new Thread() {
@Override
public void run() {
try (BoltStateMachine stateMachine = env.newMachine(new BoltConnectionDescriptor(new InetSocketAddress("<testClient>", 56789), new InetSocketAddress("<writeServer>", 7468)))) {
machine[0] = stateMachine;
stateMachine.init(USER_AGENT, emptyMap(), null);
String query = format("USING PERIODIC COMMIT 10 LOAD CSV FROM 'http://localhost:%d' AS line " + "CREATE (n:A {id: line[0], square: line[1]}) " + "WITH count(*) as number " + "CREATE (n:ShouldNotExist)", localPort);
try {
latch.start();
stateMachine.run(query, emptyMap(), nullResponseHandler());
stateMachine.pullAll(nullResponseHandler());
} finally {
latch.finish();
}
} catch (BoltConnectionFatality connectionFatality) {
throw new RuntimeException(connectionFatality);
}
}
};
thread.setName("query runner");
thread.start();
// We block this thread here, waiting for the http server to spin up and the running query to get started
latch.startAndWaitForAllToStart();
Thread.sleep(1000);
// This is the call that RESETs the Bolt connection and will terminate the running query
machine[0].reset(nullResponseHandler());
barrier.release();
// We block again here, waiting for the running query to have been terminated, and for the server to have
// wrapped up and finished streaming http results
latch.finishAndWaitForAllToFinish();
// And now we check that the last node did not get created
try (Transaction ignored = env.graph().beginTx()) {
assertFalse("Query was not terminated in time - nodes were created!", env.graph().findNodes(Label.label("ShouldNotExist")).hasNext());
}
}
use of org.neo4j.bolt.v1.runtime.BoltStateMachine in project neo4j by neo4j.
the class TransactionIT method shouldReceiveBookmarkOnCommitAndPullAll.
@Test
public void shouldReceiveBookmarkOnCommitAndPullAll() throws Throwable {
// Given
BoltResponseRecorder recorder = new BoltResponseRecorder();
BoltStateMachine machine = env.newMachine(CONNECTION_DESCRIPTOR);
machine.init(USER_AGENT, emptyMap(), null);
// When
machine.run("BEGIN", emptyMap(), recorder);
machine.discardAll(recorder);
machine.run("CREATE (a:Person)", emptyMap(), recorder);
machine.discardAll(recorder);
machine.run("COMMIT", emptyMap(), recorder);
machine.pullAll(recorder);
// Then
assertThat(recorder.nextResponse(), succeeded());
assertThat(recorder.nextResponse(), succeeded());
assertThat(recorder.nextResponse(), succeeded());
assertThat(recorder.nextResponse(), succeeded());
assertThat(recorder.nextResponse(), succeeded());
assertThat(recorder.nextResponse(), succeededWithMetadata("bookmark", BOOKMARK_PATTERN));
}
use of org.neo4j.bolt.v1.runtime.BoltStateMachine in project neo4j by neo4j.
the class BoltProtocolV1Test method shouldNotTalkToChannelDirectlyOnFatalError.
@Test
public void shouldNotTalkToChannelDirectlyOnFatalError() throws Throwable {
// Given
Channel outputChannel = newChannelMock();
BoltStateMachine machine = mock(BoltStateMachine.class);
BoltProtocolV1 protocol = new BoltProtocolV1(new SynchronousBoltWorker(machine), outputChannel, NullLogService.getInstance());
verify(outputChannel).alloc();
// And given inbound data that'll explode when the protocol tries to interpret it
ByteBuf bomb = mock(ByteBuf.class);
doThrow(IOException.class).when(bomb).readableBytes();
// When
protocol.handle(mock(ChannelHandlerContext.class), bomb);
// Then the protocol should not mess with the channel (because it runs on the IO thread, and only the worker thread should produce writes)
verifyNoMoreInteractions(outputChannel);
// But instead make sure the state machine is shut down
verify(machine).close();
}
use of org.neo4j.bolt.v1.runtime.BoltStateMachine in project neo4j by neo4j.
the class BoltStateMachineTest method testPublishingError.
@Test
public void testPublishingError() throws Throwable {
// Given a new ready machine...
BoltStateMachine machine = newMachine(READY);
// ...and a result ready to be retrieved...
machine.run("RETURN 1", null, nullResponseHandler());
// ...and a handler guaranteed to break
BoltResponseRecorder recorder = new BoltResponseRecorder() {
@Override
public void onRecords(BoltResult result, boolean pull) throws Exception {
throw new RuntimeException("I've been expecting you, Mr Bond.");
}
};
// When we pull using that handler
machine.pullAll(recorder);
// Then the breakage should surface as a FAILURE
assertThat(recorder.nextResponse(), failedWithStatus(Status.General.UnknownError));
// ...and the machine should have entered a FAILED state
assertThat(machine, inState(FAILED));
}
use of org.neo4j.bolt.v1.runtime.BoltStateMachine in project neo4j by neo4j.
the class BoltMatchers method canReset.
public static Matcher<BoltStateMachine> canReset() {
return new BaseMatcher<BoltStateMachine>() {
@Override
public boolean matches(final Object item) {
final BoltStateMachine machine = (BoltStateMachine) item;
final BoltResponseRecorder recorder = new BoltResponseRecorder();
try {
machine.reset(recorder);
return recorder.responseCount() == 1 && machine.state() == READY;
} catch (BoltConnectionFatality boltConnectionFatality) {
return false;
}
}
@Override
public void describeTo(Description description) {
description.appendText("can reset");
}
};
}
Aggregations