private void setUpMocks() { queryService = mock( GraphDatabaseQueryService.class ); DependencyResolver resolver = mock( DependencyResolver.class ); txBridge = mock( ThreadToStatementContextBridge.class ); initialStatement = mock( KernelStatement.class ); statistics = new ConfiguredExecutionStatistics(); QueryRegistryOperations queryRegistryOperations = mock( QueryRegistryOperations.class ); InternalTransaction internalTransaction = mock( InternalTransaction.class ); when( internalTransaction.terminationReason() ).thenReturn( Optional.empty() ); when( initialStatement.queryRegistration() ).thenReturn( queryRegistryOperations ); when( queryService.getDependencyResolver() ).thenReturn( resolver ); when( resolver.resolveDependency( ThreadToStatementContextBridge.class ) ).thenReturn( txBridge ); when( queryService.beginTransaction( any(), any() ) ).thenReturn( internalTransaction ); KernelTransaction mockTransaction = mockTransaction( initialStatement ); when( txBridge.get() ).thenReturn( initialStatement ); when( txBridge.getKernelTransactionBoundToThisThread(true ) ).thenReturn( mockTransaction ); }
@Test public void shouldNotCloseTransactionDuringTermination() { InternalTransaction tx = mock( InternalTransaction.class ); when( tx.transactionType() ).thenReturn( KernelTransaction.Type.implicit ); Neo4jTransactionalContext context = newContext( tx ); context.terminate(); verify( tx ).terminate(); verify( tx, never() ).close(); }
@Before public void setUp() { setUpMocks(); }
@Test public void shouldBeTopLevelWithImplicitTx() { InternalTransaction tx = mock( InternalTransaction.class ); when( tx.transactionType() ).thenReturn( KernelTransaction.Type.implicit ); Neo4jTransactionalContext context = newContext( tx ); assertTrue( context.isTopLevelTx() ); }
@Test public void checkKernelStatementOnCheck() { InternalTransaction initialTransaction = mock( InternalTransaction.class, new ReturnsDeepStubs() ); Kernel kernel = mock( Kernel.class ); ThreadToStatementContextBridge txBridge = mock( ThreadToStatementContextBridge.class ); KernelTransaction kernelTransaction = mockTransaction( initialStatement ); when( txBridge.getKernelTransactionBoundToThisThread( true ) ).thenReturn( kernelTransaction ); Neo4jTransactionalContext transactionalContext = new Neo4jTransactionalContext( null, txBridge, null, initialTransaction, initialStatement, null, kernel ); transactionalContext.check(); verify( kernelTransaction ).assertOpen(); }
@Test public void shouldNotBeTopLevelWithExplicitTx() { InternalTransaction tx = mock( InternalTransaction.class ); when( tx.transactionType() ).thenReturn( KernelTransaction.Type.explicit ); Neo4jTransactionalContext context = newContext( tx ); assertFalse( context.isTopLevelTx() ); }
KernelTransaction initialKTX = mockTransaction( initialStatement ); InternalTransaction initialTransaction = mock( InternalTransaction.class, new ReturnsDeepStubs() ); KernelTransaction.Type transactionType = KernelTransaction.Type.implicit; KernelTransaction secondKTX = mockTransaction( secondStatement ); InternalTransaction secondTransaction = mock( InternalTransaction.class ); when( secondTransaction.terminationReason() ).thenReturn( Optional.empty() );
@Test public void shouldBePossibleToTerminateWithoutActiveTransaction() { InternalTransaction tx = mock( InternalTransaction.class ); Neo4jTransactionalContext context = newContext( tx ); context.close( true ); verify( tx ).success(); verify( tx ).close(); context.terminate(); verify( tx, never() ).terminate(); }
KernelTransaction initialKTX = mockTransaction( initialStatement ); QueryRegistryOperations initialQueryRegistry = mock( QueryRegistryOperations.class ); ExecutingQuery executingQuery = mock( ExecutingQuery.class ); KernelTransaction secondKTX = mockTransaction( secondStatement ); InternalTransaction secondTransaction = mock( InternalTransaction.class ); when( secondTransaction.terminationReason() ).thenReturn( Optional.empty() );
@Test public void shouldBeOpenAfterCreation() { InternalTransaction tx = mock( InternalTransaction.class ); Neo4jTransactionalContext context = newContext( tx ); assertTrue( context.isOpen() ); }
@Test public void shouldBePossibleToCloseAfterTermination() { InternalTransaction tx = mock( InternalTransaction.class ); when( tx.transactionType() ).thenReturn( KernelTransaction.Type.implicit ); Neo4jTransactionalContext context = newContext( tx ); context.terminate(); verify( tx ).terminate(); verify( tx, never() ).close(); context.close( false ); verify( tx ).failure(); verify( tx ).close(); }
@Test public void shouldNotBePossibleToCloseMultipleTimes() { InternalTransaction tx = mock( InternalTransaction.class ); Neo4jTransactionalContext context = newContext( tx ); context.close( false ); context.close( true ); context.close( false ); verify( tx ).failure(); verify( tx, never() ).success(); verify( tx ).close(); }
@Test public void shouldThrowWhenRestartedAfterTermination() { MutableObject<Status> terminationReason = new MutableObject<>(); InternalTransaction tx = mock( InternalTransaction.class ); doAnswer( invocation -> { terminationReason.setValue( Status.Transaction.Terminated ); return null; } ).when( tx ).terminate(); when( tx.terminationReason() ).then( invocation -> Optional.ofNullable( terminationReason.getValue() ) ); Neo4jTransactionalContext context = newContext( tx ); context.terminate(); try { context.commitAndRestartTx(); fail( "Exception expected" ); } catch ( Exception e ) { assertThat( e, instanceOf( TransactionTerminatedException.class ) ); } }
@Test public void shouldThrowWhenGettingTxAfterTermination() { MutableObject<Status> terminationReason = new MutableObject<>(); InternalTransaction tx = mock( InternalTransaction.class ); doAnswer( invocation -> { terminationReason.setValue( Status.Transaction.Terminated ); return null; } ).when( tx ).terminate(); when( tx.terminationReason() ).then( invocation -> Optional.ofNullable( terminationReason.getValue() ) ); Neo4jTransactionalContext context = newContext( tx ); context.terminate(); try { context.getOrBeginNewIfClosed(); fail( "Exception expected" ); } catch ( Exception e ) { assertThat( e, instanceOf( TransactionTerminatedException.class ) ); } }