+ DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+ assertNotNull(writeTx);
+
+ ContainerNode containerNode = ImmutableContainerNodeBuilder.create()
+ .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
+ .addChild(ImmutableNodes.mapNodeBuilder(TestModel.OUTER_LIST_QNAME)
+ .addChild(ImmutableNodes.mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)).build())
+ .build();
+
+ writeTx.merge(TestModel.TEST_PATH, containerNode);
+
+ CheckedFuture<Boolean, ReadFailedException> exists =
+ writeTx.exists(TestModel.TEST_PATH);
+
+ assertEquals(true, exists.checkedGet());
+
+ DOMStoreThreePhaseCommitCohort ready = writeTx.ready();
+
+ ready.preCommit().get();
+
+ ready.commit().get();
+
+ DOMStoreReadTransaction readTx = domStore.newReadOnlyTransaction();
+ assertNotNull(readTx);
+
+ exists =
+ readTx.exists(TestModel.TEST_PATH);
+
+ assertEquals(true, exists.checkedGet());
+ }
+
+ @Test
+ public void testExistsForNonExistingData() throws Exception {
+
+ DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+ assertNotNull(writeTx);
+
+ CheckedFuture<Boolean, ReadFailedException> exists =
+ writeTx.exists(TestModel.TEST_PATH);
+
+ assertEquals(false, exists.checkedGet());
+
+ DOMStoreReadTransaction readTx = domStore.newReadOnlyTransaction();
+ assertNotNull(readTx);
+
+ exists =
+ readTx.exists(TestModel.TEST_PATH);
+
+ assertEquals(false, exists.checkedGet());
+ }
+
+ @Test(expected = ReadFailedException.class)
+ public void testExistsThrowsReadFailedException() throws Exception {
+
+ DOMStoreReadTransaction readTx = domStore.newReadOnlyTransaction();
+ assertNotNull(readTx);
+
+ readTx.close();
+
+ readTx.exists(TestModel.TEST_PATH).checkedGet();
+ }
+
+ @Test(expected = ReadFailedException.class)
+ public void testReadWithReadOnlyTransactionClosed() throws Exception {
+
+ DOMStoreReadTransaction readTx = domStore.newReadOnlyTransaction();
+ assertNotNull(readTx);
+
+ readTx.close();
+
+ doReadAndThrowEx(readTx);
+ }
+
+ @Test(expected = ReadFailedException.class)
+ public void testReadWithReadOnlyTransactionFailure() throws Exception {
+
+ DataTreeSnapshot mockSnapshot = Mockito.mock(DataTreeSnapshot.class);
+ Mockito.doThrow(new RuntimeException("mock ex")).when(mockSnapshot)
+ .readNode(Mockito.any(YangInstanceIdentifier.class));
+
+ DOMStoreReadTransaction readTx = SnapshotBackedTransactions.newReadTransaction("1", true, mockSnapshot);
+
+ doReadAndThrowEx(readTx);
+ }
+
+ @Test(expected = ReadFailedException.class)
+ public void testReadWithReadWriteTransactionClosed() throws Exception {
+
+ DOMStoreReadTransaction readTx = domStore.newReadWriteTransaction();
+ assertNotNull(readTx);
+
+ readTx.close();
+
+ doReadAndThrowEx(readTx);
+ }
+
+ @Test(expected = ReadFailedException.class)
+ public void testReadWithReadWriteTransactionFailure() throws Exception {
+
+ DataTreeSnapshot mockSnapshot = Mockito.mock(DataTreeSnapshot.class);
+ DataTreeModification mockModification = Mockito.mock(DataTreeModification.class);
+ Mockito.doThrow(new RuntimeException("mock ex")).when(mockModification)
+ .readNode(Mockito.any(YangInstanceIdentifier.class));
+ Mockito.doReturn(mockModification).when(mockSnapshot).newModification();
+ @SuppressWarnings("unchecked")
+ TransactionReadyPrototype<String> mockReady = Mockito.mock(TransactionReadyPrototype.class);
+ DOMStoreReadTransaction readTx = SnapshotBackedTransactions.newReadWriteTransaction("1", false, mockSnapshot,
+ mockReady);
+
+ doReadAndThrowEx(readTx);
+ }
+
+ private static void doReadAndThrowEx(final DOMStoreReadTransaction readTx) throws ReadFailedException {
+ readTx.read(TestModel.TEST_PATH).checkedGet();
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testWriteWithTransactionReady() throws Exception {
+
+ DOMStoreWriteTransaction writeTx = domStore.newWriteOnlyTransaction();
+
+ writeTx.ready();
+
+ // Should throw ex
+ writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testReadyWithTransactionAlreadyReady() throws Exception {
+
+ DOMStoreWriteTransaction writeTx = domStore.newWriteOnlyTransaction();
+
+ writeTx.ready();
+
+ // Should throw ex
+ writeTx.ready();
+ }
+
+ @Test
+ public void testReadyWithMissingMandatoryData() throws InterruptedException {
+ DOMStoreWriteTransaction writeTx = domStore.newWriteOnlyTransaction();
+ NormalizedNode<?, ?> testNode = ImmutableContainerNodeBuilder.create()
+ .withNodeIdentifier(new NodeIdentifier(TestModel.MANDATORY_DATA_TEST_QNAME))
+ .addChild(ImmutableNodes.leafNode(TestModel.OPTIONAL_QNAME, "data"))
+ .build();
+ writeTx.write(TestModel.MANDATORY_DATA_TEST_PATH, testNode);
+ DOMStoreThreePhaseCommitCohort ready = writeTx.ready();
+ try {
+ ready.canCommit().get();
+ Assert.fail("Expected exception on canCommit");
+ } catch (ExecutionException e) {
+ // nop
+ }
+ }
+
+ @Test
+ public void testTransactionAbort() throws InterruptedException, ExecutionException {
+
+ DOMStoreReadWriteTransaction writeTx = domStore.newReadWriteTransaction();
+ assertNotNull(writeTx);
+
+ assertTestContainerWrite(writeTx);
+
+ DOMStoreThreePhaseCommitCohort cohort = writeTx.ready();
+
+ assertTrue(cohort.canCommit().get().booleanValue());
+ cohort.preCommit().get();
+ cohort.abort().get();
+
+ Optional<NormalizedNode<?, ?>> afterCommitRead = domStore.newReadOnlyTransaction().read(TestModel.TEST_PATH)
+ .get();
+ assertFalse(afterCommitRead.isPresent());
+ }
+
+ @Test
+ public void testTransactionChain() throws InterruptedException, ExecutionException {
+ DOMStoreTransactionChain txChain = domStore.createTransactionChain();
+ assertNotNull(txChain);
+
+ /*
+ * We alocate new read-write transaction and write /test
+ */
+ DOMStoreReadWriteTransaction firstTx = txChain.newReadWriteTransaction();
+ assertTestContainerWrite(firstTx);
+
+ /*
+ * First transaction is marked as ready, we are able to allocate chained
+ * transactions
+ */
+ final DOMStoreThreePhaseCommitCohort firstWriteTxCohort = firstTx.ready();
+
+ /*
+ * We alocate chained transaction - read transaction, note first one is
+ * still not commited to datastore.
+ */
+ DOMStoreReadTransaction secondReadTx = txChain.newReadOnlyTransaction();
+
+ /*
+ * We test if we are able to read data from tx, read should not fail
+ * since we are using chained transaction.
+ */
+ assertTestContainerExists(secondReadTx);
+
+ /*
+ * We alocate next transaction, which is still based on first one, but
+ * is read-write.
+ */
+ DOMStoreReadWriteTransaction thirdDeleteTx = txChain.newReadWriteTransaction();
+
+ /*
+ * We test existence of /test in third transaction container should
+ * still be visible from first one (which is still uncommmited).
+ */
+ assertTestContainerExists(thirdDeleteTx);
+
+ /*
+ * We delete node in third transaction
+ */
+ thirdDeleteTx.delete(TestModel.TEST_PATH);
+
+ /*
+ * third transaction is sealed.
+ */
+ DOMStoreThreePhaseCommitCohort thirdDeleteTxCohort = thirdDeleteTx.ready();
+
+ /*
+ * We commit first transaction
+ */
+ assertThreePhaseCommit(firstWriteTxCohort);
+
+ // Alocates store transacion
+ DOMStoreReadTransaction storeReadTx = domStore.newReadOnlyTransaction();
+
+ /*
+ * We verify transaction is commited to store, container should exists
+ * in datastore.
+ */
+ assertTestContainerExists(storeReadTx);
+
+ /*
+ * We commit third transaction
+ */
+ assertThreePhaseCommit(thirdDeleteTxCohort);
+ }
+
+ @Test
+ @Ignore
+ public void testTransactionConflict() throws InterruptedException, ExecutionException {
+ DOMStoreReadWriteTransaction txOne = domStore.newReadWriteTransaction();
+ DOMStoreReadWriteTransaction txTwo = domStore.newReadWriteTransaction();
+ assertTestContainerWrite(txOne);
+ assertTestContainerWrite(txTwo);
+
+ /*
+ * Commits transaction
+ */
+ assertThreePhaseCommit(txOne.ready());
+
+ /*
+ * Asserts that txTwo could not be commited
+ */
+ assertFalse(txTwo.ready().canCommit().get());
+ }
+
+ private static void assertThreePhaseCommit(final DOMStoreThreePhaseCommitCohort cohort)
+ throws InterruptedException, ExecutionException {
+ assertTrue(cohort.canCommit().get().booleanValue());
+ cohort.preCommit().get();
+ cohort.commit().get();
+ }
+
+ private static Optional<NormalizedNode<?, ?>> assertTestContainerWrite(final DOMStoreReadWriteTransaction writeTx)
+ throws InterruptedException, ExecutionException {
+ /*
+ * Writes /test in writeTx
+ */
+ writeTx.write(TestModel.TEST_PATH, ImmutableNodes.containerNode(TestModel.TEST_QNAME));
+
+ return assertTestContainerExists(writeTx);
+ }
+
+ /**
+ * Reads /test from readTx Read should return container.
+ */
+ private static Optional<NormalizedNode<?, ?>> assertTestContainerExists(final DOMStoreReadTransaction readTx)
+ throws InterruptedException, ExecutionException {