use of org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree in project controller by opendaylight.
the class ShardTest method testDataTreeCandidateRecovery.
@Test
public void testDataTreeCandidateRecovery() throws Exception {
// Set up the InMemorySnapshotStore.
final DataTree source = setupInMemorySnapshotStore();
final DataTreeModification writeMod = source.takeSnapshot().newModification();
writeMod.write(TestModel.OUTER_LIST_PATH, ImmutableNodes.mapNodeBuilder(TestModel.OUTER_LIST_QNAME).build());
writeMod.ready();
InMemoryJournal.addEntry(shardID.toString(), 0, DUMMY_DATA);
// Set up the InMemoryJournal.
InMemoryJournal.addEntry(shardID.toString(), 1, new SimpleReplicatedLogEntry(0, 1, payloadForModification(source, writeMod, nextTransactionId())));
final int nListEntries = 16;
final Set<Integer> listEntryKeys = new HashSet<>();
// Add some ModificationPayload entries
for (int i = 1; i <= nListEntries; i++) {
listEntryKeys.add(Integer.valueOf(i));
final YangInstanceIdentifier path = YangInstanceIdentifier.builder(TestModel.OUTER_LIST_PATH).nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, i).build();
final DataTreeModification mod = source.takeSnapshot().newModification();
mod.merge(path, ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, i));
mod.ready();
InMemoryJournal.addEntry(shardID.toString(), i + 1, new SimpleReplicatedLogEntry(i, 1, payloadForModification(source, mod, nextTransactionId())));
}
InMemoryJournal.addEntry(shardID.toString(), nListEntries + 2, new ApplyJournalEntries(nListEntries));
testRecovery(listEntryKeys);
}
use of org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree in project controller by opendaylight.
the class ShardTest method testCommitPhaseFailure.
@Test
public void testCommitPhaseFailure() throws Exception {
new ShardTestKit(getSystem()) {
{
final DataTree dataTree = createDelegatingMockDataTree();
final TestActorRef<Shard> shard = actorFactory.createTestActor(newShardBuilder().dataTree(dataTree).props().withDispatcher(Dispatchers.DefaultDispatcherId()), "testCommitPhaseFailure");
waitUntilLeader(shard);
final FiniteDuration duration = duration("5 seconds");
final Timeout timeout = new Timeout(duration);
// Setup 2 simulated transactions with mock cohorts. The first
// one fails in the
// commit phase.
doThrow(new RuntimeException("mock commit failure")).when(dataTree).commit(any(DataTreeCandidate.class));
final TransactionIdentifier transactionID1 = nextTransactionId();
shard.tell(newBatchedModifications(transactionID1, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true, false, 1), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
final TransactionIdentifier transactionID2 = nextTransactionId();
shard.tell(newBatchedModifications(transactionID2, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true, false, 1), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
// Send the CanCommitTransaction message for the first Tx.
shard.tell(new CanCommitTransaction(transactionID1, CURRENT_VERSION).toSerializable(), getRef());
final CanCommitTransactionReply canCommitReply = CanCommitTransactionReply.fromSerializable(expectMsgClass(duration, CanCommitTransactionReply.class));
assertEquals("Can commit", true, canCommitReply.getCanCommit());
// Send the CanCommitTransaction message for the 2nd Tx. This
// should get queued and
// processed after the first Tx completes.
final Future<Object> canCommitFuture = Patterns.ask(shard, new CanCommitTransaction(transactionID2, CURRENT_VERSION).toSerializable(), timeout);
// Send the CommitTransaction message for the first Tx. This
// should send back an error
// and trigger the 2nd Tx to proceed.
shard.tell(new CommitTransaction(transactionID1, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, akka.actor.Status.Failure.class);
// Wait for the 2nd Tx to complete the canCommit phase.
final CountDownLatch latch = new CountDownLatch(1);
canCommitFuture.onComplete(new OnComplete<Object>() {
@Override
public void onComplete(final Throwable failure, final Object resp) {
latch.countDown();
}
}, getSystem().dispatcher());
assertEquals("2nd CanCommit complete", true, latch.await(5, TimeUnit.SECONDS));
final InOrder inOrder = inOrder(dataTree);
inOrder.verify(dataTree).validate(any(DataTreeModification.class));
inOrder.verify(dataTree).prepare(any(DataTreeModification.class));
// FIXME: this invocation is done on the result of validate(). To test it, we need to make sure mock
// validate performs wrapping and we capture that mock
// inOrder.verify(dataTree).validate(any(DataTreeModification.class));
inOrder.verify(dataTree).commit(any(DataTreeCandidate.class));
}
};
}
use of org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree in project controller by opendaylight.
the class ShardTest method testImmediateCommitWithCanCommitPhaseFailure.
private void testImmediateCommitWithCanCommitPhaseFailure(final boolean readWrite) throws Exception {
new ShardTestKit(getSystem()) {
{
final DataTree dataTree = createDelegatingMockDataTree();
final TestActorRef<Shard> shard = actorFactory.createTestActor(newShardBuilder().dataTree(dataTree).props().withDispatcher(Dispatchers.DefaultDispatcherId()), "testImmediateCommitWithCanCommitPhaseFailure-" + readWrite);
waitUntilLeader(shard);
doThrow(new DataValidationFailedException(YangInstanceIdentifier.EMPTY, "mock canCommit failure")).doNothing().when(dataTree).validate(any(DataTreeModification.class));
final FiniteDuration duration = duration("5 seconds");
final TransactionIdentifier transactionID1 = nextTransactionId();
if (readWrite) {
shard.tell(prepareForwardedReadyTransaction(shard, transactionID1, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true), getRef());
} else {
shard.tell(prepareBatchedModifications(transactionID1, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true), getRef());
}
expectMsgClass(duration, akka.actor.Status.Failure.class);
// Send another can commit to ensure the failed one got cleaned
// up.
final TransactionIdentifier transactionID2 = nextTransactionId();
if (readWrite) {
shard.tell(prepareForwardedReadyTransaction(shard, transactionID2, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true), getRef());
} else {
shard.tell(prepareBatchedModifications(transactionID2, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true), getRef());
}
expectMsgClass(duration, CommitTransactionReply.class);
}
};
}
use of org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree in project controller by opendaylight.
the class ShardTest method testPreCommitPhaseFailure.
@Test
public void testPreCommitPhaseFailure() throws Exception {
new ShardTestKit(getSystem()) {
{
final DataTree dataTree = createDelegatingMockDataTree();
final TestActorRef<Shard> shard = actorFactory.createTestActor(newShardBuilder().dataTree(dataTree).props().withDispatcher(Dispatchers.DefaultDispatcherId()), "testPreCommitPhaseFailure");
waitUntilLeader(shard);
final FiniteDuration duration = duration("5 seconds");
final Timeout timeout = new Timeout(duration);
doThrow(new RuntimeException("mock preCommit failure")).when(dataTree).prepare(any(DataTreeModification.class));
final TransactionIdentifier transactionID1 = nextTransactionId();
shard.tell(newBatchedModifications(transactionID1, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true, false, 1), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
final TransactionIdentifier transactionID2 = nextTransactionId();
shard.tell(newBatchedModifications(transactionID2, TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME), true, false, 1), getRef());
expectMsgClass(duration, ReadyTransactionReply.class);
// Send the CanCommitTransaction message for the first Tx.
shard.tell(new CanCommitTransaction(transactionID1, CURRENT_VERSION).toSerializable(), getRef());
final CanCommitTransactionReply canCommitReply = CanCommitTransactionReply.fromSerializable(expectMsgClass(duration, CanCommitTransactionReply.class));
assertEquals("Can commit", true, canCommitReply.getCanCommit());
// Send the CanCommitTransaction message for the 2nd Tx. This
// should get queued and
// processed after the first Tx completes.
final Future<Object> canCommitFuture = Patterns.ask(shard, new CanCommitTransaction(transactionID2, CURRENT_VERSION).toSerializable(), timeout);
// Send the CommitTransaction message for the first Tx. This
// should send back an error
// and trigger the 2nd Tx to proceed.
shard.tell(new CommitTransaction(transactionID1, CURRENT_VERSION).toSerializable(), getRef());
expectMsgClass(duration, akka.actor.Status.Failure.class);
// Wait for the 2nd Tx to complete the canCommit phase.
final CountDownLatch latch = new CountDownLatch(1);
canCommitFuture.onComplete(new OnComplete<Object>() {
@Override
public void onComplete(final Throwable failure, final Object resp) {
latch.countDown();
}
}, getSystem().dispatcher());
assertEquals("2nd CanCommit complete", true, latch.await(5, TimeUnit.SECONDS));
final InOrder inOrder = inOrder(dataTree);
inOrder.verify(dataTree).validate(any(DataTreeModification.class));
inOrder.verify(dataTree).prepare(any(DataTreeModification.class));
inOrder.verify(dataTree).validate(any(DataTreeModification.class));
}
};
}
use of org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree in project controller by opendaylight.
the class DistributedDataStoreRemotingIntegrationTest method testForwardedReadyTransactionForwardedToLeader.
@SuppressWarnings("unchecked")
@Test
public void testForwardedReadyTransactionForwardedToLeader() throws Exception {
initDatastoresWithCars("testForwardedReadyTransactionForwardedToLeader");
followerTestKit.waitUntilLeader(followerDistributedDataStore.getActorContext(), "cars");
final Optional<ActorRef> carsFollowerShard = followerDistributedDataStore.getActorContext().findLocalShard("cars");
assertEquals("Cars follower shard found", true, carsFollowerShard.isPresent());
carsFollowerShard.get().tell(GetShardDataTree.INSTANCE, followerTestKit.getRef());
final DataTree dataTree = followerTestKit.expectMsgClass(DataTree.class);
// Send a tx with immediate commit.
DataTreeModification modification = dataTree.takeSnapshot().newModification();
new WriteModification(CarsModel.BASE_PATH, CarsModel.emptyContainer()).apply(modification);
new MergeModification(CarsModel.CAR_LIST_PATH, CarsModel.newCarMapNode()).apply(modification);
final MapEntryNode car1 = CarsModel.newCarEntry("optima", BigInteger.valueOf(20000));
new WriteModification(CarsModel.newCarPath("optima"), car1).apply(modification);
ForwardedReadyTransaction forwardedReady = new ForwardedReadyTransaction(tx1, DataStoreVersions.CURRENT_VERSION, new ReadWriteShardDataTreeTransaction(Mockito.mock(ShardDataTreeTransactionParent.class), tx1, modification), true);
carsFollowerShard.get().tell(forwardedReady, followerTestKit.getRef());
Object resp = followerTestKit.expectMsgClass(Object.class);
if (resp instanceof akka.actor.Status.Failure) {
throw new AssertionError("Unexpected failure response", ((akka.actor.Status.Failure) resp).cause());
}
assertEquals("Response type", CommitTransactionReply.class, resp.getClass());
verifyCars(leaderDistributedDataStore.newReadOnlyTransaction(), car1);
// Send another tx without immediate commit.
modification = dataTree.takeSnapshot().newModification();
MapEntryNode car2 = CarsModel.newCarEntry("sportage", BigInteger.valueOf(30000));
new WriteModification(CarsModel.newCarPath("sportage"), car2).apply(modification);
forwardedReady = new ForwardedReadyTransaction(tx2, DataStoreVersions.CURRENT_VERSION, new ReadWriteShardDataTreeTransaction(Mockito.mock(ShardDataTreeTransactionParent.class), tx2, modification), false);
carsFollowerShard.get().tell(forwardedReady, followerTestKit.getRef());
resp = followerTestKit.expectMsgClass(Object.class);
if (resp instanceof akka.actor.Status.Failure) {
throw new AssertionError("Unexpected failure response", ((akka.actor.Status.Failure) resp).cause());
}
assertEquals("Response type", ReadyTransactionReply.class, resp.getClass());
ActorSelection txActor = leaderDistributedDataStore.getActorContext().actorSelection(((ReadyTransactionReply) resp).getCohortPath());
final Supplier<Short> versionSupplier = Mockito.mock(Supplier.class);
Mockito.doReturn(DataStoreVersions.CURRENT_VERSION).when(versionSupplier).get();
final ThreePhaseCommitCohortProxy cohort = new ThreePhaseCommitCohortProxy(leaderDistributedDataStore.getActorContext(), Arrays.asList(new ThreePhaseCommitCohortProxy.CohortInfo(Futures.successful(txActor), versionSupplier)), tx2);
cohort.canCommit().get(5, TimeUnit.SECONDS);
cohort.preCommit().get(5, TimeUnit.SECONDS);
cohort.commit().get(5, TimeUnit.SECONDS);
verifyCars(leaderDistributedDataStore.newReadOnlyTransaction(), car1, car2);
}
Aggregations