public void testOrderedIncoming() throws Exception { TransactionBatchContext batch1 = transactionBatch(0, 1, 2); TransactionBatchContext batch2 = transactionBatch(1, 2, 3); sequencer.goToActiveMode(); sequencer.addResentServerTransactionIDs(batch2.getTransactionIDs()); sequencer.addResentServerTransactionIDs(batch1.getTransactionIDs()); sequencer.transactionManagerStarted(clientIDs(0, 1)); // Add a batch that isn't resent, should be processed last TransactionBatchContext batch3 = transactionBatch(0, 4, 5); TransactionBatchContext batch4 = transactionBatch(1, 4, 5); sequencer.addTransactions(batch3); sequencer.addTransactions(batch4); sequencer.addTransactions(batch2); sequencer.addTransactions(batch1); ArgumentCaptor<Map> c = ArgumentCaptor.<Map>forClass(Map.class); ArgumentCaptor<NodeID> n = ArgumentCaptor.<NodeID>forClass(NodeID.class); InOrder inOrder = inOrder(replicatedObjectManager, transactionManager); inOrder.verify(transactionManager).incomingTransactions(n.capture(), c.capture()); inOrder.verify(replicatedObjectManager).relayTransactions(batch1); inOrder.verify(transactionManager).incomingTransactions(n.capture(), c.capture()); inOrder.verify(replicatedObjectManager).relayTransactions(batch2); inOrder.verify(transactionManager).incomingTransactions(n.capture(), c.capture()); inOrder.verify(replicatedObjectManager).relayTransactions(batch3); inOrder.verify(transactionManager).incomingTransactions(n.capture(), c.capture()); inOrder.verify(replicatedObjectManager).relayTransactions(batch4); verifyBatches(true, c, batch1, batch2, batch3, batch4); }
private void verifyBatches( boolean isResent, ArgumentCaptor<Map> captor, TransactionBatchContext... batch) { List<Map> actual = captor.getAllValues(); Iterator<Map> itr = actual.iterator(); for (TransactionBatchContext tb : batch) { Map am = itr.next(); for (ServerTransactionID tid : tb.getTransactionIDs()) { ServerTransaction actualTxn = (ServerTransaction) am.get(tid); assertNotNull(tid.toString(), actualTxn); assertEquals(tid.toString(), isResent, actualTxn instanceof ResentServerTransaction); } } }
public void testCallbackOnResentComplete() throws Exception { sequencer.callBackOnResentTxnsInSystemCompletion(callBack); sequencer.goToActiveMode(); TransactionBatchContext context = transactionBatch(0, 1, 2, 3); sequencer.addResentServerTransactionIDs(context.getTransactionIDs()); verify(transactionManager, never()).callBackOnTxnsInSystemCompletion(callBack); sequencer.transactionManagerStarted(clientIDs(0)); verify(transactionManager, never()).callBackOnTxnsInSystemCompletion(callBack); sequencer.addTransactions(context); verify(transactionManager).callBackOnTxnsInSystemCompletion(callBack); }
public void testResentTxnWrapping() throws Exception { TransactionBatchContext batch1 = transactionBatch(0, 1, 2); TransactionBatchContext batch2 = transactionBatch(1, 2, 3); sequencer.goToActiveMode(); sequencer.addResentServerTransactionIDs(batch2.getTransactionIDs()); sequencer.addResentServerTransactionIDs(batch1.getTransactionIDs()); sequencer.transactionManagerStarted(clientIDs(0, 1)); sequencer.addTransactions(batch2); sequencer.addTransactions(batch1); // Add non-resent batches (pass through mode) TransactionBatchContext batch3 = transactionBatch(0, 4, 5); TransactionBatchContext batch4 = transactionBatch(1, 4, 5); sequencer.addTransactions(batch3); sequencer.addTransactions(batch4); ArgumentCaptor<Map> c = ArgumentCaptor.<Map>forClass(Map.class); ArgumentCaptor<NodeID> n = ArgumentCaptor.<NodeID>forClass(NodeID.class); InOrder inOrder = inOrder(replicatedObjectManager, transactionManager); inOrder.verify(transactionManager).incomingTransactions(n.capture(), c.capture()); inOrder.verify(replicatedObjectManager).relayTransactions(batch1); inOrder.verify(transactionManager).incomingTransactions(n.capture(), c.capture()); inOrder.verify(replicatedObjectManager).relayTransactions(batch2); verifyBatches(true, c, batch1, batch2); // reset arg captor c = ArgumentCaptor.<Map>forClass(Map.class); inOrder.verify(transactionManager).incomingTransactions(n.capture(), c.capture()); inOrder.verify(replicatedObjectManager).relayTransactions(batch3); inOrder.verify(transactionManager).incomingTransactions(n.capture(), c.capture()); inOrder.verify(replicatedObjectManager).relayTransactions(batch4); verifyBatches(false, c, batch3, batch4); }
public void testClientDisconnect() throws Exception { sequencer.callBackOnResentTxnsInSystemCompletion(callBack); sequencer.goToActiveMode(); TransactionBatchContext batch1 = transactionBatch(0, 1); TransactionBatchContext batch2 = transactionBatch(1, 1); TransactionBatchContext batch3 = transactionBatch(2, 1); sequencer.addResentServerTransactionIDs(batch1.getTransactionIDs()); sequencer.addResentServerTransactionIDs(batch2.getTransactionIDs()); sequencer.addResentServerTransactionIDs(batch3.getTransactionIDs()); sequencer.transactionManagerStarted(clientIDs(0, 1, 2)); sequencer.addTransactions(batch2); sequencer.clearAllTransactionsFor(batch2.getSourceNodeID()); sequencer.addTransactions(batch3); sequencer.addTransactions(batch1); InOrder inOrder = inOrder(transactionManager); inOrder .verify(transactionManager) .incomingTransactions( eq(batch1.getSourceNodeID()), argThat(hasServerTransactions(serverTransactionID(0, 1)))); inOrder .verify(transactionManager) .incomingTransactions( eq(batch2.getSourceNodeID()), argThat(hasServerTransactions(serverTransactionID(1, 1)))); inOrder .verify(transactionManager) .incomingTransactions( eq(batch3.getSourceNodeID()), argThat(hasServerTransactions(serverTransactionID(2, 1)))); inOrder.verify(transactionManager).callBackOnTxnsInSystemCompletion(callBack); }
public void testDiscontinuousGIDInOrder() throws Exception { // Cut batch1 into 2 sub-batches based on the GID split, batch2 is just 1 batch sitting between // batch1 part1 and batch1 part2 when(gtxm.getGlobalTransactionID(serverTransactionID(0, 1))) .thenReturn(new GlobalTransactionID(0)); when(gtxm.getGlobalTransactionID(serverTransactionID(1, 1))) .thenReturn(new GlobalTransactionID(1)); when(gtxm.getGlobalTransactionID(serverTransactionID(0, 2))) .thenReturn(new GlobalTransactionID(2)); TransactionBatchContext batch1 = transactionBatch(0, 1, 2); TransactionBatchContext batch2 = transactionBatch(1, 1); sequencer.goToActiveMode(); sequencer.addResentServerTransactionIDs(batch1.getTransactionIDs()); sequencer.addResentServerTransactionIDs(batch2.getTransactionIDs()); sequencer.transactionManagerStarted(clientIDs(0, 1)); sequencer.addTransactions(batch1); sequencer.addTransactions(batch2); InOrder inOrder = inOrder(transactionManager, replicatedObjectManager); // Make sure transactions are passed through and relayed in 3 chunks (1 per GID range) in the // correct order inOrder .verify(transactionManager) .incomingTransactions( eq(batch1.getSourceNodeID()), argThat(hasServerTransactions(serverTransactionID(0, 1)))); inOrder .verify(replicatedObjectManager) .relayTransactions(argThat(hasClientIDAndTxns(0, serverTransactionID(0, 1)))); inOrder .verify(transactionManager) .incomingTransactions( eq(batch2.getSourceNodeID()), argThat(hasServerTransactions(serverTransactionID(1, 1)))); inOrder .verify(replicatedObjectManager) .relayTransactions(argThat(hasClientIDAndTxns(1, serverTransactionID(1, 1)))); inOrder .verify(transactionManager) .incomingTransactions( eq(batch1.getSourceNodeID()), argThat(hasServerTransactions(serverTransactionID(0, 2)))); inOrder .verify(replicatedObjectManager) .relayTransactions(argThat(hasClientIDAndTxns(0, serverTransactionID(0, 2)))); }
private TransactionBatchContext transactionBatch(long clientId, long... transactionIds) { TransactionBatchContext context = mock(TransactionBatchContext.class); List<ServerTransaction> transactions = new ArrayList<ServerTransaction>(); List<ServerTransactionID> ids = transactionIDs(clientId, transactionIds); for (ServerTransactionID stxId : ids) { ServerTransaction transaction = mock(ServerTransaction.class); GlobalTransactionID globalTransactionID = getOrCreateGID(stxId); when(transaction.getGlobalTransactionID()).thenReturn(globalTransactionID); when(transaction.getServerTransactionID()).thenReturn(stxId); transactions.add(transaction); } when(context.getTransactionBatchReader()).thenReturn(batchReader); when(context.getNumTxns()).thenReturn(transactionIds.length); when(context.getTransactions()).thenReturn(transactions); when(context.getTransactionIDs()).thenReturn(Sets.newHashSet(ids)); when(context.getSourceNodeID()).thenReturn(new ClientID(clientId)); return context; }