Bug 5947: Increasing code coverage - mdsal-dom-spi 38/40838/4
authorPeter Nosal <peter.nosal@pantheon.tech>
Sat, 25 Jun 2016 16:45:54 +0000 (18:45 +0200)
committerRobert Varga <nite@hq.sk>
Wed, 29 Jun 2016 11:14:20 +0000 (11:14 +0000)
Change-Id: Idcc5ba3ea102576d593a824fffbb32567177fdba
Signed-off-by: Peter Nosal <peter.nosal@pantheon.tech>
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/AbstractDOMStoreTransactionTest.java [new file with mode: 0644]
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/AbstractDOMStoreTreeChangePublisherTest.java [new file with mode: 0644]
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/AbstractSnapshotBackedTransactionChainTest.java [new file with mode: 0644]
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/ForwardingDOMStoreThreePhaseCommitCohortTest.java [new file with mode: 0644]
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedReadTransactionTest.java [new file with mode: 0644]
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedReadWriteTransactionTest.java [new file with mode: 0644]
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedTransactionsTest.java [new file with mode: 0644]
dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedWriteTransactionTest.java [new file with mode: 0644]

diff --git a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/AbstractDOMStoreTransactionTest.java b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/AbstractDOMStoreTransactionTest.java
new file mode 100644 (file)
index 0000000..143b4ff
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.spi.store;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+public class AbstractDOMStoreTransactionTest extends AbstractDOMStoreTransaction {
+
+    private static final String IDENTIFIER = "testIdentifier";
+
+    @Test
+    public void basicTest() throws Exception {
+        assertEquals(IDENTIFIER, this.getIdentifier());
+        assertTrue(this.toString().contains(IDENTIFIER));
+        assertNull(this.getDebugContext());
+    }
+
+    public AbstractDOMStoreTransactionTest() {
+        super(IDENTIFIER);
+    }
+
+    @Override
+    public void close() {
+        // NOOP
+    }
+}
\ No newline at end of file
diff --git a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/AbstractDOMStoreTreeChangePublisherTest.java b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/AbstractDOMStoreTreeChangePublisherTest.java
new file mode 100644 (file)
index 0000000..40c9b37
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.spi.store;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.collect.ImmutableList;
+import java.lang.reflect.Field;
+import java.util.Collection;
+import javax.annotation.Nonnull;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeListener;
+import org.opendaylight.mdsal.dom.spi.AbstractDOMDataTreeChangeListenerRegistration;
+import org.opendaylight.yangtools.concepts.AbstractRegistration;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.ModificationType;
+
+public class AbstractDOMStoreTreeChangePublisherTest extends AbstractDOMStoreTreeChangePublisher {
+
+    private static boolean removeInvoked = false;
+    private static boolean notifyInvoked = false;
+
+    @Test
+    public void basicTest() throws Exception {
+        final DataTreeCandidate dataTreeCandidate = mock(DataTreeCandidate.class);
+        final DataTreeCandidateNode dataTreeCandidateNode = mock(DataTreeCandidateNode.class, "dataTreeCandidateNode");
+        final YangInstanceIdentifier yangInstanceIdentifier = YangInstanceIdentifier.builder()
+                .node(QName.create("node1")).node(QName.create("node2")).build();
+
+        doReturn(dataTreeCandidateNode).when(dataTreeCandidate).getRootNode();
+        doReturn(ModificationType.WRITE).when(dataTreeCandidateNode).getModificationType();
+        doReturn(yangInstanceIdentifier).when(dataTreeCandidate).getRootPath();
+        doReturn(ImmutableList.of(dataTreeCandidateNode)).when(dataTreeCandidateNode).getChildNodes();
+        doReturn(yangInstanceIdentifier.getLastPathArgument()).when(dataTreeCandidateNode).getIdentifier();
+
+        final DOMDataTreeChangeListener domDataTreeChangeListener = mock(DOMDataTreeChangeListener.class);
+
+        final AbstractDOMDataTreeChangeListenerRegistration abstractDOMDataTreeChangeListenerRegistration =
+                this.registerTreeChangeListener(yangInstanceIdentifier, domDataTreeChangeListener);
+
+        assertFalse(removeInvoked);
+        assertFalse(notifyInvoked);
+
+        this.processCandidateTree(dataTreeCandidate);
+        doReturn(ModificationType.UNMODIFIED).when(dataTreeCandidateNode).getModificationType();
+        this.processCandidateTree(dataTreeCandidate);
+
+        abstractDOMDataTreeChangeListenerRegistration.close();
+
+        assertTrue(removeInvoked);
+        assertTrue(notifyInvoked);
+
+        final Field closedField = AbstractRegistration.class.getDeclaredField("closed");
+        closedField.setAccessible(true);
+
+        final int closed = (int) closedField.get(abstractDOMDataTreeChangeListenerRegistration);
+        Assert.assertEquals(1, closed);
+    }
+
+    @Override
+    protected void notifyListeners(@Nonnull Collection<AbstractDOMDataTreeChangeListenerRegistration<?>> registrations,
+                                   @Nonnull YangInstanceIdentifier path, @Nonnull DataTreeCandidateNode node) {
+        notifyInvoked = true;
+    }
+
+    @Override
+    protected void registrationRemoved(@Nonnull AbstractDOMDataTreeChangeListenerRegistration<?> registration) {
+        removeInvoked = true;
+    }
+}
\ No newline at end of file
diff --git a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/AbstractSnapshotBackedTransactionChainTest.java b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/AbstractSnapshotBackedTransactionChainTest.java
new file mode 100644 (file)
index 0000000..2168352
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.spi.store;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import com.google.common.base.MoreObjects;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
+
+public class AbstractSnapshotBackedTransactionChainTest extends AbstractSnapshotBackedTransactionChain {
+
+    @Mock
+    private static DataTreeSnapshot dataTreeSnapshot;
+
+    @Mock
+    private static DOMStoreThreePhaseCommitCohort domStoreThreePhaseCommitCohort;
+
+    @Test
+    public void basicTest() throws Exception {
+        initMocks(this);
+        SnapshotBackedWriteTransaction snapshotBackedWriteTransaction = mock(SnapshotBackedWriteTransaction.class);
+        DataTreeModification dataTreeModification = mock(DataTreeModification.class);
+        doReturn(dataTreeModification).when(dataTreeSnapshot).newModification();
+        doReturn(MoreObjects.toStringHelper(this)).when(snapshotBackedWriteTransaction).addToStringAttributes(any());
+
+        this.newReadOnlyTransaction().close();
+        this.newWriteOnlyTransaction().close();
+        this.newReadWriteTransaction().close();
+
+        this.transactionReady(snapshotBackedWriteTransaction, dataTreeModification);
+
+
+        this.transactionAborted(snapshotBackedWriteTransaction);
+        this.close();
+
+        this.onTransactionCommited(snapshotBackedWriteTransaction);
+        this.onTransactionFailed(snapshotBackedWriteTransaction, null);
+
+    }
+
+    @Override
+    protected Object nextTransactionIdentifier() {
+        return new Object();
+    }
+
+    @Override
+    protected boolean getDebugTransactions() {
+        return false;
+    }
+
+    @Override
+    protected DataTreeSnapshot takeSnapshot() {
+        return dataTreeSnapshot;
+    }
+
+    @Override
+    protected DOMStoreThreePhaseCommitCohort createCohort(SnapshotBackedWriteTransaction transaction,
+                                                          DataTreeModification modification) {
+        return domStoreThreePhaseCommitCohort;
+    }
+}
\ No newline at end of file
diff --git a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/ForwardingDOMStoreThreePhaseCommitCohortTest.java b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/ForwardingDOMStoreThreePhaseCommitCohortTest.java
new file mode 100644 (file)
index 0000000..5edaec2
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.spi.store;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.MockitoAnnotations.initMocks;
+
+import org.junit.Test;
+import org.mockito.Mock;
+
+public class ForwardingDOMStoreThreePhaseCommitCohortTest extends ForwardingDOMStoreThreePhaseCommitCohort {
+
+    @Mock(name = "domStoreThreePhaseCommitCohort")
+    private DOMStoreThreePhaseCommitCohort domStoreThreePhaseCommitCohort;
+
+    @Test
+    public void basicTest() throws Exception {
+        initMocks(this);
+
+        doReturn(null).when(domStoreThreePhaseCommitCohort).canCommit();
+        this.canCommit();
+        verify(domStoreThreePhaseCommitCohort).canCommit();
+
+        doReturn(null).when(domStoreThreePhaseCommitCohort).preCommit();
+        this.preCommit();
+        verify(domStoreThreePhaseCommitCohort).preCommit();
+
+        doReturn(null).when(domStoreThreePhaseCommitCohort).commit();
+        this.commit();
+        verify(domStoreThreePhaseCommitCohort).commit();
+
+        doReturn(null).when(domStoreThreePhaseCommitCohort).abort();
+        this.abort();
+        verify(domStoreThreePhaseCommitCohort).abort();
+    }
+
+    @Override
+    protected DOMStoreThreePhaseCommitCohort delegate() {
+        return domStoreThreePhaseCommitCohort;
+    }
+}
\ No newline at end of file
diff --git a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedReadTransactionTest.java b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedReadTransactionTest.java
new file mode 100644 (file)
index 0000000..e70dfcc
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.spi.store;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.base.Optional;
+import java.lang.reflect.Field;
+import org.junit.Test;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
+
+public class SnapshotBackedReadTransactionTest {
+
+    private static final DataTreeSnapshot DATA_TREE_SNAPSHOT = mock(DataTreeSnapshot.class);
+    private static SnapshotBackedReadTransaction snapshotBackedReadTransaction =
+            new SnapshotBackedReadTransaction<>(new Object(), false, DATA_TREE_SNAPSHOT);
+
+    @Test
+    public void basicTest() throws Exception {
+        final NormalizedNode<?, ?> testNode = mock(NormalizedNode.class);
+        final Optional<NormalizedNode> optional = Optional.of(testNode);
+        doReturn("testNode").when(testNode).toString();
+        doReturn(optional).when(DATA_TREE_SNAPSHOT).readNode(YangInstanceIdentifier.EMPTY);
+        assertTrue((Boolean) snapshotBackedReadTransaction.exists(YangInstanceIdentifier.EMPTY).get());
+
+        assertEquals(optional, snapshotBackedReadTransaction.read(YangInstanceIdentifier.EMPTY).get());
+
+        final Field stableSnapshotField = SnapshotBackedReadTransaction.class.getDeclaredField("stableSnapshot");
+        stableSnapshotField.setAccessible(true);
+
+        DataTreeSnapshot stableSnapshot = (DataTreeSnapshot) stableSnapshotField.get(snapshotBackedReadTransaction);
+        assertNotNull(stableSnapshot);
+        snapshotBackedReadTransaction.close();
+        stableSnapshot = (DataTreeSnapshot) stableSnapshotField.get(snapshotBackedReadTransaction);
+        assertNull(stableSnapshot);
+    }
+
+    @Test(expected = ReadFailedException.class)
+    public void readTestWithException() throws Throwable {
+        snapshotBackedReadTransaction.close();
+        try {
+            snapshotBackedReadTransaction.read(YangInstanceIdentifier.EMPTY).get();
+            fail("Expected ReadFailedException");
+        } catch (Exception e) {
+            throw e.getCause();
+        }
+    }
+
+    @Test(expected = ReadFailedException.class)
+    public void readNodeTestWithException() throws Throwable {
+        doThrow(new NullPointerException("no Node")).when(DATA_TREE_SNAPSHOT).readNode(any());
+        snapshotBackedReadTransaction = new SnapshotBackedReadTransaction<>(new Object(), false, DATA_TREE_SNAPSHOT);
+        try {
+            snapshotBackedReadTransaction.read(YangInstanceIdentifier.EMPTY).get();
+            fail("Expected ReadFailedException");
+        } catch (Exception e) {
+            throw e.getCause();
+        }
+    }
+
+    @Test(expected = ReadFailedException.class)
+    public void existsTestWithException() throws Throwable {
+        doThrow(new NullPointerException("no Node")).when(DATA_TREE_SNAPSHOT).readNode(any());
+
+        try {
+            snapshotBackedReadTransaction.exists(YangInstanceIdentifier.EMPTY).get();
+            fail("Expected ReadFailedException");
+        } catch (Exception e) {
+            throw e.getCause();
+        }
+    }
+}
\ No newline at end of file
diff --git a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedReadWriteTransactionTest.java b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedReadWriteTransactionTest.java
new file mode 100644 (file)
index 0000000..7b361a9
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.spi.store;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+
+import com.google.common.base.Optional;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.mdsal.common.api.ReadFailedException;
+import org.opendaylight.mdsal.dom.spi.store.SnapshotBackedWriteTransaction.TransactionReadyPrototype;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
+
+public class SnapshotBackedReadWriteTransactionTest {
+
+    private static final DataTreeSnapshot DATA_TREE_SNAPSHOT = mock(DataTreeSnapshot.class);
+    private static final DataTreeModification DATA_TREE_MODIFICATION = mock(DataTreeModification.class);
+    private static final TransactionReadyPrototype TRANSACTION_READY_PROTOTYPE =  mock(TransactionReadyPrototype.class);
+    private SnapshotBackedReadWriteTransaction snapshotBackedReadWriteTransaction;
+
+    @Before
+    public void setUp() throws Exception {
+        doReturn(DATA_TREE_MODIFICATION).when(DATA_TREE_SNAPSHOT).newModification();
+        snapshotBackedReadWriteTransaction = new SnapshotBackedReadWriteTransaction(new Object(), false,
+                DATA_TREE_SNAPSHOT, TRANSACTION_READY_PROTOTYPE);
+    }
+
+    @Test
+    public void basicTest() throws Exception {
+        final NormalizedNode<?, ?> testNode = mock(NormalizedNode.class);
+        final Optional<NormalizedNode> optional = Optional.of(testNode);
+        doReturn("testNode").when(testNode).toString();
+        doReturn(optional).when(DATA_TREE_MODIFICATION).readNode(YangInstanceIdentifier.EMPTY);
+        assertTrue((Boolean) snapshotBackedReadWriteTransaction.exists(YangInstanceIdentifier.EMPTY).get());
+        assertEquals(optional, snapshotBackedReadWriteTransaction.read(YangInstanceIdentifier.EMPTY).get());
+    }
+
+    @Test(expected = ReadFailedException.class)
+    public void readTestWithNullException() throws Throwable {
+        doReturn(null).when(DATA_TREE_MODIFICATION).readNode(YangInstanceIdentifier.EMPTY);
+        try {
+            snapshotBackedReadWriteTransaction.read(YangInstanceIdentifier.EMPTY).get();
+            fail("Expected ReadFailedException");
+        } catch (Exception e) {
+            throw e.getCause();
+        }
+    }
+
+    @Test(expected = ReadFailedException.class)
+    public void readNodeTestWithException() throws Throwable {
+        doThrow(new NullPointerException("no Node")).when(DATA_TREE_MODIFICATION).readNode(any());
+        try {
+            snapshotBackedReadWriteTransaction.read(YangInstanceIdentifier.EMPTY).get();
+            fail("Expected ReadFailedException");
+        } catch (Exception e) {
+            throw e.getCause();
+        }
+    }
+
+    @Test(expected = ReadFailedException.class)
+    public void existsTestWithException() throws Throwable {
+        doThrow(new NullPointerException("no Node")).when(DATA_TREE_MODIFICATION).readNode(any());
+        try {
+            snapshotBackedReadWriteTransaction.exists(YangInstanceIdentifier.EMPTY).get();
+            fail("Expected ReadFailedException");
+        } catch (Exception e) {
+            throw e.getCause();
+        }
+    }
+}
\ No newline at end of file
diff --git a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedTransactionsTest.java b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedTransactionsTest.java
new file mode 100644 (file)
index 0000000..8e94bf2
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.spi.store;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+
+import java.lang.reflect.Constructor;
+import org.junit.Test;
+import org.opendaylight.mdsal.dom.spi.store.SnapshotBackedWriteTransaction.TransactionReadyPrototype;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
+
+public class SnapshotBackedTransactionsTest {
+
+    @Test
+    public void basicTest() throws Exception {
+        final DataTreeSnapshot dataTreeSnapshot = mock(DataTreeSnapshot.class);
+        final DataTreeModification dataTreeModification = mock(DataTreeModification.class);
+        final TransactionReadyPrototype transactionReadyPrototype =  mock(TransactionReadyPrototype.class);
+        doReturn(dataTreeModification).when(dataTreeSnapshot).newModification();
+
+        assertNotNull(SnapshotBackedTransactions.newReadTransaction(new Object(), false, dataTreeSnapshot));
+        assertNotNull(SnapshotBackedTransactions.newWriteTransaction(
+                new Object(), false, dataTreeSnapshot, transactionReadyPrototype));
+        assertNotNull(SnapshotBackedTransactions.newReadWriteTransaction(
+                new Object(), false, dataTreeSnapshot, transactionReadyPrototype));
+    }
+
+    @Test(expected = UnsupportedOperationException.class)
+    public void constructorTest() throws Throwable {
+        Constructor<SnapshotBackedTransactions> constructor = SnapshotBackedTransactions.class.getDeclaredConstructor();
+        constructor.setAccessible(true);
+        try {
+            constructor.newInstance();
+            fail("Expected UnsupportedOperationException");
+        } catch (Exception e) {
+            throw e.getCause();
+        }
+    }
+}
\ No newline at end of file
diff --git a/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedWriteTransactionTest.java b/dom/mdsal-dom-spi/src/test/java/org/opendaylight/mdsal/dom/spi/store/SnapshotBackedWriteTransactionTest.java
new file mode 100644 (file)
index 0000000..6fb924c
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.mdsal.dom.spi.store;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Optional;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.mdsal.dom.spi.store.SnapshotBackedWriteTransaction.TransactionReadyPrototype;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot;
+
+public class SnapshotBackedWriteTransactionTest {
+
+    private static final DataTreeSnapshot DATA_TREE_SNAPSHOT = mock(DataTreeSnapshot.class);
+    private static final DataTreeModification DATA_TREE_MODIFICATION = mock(DataTreeModification.class);
+    private static final TransactionReadyPrototype<Object> TRANSACTION_READY_PROTOTYPE =
+            mock(TransactionReadyPrototype.class);
+    private static final DOMStoreThreePhaseCommitCohort DOM_STORE_THREE_PHASE_COMMIT_COHORT =
+            mock(DOMStoreThreePhaseCommitCohort.class);
+    private static final NormalizedNode NORMALIZED_NODE = mock(NormalizedNode.class);
+    private static final Optional NORMALIZED_NODE_OPTIONAL = Optional.of(NORMALIZED_NODE);
+    private static SnapshotBackedWriteTransaction snapshotBackedWriteTransaction;
+
+    @Before
+    public void setUp() throws Exception {
+        doReturn(DATA_TREE_MODIFICATION).when(DATA_TREE_SNAPSHOT).newModification();
+        doNothing().when(DATA_TREE_MODIFICATION).ready();
+        doNothing().when(DATA_TREE_MODIFICATION).write(any(), any());
+        doNothing().when(DATA_TREE_MODIFICATION).merge(any(), any());
+        doNothing().when(DATA_TREE_MODIFICATION).delete(any());
+        doNothing().when(TRANSACTION_READY_PROTOTYPE).transactionAborted(any());
+        doReturn("testDataTreeModification").when(DATA_TREE_MODIFICATION).toString();
+        doReturn("testNormalizedNode").when(NORMALIZED_NODE).toString();
+        doReturn(DOM_STORE_THREE_PHASE_COMMIT_COHORT).when(TRANSACTION_READY_PROTOTYPE).transactionReady(any(),any());
+        doReturn(NORMALIZED_NODE_OPTIONAL).when(DATA_TREE_MODIFICATION).readNode(YangInstanceIdentifier.EMPTY);
+        snapshotBackedWriteTransaction = new SnapshotBackedWriteTransaction<>(new Object(), false, DATA_TREE_SNAPSHOT,
+                TRANSACTION_READY_PROTOTYPE);
+    }
+
+    @Test
+    public void basicTest() throws Exception {
+        snapshotBackedWriteTransaction.write(YangInstanceIdentifier.EMPTY, NORMALIZED_NODE);
+        verify(DATA_TREE_MODIFICATION).write(any(), any());
+
+        snapshotBackedWriteTransaction.merge(YangInstanceIdentifier.EMPTY, NORMALIZED_NODE);
+        verify(DATA_TREE_MODIFICATION).merge(any(), any());
+
+        snapshotBackedWriteTransaction.delete(YangInstanceIdentifier.EMPTY);
+        verify(DATA_TREE_MODIFICATION).delete(any());
+
+        assertEquals(NORMALIZED_NODE_OPTIONAL,
+                snapshotBackedWriteTransaction.readSnapshotNode(YangInstanceIdentifier.EMPTY));
+        verify(DATA_TREE_MODIFICATION).readNode(any());
+
+        assertTrue(snapshotBackedWriteTransaction.addToStringAttributes(
+                MoreObjects.toStringHelper(this).omitNullValues()).toString().contains("ready"));
+        snapshotBackedWriteTransaction.close();
+    }
+
+    @Test
+    public void readyTest() throws Exception {
+        SnapshotBackedWriteTransaction snapshotBackedWriteTransaction =
+                new SnapshotBackedWriteTransaction<>(
+                        new Object(), false, DATA_TREE_SNAPSHOT, TRANSACTION_READY_PROTOTYPE);
+        Assert.assertNotNull(snapshotBackedWriteTransaction.ready());
+        verify(TRANSACTION_READY_PROTOTYPE).transactionReady(any(), any());
+        snapshotBackedWriteTransaction.close();
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void writeWithException() throws Exception {
+        doThrow(TestException.class).when(DATA_TREE_MODIFICATION).write(any(), any());
+        snapshotBackedWriteTransaction.write(YangInstanceIdentifier.EMPTY, NORMALIZED_NODE);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void mergeWithException() throws Exception {
+        doThrow(TestException.class).when(DATA_TREE_MODIFICATION).merge(any(), any());
+        snapshotBackedWriteTransaction.merge(YangInstanceIdentifier.EMPTY, NORMALIZED_NODE);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void deleteWithException() throws Exception {
+        doThrow(TestException.class).when(DATA_TREE_MODIFICATION).delete(any());
+        snapshotBackedWriteTransaction.delete(YangInstanceIdentifier.EMPTY);
+    }
+
+    private static final class TestException extends Exception {}
+}
\ No newline at end of file