From d54ea758da8dcf71d52727c4f01f87090c50bf2e Mon Sep 17 00:00:00 2001 From: Maros Marsalek Date: Tue, 17 May 2016 09:10:39 +0200 Subject: HONEYCOMB-61: Add BA broker for context data tree With broker, context data can be accessed in a transactional manner, same as config data + Renamed data-api concepts to not include DataTree + Renamed context related concepts to better distinguish between them + Now passing full ReadContext to read customizers + Naming context is backed by context data broker Change-Id: I0b2876dd74a31a9ced7d9b5145672868e12f8b82 Signed-off-by: Maros Marsalek --- .../v3po/data/impl/ConfigDataTreeTest.java | 271 ------------------ .../honeycomb/v3po/data/impl/DataBrokerTest.java | 20 +- .../data/impl/ModifiableDataTreeDelegatorTest.java | 308 +++++++++++++++++++++ .../v3po/data/impl/OperationalDataTreeTest.java | 185 ------------- .../v3po/data/impl/ReadOnlyTransactionTest.java | 10 +- .../data/impl/ReadableDataTreeDelegatorTest.java | 193 +++++++++++++ .../v3po/data/impl/WriteTransactionTest.java | 30 +- 7 files changed, 527 insertions(+), 490 deletions(-) delete mode 100644 v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTreeTest.java create mode 100644 v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java delete mode 100644 v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTreeTest.java create mode 100644 v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java (limited to 'v3po/data-impl/src/test') diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTreeTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTreeTest.java deleted file mode 100644 index b7f8b9d2c..000000000 --- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ConfigDataTreeTest.java +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.data.impl; - -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.Matchers.anyMap; -import static org.mockito.Matchers.eq; -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 static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.common.base.Optional; -import com.google.common.util.concurrent.CheckedFuture; -import io.fd.honeycomb.v3po.data.DataTreeSnapshot; -import io.fd.honeycomb.v3po.translate.TranslationException; -import io.fd.honeycomb.v3po.translate.write.WriteContext; -import io.fd.honeycomb.v3po.translate.write.WriterRegistry; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; -import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Ethernet; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree; -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.DataTreeModification; - -public class ConfigDataTreeTest { - - @Mock - private WriterRegistry writer; - @Mock - private BindingNormalizedNodeSerializer serializer; - @Mock - private DataTree dataTree; - @Mock - private DataTreeModification modification; - - private ConfigDataTree configDataTree; - - @Before - public void setUp() { - initMocks(this); - configDataTree = new ConfigDataTree(serializer, dataTree, writer); - } - - @Test - public void testRead() throws Exception { - final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot - snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class); - when(dataTree.takeSnapshot()).thenReturn(snapshot); - - final YangInstanceIdentifier path = mock(YangInstanceIdentifier.class); - final Optional node = mock(Optional.class); - doReturn(node).when(snapshot).readNode(path); - - final DataTreeSnapshot dataTreeSnapshot = configDataTree.takeSnapshot(); - final CheckedFuture>, ReadFailedException> future = - dataTreeSnapshot.read(path); - - verify(dataTree).takeSnapshot(); - verify(snapshot).readNode(path); - - assertTrue(future.isDone()); - assertEquals(node, future.get()); - } - - @Test - public void testNewModification() throws Exception { - final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot - snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class); - when(dataTree.takeSnapshot()).thenReturn(snapshot); - - when(snapshot.newModification()).thenReturn(modification); - - final DataTreeSnapshot dataTreeSnapshot = configDataTree.takeSnapshot(); - final DataTreeModification newModification = dataTreeSnapshot.newModification(); - verify(dataTree).takeSnapshot(); - verify(snapshot).newModification(); - - assertEquals(modification, newModification); - } - - @Test - public void testCommitSuccessful() throws Exception { - final DataObject dataBefore = mockDataObject("before", Ethernet.class); - final DataObject dataAfter = mockDataObject("after", Ethernet.class); - - // Prepare modification: - final DataTreeCandidateNode rootNode = mockRootNode(); - // data before: - final ContainerNode nodeBefore = mockContainerNode(dataBefore); - when(rootNode.getDataBefore()).thenReturn(Optional.>fromNullable(nodeBefore)); - // data after: - final ContainerNode nodeAfter = mockContainerNode(dataAfter); - when(rootNode.getDataAfter()).thenReturn(Optional.>fromNullable(nodeAfter)); - - // Run the test - configDataTree.modify(modification); - - // Verify all changes were processed: - verify(writer).update( - mapOf(dataBefore, Ethernet.class), - mapOf(dataAfter, Ethernet.class), - any(WriteContext.class)); - - // Verify modification was validated - verify(dataTree).validate(modification); - } - - private Map, DataObject> mapOf(final DataObject dataBefore, final Class type) { - return eq( - Collections., DataObject>singletonMap(InstanceIdentifier.create(type), - dataBefore)); - } - - private DataObject mockDataObject(final String name, final Class classToMock) { - final DataObject dataBefore = mock(classToMock, name); - doReturn(classToMock).when(dataBefore).getImplementedInterface(); - return dataBefore; - } - - @Test - public void testCommitUndoSuccessful() throws Exception { - // Prepare data changes: - final DataObject dataBefore = mockDataObject("before", Ethernet.class); - final DataObject dataAfter = mockDataObject("after", Ethernet.class); - - final io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter reverter = mock( - io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.class); - - // Fail on update: - final TranslationException failedOnUpdateException = new TranslationException("update failed"); - doThrow(new io.fd.honeycomb.v3po.translate.write.WriterRegistry.BulkUpdateException(InstanceIdentifier.create(Ethernet.class), reverter, - failedOnUpdateException)).when(writer).update(anyMap(), anyMap(), any(WriteContext.class)); - - // Prepare modification: - final DataTreeCandidateNode rootNode = mockRootNode(); - // data before: - final ContainerNode nodeBefore = mockContainerNode(dataBefore); - when(rootNode.getDataBefore()).thenReturn(Optional.>fromNullable(nodeBefore)); - // data after: - final ContainerNode nodeAfter = mockContainerNode(dataAfter); - when(rootNode.getDataAfter()).thenReturn(Optional.>fromNullable(nodeAfter)); - - // Run the test - try { - configDataTree.modify(modification); - } catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.BulkUpdateException e) { - verify(writer).update(anyMap(), anyMap(), any(WriteContext.class)); - verify(reverter).revert(); - assertEquals(failedOnUpdateException, e.getCause()); - return; - } - - fail("WriterRegistry.BulkUpdateException was expected"); - } - - @Test - public void testCommitUndoFailed() throws Exception { - // Prepare data changes: - final DataObject dataBefore = mockDataObject("before", Ethernet.class); - final DataObject dataAfter = mockDataObject("after", Ethernet.class); - - final io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter reverter = mock( - io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.class); - - // Fail on update: - doThrow(new io.fd.honeycomb.v3po.translate.write.WriterRegistry.BulkUpdateException(InstanceIdentifier.create(Ethernet.class), reverter, - new TranslationException("update failed"))).when(writer).update(anyMap(), anyMap(), any(WriteContext.class)); - - // Fail on revert: - final TranslationException failedOnRevertException = new TranslationException("update failed"); - final io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.RevertFailedException revertFailedException = - new io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.RevertFailedException(Collections.>emptyList(), - failedOnRevertException); - doThrow(revertFailedException).when(reverter).revert(); - - // Prepare modification: - final DataTreeCandidateNode rootNode = mockRootNode(); - // data before: - final ContainerNode nodeBefore = mockContainerNode(dataBefore); - when(rootNode.getDataBefore()).thenReturn(Optional.>fromNullable(nodeBefore)); - // data after: - final ContainerNode nodeAfter = mockContainerNode(dataAfter); - when(rootNode.getDataAfter()).thenReturn(Optional.>fromNullable(nodeAfter)); - - // Run the test - try { - configDataTree.modify(modification); - } catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.RevertFailedException e) { - verify(writer).update(anyMap(), anyMap(), any(WriteContext.class)); - verify(reverter).revert(); - assertEquals(failedOnRevertException, e.getCause()); - return; - } - - fail("RevertFailedException was expected"); - } - - private DataTreeCandidateNode mockRootNode() { - final DataTreeCandidate candidate = mock(DataTreeCandidate.class); - when(dataTree.prepare(modification)).thenReturn(candidate); - - final DataTreeCandidateNode rootNode = mock(DataTreeCandidateNode.class); - when(candidate.getRootNode()).thenReturn(rootNode); - - return rootNode; - } - - private ContainerNode mockContainerNode(DataObject... modifications) { - final int numberOfChildren = modifications.length; - - final YangInstanceIdentifier.NodeIdentifier identifier = - YangInstanceIdentifier.NodeIdentifier.create(QName.create("/")); - - final ContainerNode node = mock(ContainerNode.class); - when(node.getIdentifier()).thenReturn(identifier); - - final List list = new ArrayList<>(numberOfChildren); - doReturn(list).when(node).getValue(); - - for (DataObject modification : modifications) { - final DataContainerChild child = mock(DataContainerChild.class); - when(child.getIdentifier()).thenReturn(mock(YangInstanceIdentifier.PathArgument.class)); - list.add(child); - - final Map.Entry entry = mock(Map.Entry.class); - final Class implementedInterface = - (Class) modification.getImplementedInterface(); - final InstanceIdentifier id = InstanceIdentifier.create(implementedInterface); - - doReturn(id).when(entry).getKey(); - doReturn(modification).when(entry).getValue(); - doReturn(entry).when(serializer).fromNormalizedNode(any(YangInstanceIdentifier.class), eq(child)); - } - return node; - } -} diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataBrokerTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataBrokerTest.java index a2908d591..55b92b50b 100644 --- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataBrokerTest.java +++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/DataBrokerTest.java @@ -22,9 +22,9 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; -import io.fd.honeycomb.v3po.data.ReadableDataTree; -import io.fd.honeycomb.v3po.data.ModifiableDataTree; -import io.fd.honeycomb.v3po.data.DataTreeSnapshot; +import io.fd.honeycomb.v3po.data.ReadableDataManager; +import io.fd.honeycomb.v3po.data.ModifiableDataManager; +import io.fd.honeycomb.v3po.data.DataModification; import java.util.Map; import org.junit.Before; import org.junit.Test; @@ -42,18 +42,18 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; public class DataBrokerTest { @Mock - private ReadableDataTree operationalData; + private ReadableDataManager operationalData; @Mock - private ModifiableDataTree confiDataTree; + private ModifiableDataManager confiDataTree; @Mock - private DataTreeSnapshot configSnapshot; + private DataModification configSnapshot; private DataBroker broker; @Before public void setUp() { initMocks(this); - when(confiDataTree.takeSnapshot()).thenReturn(configSnapshot); - broker = new DataBroker(operationalData, confiDataTree); + when(confiDataTree.newModification()).thenReturn(configSnapshot); + broker = DataBroker.create(confiDataTree, operationalData); } @Test @@ -64,7 +64,7 @@ public class DataBrokerTest { // verify that read and write transactions use the same config snapshot verify(configSnapshot).read(path); - verify(configSnapshot).newModification(); + verify(confiDataTree).newModification(); } @Test @@ -72,7 +72,7 @@ public class DataBrokerTest { final DOMDataWriteTransaction writeTx = broker.newWriteOnlyTransaction(); // verify that write transactions use config snapshot - verify(configSnapshot).newModification(); + verify(confiDataTree).newModification(); } @Test diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java new file mode 100644 index 000000000..fed32da8a --- /dev/null +++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ModifiableDataTreeDelegatorTest.java @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.data.impl; + +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.Matchers.anyMap; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.Futures; +import io.fd.honeycomb.v3po.data.DataModification; +import io.fd.honeycomb.v3po.translate.TranslationException; +import io.fd.honeycomb.v3po.translate.write.WriteContext; +import io.fd.honeycomb.v3po.translate.write.WriterRegistry; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.interfaces._interface.Ethernet; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTree; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate; +import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode; + +public class ModifiableDataTreeDelegatorTest { + + @Mock + private WriterRegistry writer; + @Mock + private BindingNormalizedNodeSerializer serializer; + @Mock + private DataTree dataTree; + @Mock + private org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification modification; + @Mock + private DataBroker contextBroker; + + private ModifiableDataTreeManager configDataTree; + + @Before + public void setUp() { + initMocks(this); + configDataTree = new ModifiableDataTreeDelegator(serializer, dataTree, writer, contextBroker); + } + + @Test + public void testRead() throws Exception { + final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot + snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class); + when(dataTree.takeSnapshot()).thenReturn(snapshot); + when(snapshot.newModification()).thenReturn(modification); + + final YangInstanceIdentifier path = mock(YangInstanceIdentifier.class); + final Optional node = mock(Optional.class); + doReturn(node).when(modification).readNode(path); + + final DataModification dataTreeSnapshot = configDataTree.newModification(); + final CheckedFuture>, ReadFailedException> future = + dataTreeSnapshot.read(path); + + verify(dataTree, times(2)).takeSnapshot(); + verify(modification).readNode(path); + + assertTrue(future.isDone()); + assertEquals(node, future.get()); + } + + @Test + public void testNewModification() throws Exception { + final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot + snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class); + when(dataTree.takeSnapshot()).thenReturn(snapshot); + when(snapshot.newModification()).thenReturn(modification); + + final DataModification dataTreeSnapshot = configDataTree.newModification(); + // Snapshot captured twice, so that original data could be provided to translation layer without any possible + // modification + verify(dataTree, times(2)).takeSnapshot(); + verify(snapshot, times(2)).newModification(); + } + + @Test + public void testCommitSuccessful() throws Exception { + final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot + snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class); + when(dataTree.takeSnapshot()).thenReturn(snapshot); + when(snapshot.newModification()).thenReturn(modification); + final DataTreeCandidate prepare = mock(DataTreeCandidate.class); + doReturn(prepare).when(dataTree).prepare(modification); + + final org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction ctxTransaction = mock( + org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction.class); + doReturn(ctxTransaction).when(contextBroker).newReadWriteTransaction(); + doReturn(Futures.immediateCheckedFuture(null)).when(ctxTransaction).submit(); + + final DataObject dataBefore = mockDataObject("before", Ethernet.class); + final DataObject dataAfter = mockDataObject("after", Ethernet.class); + + // Prepare modification: + final DataTreeCandidateNode rootNode = mockRootNode(); + // data before: + final ContainerNode nodeBefore = mockContainerNode(dataBefore); + when(rootNode.getDataBefore()).thenReturn(Optional.>fromNullable(nodeBefore)); + // data after: + final ContainerNode nodeAfter = mockContainerNode(dataAfter); + when(rootNode.getDataAfter()).thenReturn(Optional.>fromNullable(nodeAfter)); + + // Run the test + doReturn(rootNode).when(prepare).getRootNode(); + final DataModification dataModification = configDataTree.newModification(); + dataModification.commit(); + + // Verify all changes were processed: + verify(writer).update( + mapOf(dataBefore, Ethernet.class), + mapOf(dataAfter, Ethernet.class), + any(WriteContext.class)); + + // Verify modification was validated + verify(dataTree).validate(modification); + // Verify context transaction was finished + verify(ctxTransaction).submit(); + } + + private Map, DataObject> mapOf(final DataObject dataBefore, final Class type) { + return eq( + Collections., DataObject>singletonMap(InstanceIdentifier.create(type), + dataBefore)); + } + + private DataObject mockDataObject(final String name, final Class classToMock) { + final DataObject dataBefore = mock(classToMock, name); + doReturn(classToMock).when(dataBefore).getImplementedInterface(); + return dataBefore; + } + + @Test + public void testCommitUndoSuccessful() throws Exception { + final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot + snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class); + when(dataTree.takeSnapshot()).thenReturn(snapshot); + when(snapshot.newModification()).thenReturn(modification); + final DataTreeCandidate prepare = mock(DataTreeCandidate.class); + doReturn(prepare).when(dataTree).prepare(modification); + + // Prepare data changes: + final DataObject dataBefore = mockDataObject("before", Ethernet.class); + final DataObject dataAfter = mockDataObject("after", Ethernet.class); + + final io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter reverter = mock( + io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.class); + + // Fail on update: + final TranslationException failedOnUpdateException = new TranslationException("update failed"); + doThrow(new io.fd.honeycomb.v3po.translate.write.WriterRegistry.BulkUpdateException(InstanceIdentifier.create(Ethernet.class), reverter, + failedOnUpdateException)).when(writer).update(anyMap(), anyMap(), any(WriteContext.class)); + + // Prepare modification: + final DataTreeCandidateNode rootNode = mockRootNode(); + // data before: + final ContainerNode nodeBefore = mockContainerNode(dataBefore); + when(rootNode.getDataBefore()).thenReturn(Optional.>fromNullable(nodeBefore)); + // data after: + final ContainerNode nodeAfter = mockContainerNode(dataAfter); + when(rootNode.getDataAfter()).thenReturn(Optional.>fromNullable(nodeAfter)); + + // Run the test + try { + doReturn(rootNode).when(prepare).getRootNode(); + final DataModification dataModification = configDataTree.newModification(); + dataModification.commit(); + } catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.BulkUpdateException e) { + verify(writer).update(anyMap(), anyMap(), any(WriteContext.class)); + verify(reverter).revert(); + assertEquals(failedOnUpdateException, e.getCause()); + return; + } + + fail("WriterRegistry.BulkUpdateException was expected"); + } + + @Test + public void testCommitUndoFailed() throws Exception { + final org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot + snapshot = mock(org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeSnapshot.class); + when(dataTree.takeSnapshot()).thenReturn(snapshot); + when(snapshot.newModification()).thenReturn(modification); + final DataTreeCandidate prepare = mock(DataTreeCandidate.class); + doReturn(prepare).when(dataTree).prepare(modification); + + // Prepare data changes: + final DataObject dataBefore = mockDataObject("before", Ethernet.class); + final DataObject dataAfter = mockDataObject("after", Ethernet.class); + + final io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter reverter = mock( + io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.class); + + // Fail on update: + doThrow(new io.fd.honeycomb.v3po.translate.write.WriterRegistry.BulkUpdateException(InstanceIdentifier.create(Ethernet.class), reverter, + new TranslationException("update failed"))).when(writer).update(anyMap(), anyMap(), any(WriteContext.class)); + + // Fail on revert: + final TranslationException failedOnRevertException = new TranslationException("update failed"); + final io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.RevertFailedException revertFailedException = + new io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.RevertFailedException(Collections.>emptyList(), + failedOnRevertException); + doThrow(revertFailedException).when(reverter).revert(); + + // Prepare modification: + final DataTreeCandidateNode rootNode = mockRootNode(); + // data before: + final ContainerNode nodeBefore = mockContainerNode(dataBefore); + when(rootNode.getDataBefore()).thenReturn(Optional.>fromNullable(nodeBefore)); + // data after: + final ContainerNode nodeAfter = mockContainerNode(dataAfter); + when(rootNode.getDataAfter()).thenReturn(Optional.>fromNullable(nodeAfter)); + + // Run the test + try { + doReturn(rootNode).when(prepare).getRootNode(); + final DataModification dataModification = configDataTree.newModification(); + dataModification.commit(); + } catch (io.fd.honeycomb.v3po.translate.write.WriterRegistry.Reverter.RevertFailedException e) { + verify(writer).update(anyMap(), anyMap(), any(WriteContext.class)); + verify(reverter).revert(); + assertEquals(failedOnRevertException, e.getCause()); + return; + } + + fail("RevertFailedException was expected"); + } + + private DataTreeCandidateNode mockRootNode() { + final DataTreeCandidate candidate = mock(DataTreeCandidate.class); + when(dataTree.prepare(modification)).thenReturn(candidate); + + final DataTreeCandidateNode rootNode = mock(DataTreeCandidateNode.class); + when(candidate.getRootNode()).thenReturn(rootNode); + + return rootNode; + } + + private ContainerNode mockContainerNode(DataObject... modifications) { + final int numberOfChildren = modifications.length; + + final YangInstanceIdentifier.NodeIdentifier identifier = + YangInstanceIdentifier.NodeIdentifier.create(QName.create("/")); + + final ContainerNode node = mock(ContainerNode.class); + when(node.getIdentifier()).thenReturn(identifier); + + final List list = new ArrayList<>(numberOfChildren); + doReturn(list).when(node).getValue(); + + for (DataObject modification : modifications) { + final DataContainerChild child = mock(DataContainerChild.class); + when(child.getIdentifier()).thenReturn(mock(YangInstanceIdentifier.PathArgument.class)); + list.add(child); + + final Map.Entry entry = mock(Map.Entry.class); + final Class implementedInterface = + (Class) modification.getImplementedInterface(); + final InstanceIdentifier id = InstanceIdentifier.create(implementedInterface); + + doReturn(id).when(entry).getKey(); + doReturn(modification).when(entry).getValue(); + doReturn(entry).when(serializer).fromNormalizedNode(any(YangInstanceIdentifier.class), eq(child)); + } + return node; + } +} diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTreeTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTreeTest.java deleted file mode 100644 index 7e6abcdcd..000000000 --- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/OperationalDataTreeTest.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2016 Cisco and/or its affiliates. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package io.fd.honeycomb.v3po.data.impl; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.same; -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 static org.mockito.Mockito.when; -import static org.mockito.MockitoAnnotations.initMocks; - -import com.google.common.base.Optional; -import com.google.common.collect.Iterables; -import com.google.common.collect.LinkedListMultimap; -import com.google.common.collect.Multimap; -import com.google.common.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.Futures; -import io.fd.honeycomb.v3po.translate.read.ReadContext; -import io.fd.honeycomb.v3po.translate.read.ReaderRegistry; -import java.util.Collections; -import java.util.Map; -import org.junit.Before; -import org.junit.Test; -import org.mockito.Mock; -import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; -import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; -import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; -import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer; -import org.opendaylight.yangtools.yang.binding.DataObject; -import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; -import org.opendaylight.yangtools.yang.common.QName; -import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; -import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; -import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; -import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; -import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; -import org.opendaylight.yangtools.yang.model.api.SchemaContext; - -public class OperationalDataTreeTest { - - @Mock - private BindingNormalizedNodeSerializer serializer; - @Mock - private ReaderRegistry reader; - - private OperationalDataTree operationalData; - - @Mock - private InstanceIdentifier id; - @Mock - private Map.Entry> entry; - @Mock - private SchemaContext globalContext; - @Mock - private DataSchemaNode schemaNode; - @Mock - private ReadContext readCtx; - @Mock - private DOMDataBroker netconfMonitoringBroker; - @Mock - private DOMDataReadOnlyTransaction domDataReadOnlyTransaction; - - @Before - public void setUp() { - initMocks(this); - operationalData = new OperationalDataTree(serializer, globalContext, reader, netconfMonitoringBroker); - doReturn(schemaNode).when(globalContext).getDataChildByName(any(QName.class)); - - doReturn(domDataReadOnlyTransaction).when(netconfMonitoringBroker).newReadOnlyTransaction(); - doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(domDataReadOnlyTransaction) - .read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)); - } - - @Test - public void testReadNode() throws Exception { - final YangInstanceIdentifier yangId = mock(YangInstanceIdentifier.class); - final YangInstanceIdentifier.PathArgument pArg = mock(YangInstanceIdentifier.PathArgument.class); - doReturn(pArg).when(yangId).getLastPathArgument(); - doReturn(Collections.singletonList(pArg)).when(yangId).getPathArguments(); - - doReturn(QName.create("namespace", "2012-12-12", "local")).when(pArg).getNodeType(); - doReturn(id).when(serializer).fromYangInstanceIdentifier(yangId); - - final DataObject dataObject = mock(DataObject.class); - doReturn(Optional.of(dataObject)).when(reader).read(same(id), any(ReadContext.class)); - - when(serializer.toNormalizedNode(id, dataObject)).thenReturn(entry); - final DataContainerChild expectedValue = mock(DataContainerChild.class); - doReturn(expectedValue).when(entry).getValue(); - - final CheckedFuture>, ReadFailedException> future = operationalData.read(yangId); - - verify(serializer).fromYangInstanceIdentifier(yangId); - verify(reader).read(same(id), any(ReadContext.class)); - final Optional> result = future.get(); - assertTrue(result.isPresent()); - assertEquals(expectedValue, result.get()); - } - - @Test - public void testReadNonExistingNode() throws Exception { - final YangInstanceIdentifier yangId = mock(YangInstanceIdentifier.class); - doReturn(id).when(serializer).fromYangInstanceIdentifier(yangId); - doReturn(Optional.absent()).when(reader).read(same(id), any(ReadContext.class)); - - final CheckedFuture>, ReadFailedException> future = operationalData.read(yangId); - - verify(serializer).fromYangInstanceIdentifier(yangId); - verify(reader).read(same(id), any(ReadContext.class)); - final Optional> result = future.get(); - assertFalse(result.isPresent()); - } - - @Test - public void testReadFailed() throws Exception{ - doThrow(io.fd.honeycomb.v3po.translate.read.ReadFailedException.class).when(reader).readAll(any(ReadContext.class)); - - final CheckedFuture>, ReadFailedException> future = - operationalData.read( YangInstanceIdentifier.EMPTY); - - try { - future.checkedGet(); - } catch (ReadFailedException e) { - assertTrue(e.getCause() instanceof io.fd.honeycomb.v3po.translate.read.ReadFailedException); - return; - } - fail("ReadFailedException was expected"); - } - - @Test - public void testReadRootWithOneNonListElement() throws Exception { - // Prepare data - final InstanceIdentifier vppStateII = InstanceIdentifier.create(VppState.class); - final VppState vppState = mock(VppState.class); - Multimap, DataObject> dataObjects = LinkedListMultimap.create(); - dataObjects.put(vppStateII, vppState); - doReturn(dataObjects).when(reader).readAll(any(ReadContext.class)); - - // Init serializer - final YangInstanceIdentifier vppYangId = YangInstanceIdentifier.builder().node(VppState.QNAME).build(); - when(serializer.toYangInstanceIdentifier(vppStateII)).thenReturn(vppYangId); - when(serializer.toNormalizedNode(vppStateII, vppState)).thenReturn(entry); - final DataContainerChild vppStateContainer = mock(DataContainerChild.class); - doReturn(vppStateContainer).when(entry).getValue(); - doReturn(vppYangId.getLastPathArgument()).when(vppStateContainer).getIdentifier(); - - // Read root - final CheckedFuture>, ReadFailedException> future = - operationalData.read(YangInstanceIdentifier.EMPTY); - - verify(reader).readAll(any(ReadContext.class)); - verify(serializer).toYangInstanceIdentifier(vppStateII); - verify(serializer).toNormalizedNode(vppStateII, vppState); - - // Check the result is an ContainerNode with only one child - final Optional> result = future.get(); - assertTrue(result.isPresent()); - - final ContainerNode rootNode = (ContainerNode) result.get(); - assertEquals(SchemaContext.NAME, rootNode.getIdentifier().getNodeType()); - assertEquals(vppStateContainer, Iterables.getOnlyElement(rootNode.getValue())); - } -} \ No newline at end of file diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransactionTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransactionTest.java index 30fdd1392..a13621725 100644 --- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransactionTest.java +++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadOnlyTransactionTest.java @@ -24,8 +24,8 @@ import static org.mockito.MockitoAnnotations.initMocks; import com.google.common.base.Optional; import com.google.common.util.concurrent.CheckedFuture; -import io.fd.honeycomb.v3po.data.ReadableDataTree; -import io.fd.honeycomb.v3po.data.DataTreeSnapshot; +import io.fd.honeycomb.v3po.data.ReadableDataManager; +import io.fd.honeycomb.v3po.data.DataModification; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -37,16 +37,16 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; public class ReadOnlyTransactionTest { @Mock - private ReadableDataTree operationalData; + private ReadableDataManager operationalData; @Mock - private DataTreeSnapshot configSnapshot; + private DataModification configSnapshot; private ReadOnlyTransaction readOnlyTx; @Before public void setUp() { initMocks(this); - readOnlyTx = new ReadOnlyTransaction(operationalData, configSnapshot); + readOnlyTx = ReadOnlyTransaction.create(configSnapshot, operationalData); } @Test diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java new file mode 100644 index 000000000..4492c70a2 --- /dev/null +++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/ReadableDataTreeDelegatorTest.java @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2016 Cisco and/or its affiliates. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.fd.honeycomb.v3po.data.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.same; +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 static org.mockito.Mockito.when; +import static org.mockito.MockitoAnnotations.initMocks; + +import com.google.common.base.Optional; +import com.google.common.collect.Iterables; +import com.google.common.collect.LinkedListMultimap; +import com.google.common.collect.Multimap; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.Futures; +import io.fd.honeycomb.v3po.translate.read.ReadContext; +import io.fd.honeycomb.v3po.translate.read.ReaderRegistry; +import java.util.Collections; +import java.util.Map; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException; +import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker; +import org.opendaylight.controller.md.sal.dom.api.DOMDataReadOnlyTransaction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev150105.VppState; +import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.common.QName; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild; +import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; +import org.opendaylight.yangtools.yang.model.api.DataSchemaNode; +import org.opendaylight.yangtools.yang.model.api.SchemaContext; + +public class ReadableDataTreeDelegatorTest { + + @Mock + private BindingNormalizedNodeSerializer serializer; + @Mock + private ReaderRegistry reader; + + private ReadableDataTreeDelegator operationalData; + + @Mock + private InstanceIdentifier id; + @Mock + private Map.Entry> entry; + @Mock + private SchemaContext globalContext; + @Mock + private DataSchemaNode schemaNode; + @Mock + private ReadContext readCtx; + @Mock + private DOMDataBroker netconfMonitoringBroker; + @Mock + private DOMDataReadOnlyTransaction domDataReadOnlyTransaction; + @Mock + private DataBroker contextBroker; + + @Before + public void setUp() { + initMocks(this); + operationalData = new ReadableDataTreeDelegator(serializer, globalContext, reader, netconfMonitoringBroker, contextBroker); + doReturn(schemaNode).when(globalContext).getDataChildByName(any(QName.class)); + + doReturn(domDataReadOnlyTransaction).when(netconfMonitoringBroker).newReadOnlyTransaction(); + doReturn(Futures.immediateCheckedFuture(Optional.absent())).when(domDataReadOnlyTransaction) + .read(any(LogicalDatastoreType.class), any(YangInstanceIdentifier.class)); + + final org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction ctxTransaction = mock( + org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction.class); + doReturn(ctxTransaction).when(contextBroker).newReadWriteTransaction(); + doReturn(Futures.immediateCheckedFuture(null)).when(ctxTransaction).submit(); + } + + @Test + public void testReadNode() throws Exception { + final YangInstanceIdentifier yangId = mock(YangInstanceIdentifier.class); + final YangInstanceIdentifier.PathArgument pArg = mock(YangInstanceIdentifier.PathArgument.class); + doReturn(pArg).when(yangId).getLastPathArgument(); + doReturn(Collections.singletonList(pArg)).when(yangId).getPathArguments(); + + doReturn(QName.create("namespace", "2012-12-12", "local")).when(pArg).getNodeType(); + doReturn(id).when(serializer).fromYangInstanceIdentifier(yangId); + + final DataObject dataObject = mock(DataObject.class); + doReturn(Optional.of(dataObject)).when(reader).read(same(id), any(ReadContext.class)); + + when(serializer.toNormalizedNode(id, dataObject)).thenReturn(entry); + final DataContainerChild expectedValue = mock(DataContainerChild.class); + doReturn(expectedValue).when(entry).getValue(); + + final CheckedFuture>, ReadFailedException> future = operationalData.read(yangId); + + verify(serializer).fromYangInstanceIdentifier(yangId); + verify(reader).read(same(id), any(ReadContext.class)); + final Optional> result = future.get(); + assertTrue(result.isPresent()); + assertEquals(expectedValue, result.get()); + } + + @Test + public void testReadNonExistingNode() throws Exception { + final YangInstanceIdentifier yangId = mock(YangInstanceIdentifier.class); + doReturn(id).when(serializer).fromYangInstanceIdentifier(yangId); + doReturn(Optional.absent()).when(reader).read(same(id), any(ReadContext.class)); + + final CheckedFuture>, ReadFailedException> future = operationalData.read(yangId); + + verify(serializer).fromYangInstanceIdentifier(yangId); + verify(reader).read(same(id), any(ReadContext.class)); + final Optional> result = future.get(); + assertFalse(result.isPresent()); + } + + @Test + public void testReadFailed() throws Exception{ + doThrow(io.fd.honeycomb.v3po.translate.read.ReadFailedException.class).when(reader).readAll(any(ReadContext.class)); + + final CheckedFuture>, ReadFailedException> future = + operationalData.read( YangInstanceIdentifier.EMPTY); + + try { + future.checkedGet(); + } catch (ReadFailedException e) { + assertTrue(e.getCause() instanceof io.fd.honeycomb.v3po.translate.read.ReadFailedException); + return; + } + fail("ReadFailedException was expected"); + } + + @Test + public void testReadRootWithOneNonListElement() throws Exception { + // Prepare data + final InstanceIdentifier vppStateII = InstanceIdentifier.create(VppState.class); + final VppState vppState = mock(VppState.class); + Multimap, DataObject> dataObjects = LinkedListMultimap.create(); + dataObjects.put(vppStateII, vppState); + doReturn(dataObjects).when(reader).readAll(any(ReadContext.class)); + + // Init serializer + final YangInstanceIdentifier vppYangId = YangInstanceIdentifier.builder().node(VppState.QNAME).build(); + when(serializer.toYangInstanceIdentifier(vppStateII)).thenReturn(vppYangId); + when(serializer.toNormalizedNode(vppStateII, vppState)).thenReturn(entry); + final DataContainerChild vppStateContainer = mock(DataContainerChild.class); + doReturn(vppStateContainer).when(entry).getValue(); + doReturn(vppYangId.getLastPathArgument()).when(vppStateContainer).getIdentifier(); + + // Read root + final CheckedFuture>, ReadFailedException> future = + operationalData.read(YangInstanceIdentifier.EMPTY); + + verify(reader).readAll(any(ReadContext.class)); + verify(serializer).toYangInstanceIdentifier(vppStateII); + verify(serializer).toNormalizedNode(vppStateII, vppState); + + // Check the result is an ContainerNode with only one child + final Optional> result = future.get(); + assertTrue(result.isPresent()); + + final ContainerNode rootNode = (ContainerNode) result.get(); + assertEquals(SchemaContext.NAME, rootNode.getIdentifier().getNodeType()); + assertEquals(vppStateContainer, Iterables.getOnlyElement(rootNode.getValue())); + } +} \ No newline at end of file diff --git a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/WriteTransactionTest.java b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/WriteTransactionTest.java index d0360dbd8..9cde27d2b 100644 --- a/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/WriteTransactionTest.java +++ b/v3po/data-impl/src/test/java/io/fd/honeycomb/v3po/data/impl/WriteTransactionTest.java @@ -23,12 +23,10 @@ import static org.junit.Assert.fail; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; import com.google.common.util.concurrent.CheckedFuture; -import io.fd.honeycomb.v3po.data.ModifiableDataTree; -import io.fd.honeycomb.v3po.data.DataTreeSnapshot; +import io.fd.honeycomb.v3po.data.DataModification; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; @@ -36,54 +34,48 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; 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.DataValidationFailedException; public class WriteTransactionTest { @Mock - private ModifiableDataTree configDataTree; - @Mock - private DataTreeSnapshot configSnapshot; + private DataModification configSnapshot; @Mock private YangInstanceIdentifier path; @Mock private NormalizedNode data; - @Mock - private DataTreeModification dataTreeModification; private WriteTransaction writeTx; @Before public void setUp() { initMocks(this); - when(configSnapshot.newModification()).thenReturn(dataTreeModification); - writeTx = new WriteTransaction(configDataTree, configSnapshot); + writeTx = WriteTransaction.createConfigOnly(configSnapshot); } @Test public void testPut() { writeTx.put(LogicalDatastoreType.CONFIGURATION, path, data); - verify(dataTreeModification).write(path, data); + verify(configSnapshot).write(path, data); } @Test(expected = IllegalArgumentException.class) public void testPutOperational() { writeTx.put(LogicalDatastoreType.OPERATIONAL, path, data); - verify(dataTreeModification).write(path, data); + verify(configSnapshot).write(path, data); } @Test(expected = IllegalStateException.class) public void testOnFinishedTx() { writeTx.submit(); writeTx.put(LogicalDatastoreType.CONFIGURATION, path, data); - verify(dataTreeModification).write(path, data); + verify(configSnapshot).write(path, data); } @Test public void testMerge() { writeTx.merge(LogicalDatastoreType.CONFIGURATION, path, data); - verify(dataTreeModification).merge(path, data); + verify(configSnapshot).merge(path, data); } @Test @@ -100,19 +92,19 @@ public class WriteTransactionTest { @Test public void testDelete() { writeTx.delete(LogicalDatastoreType.CONFIGURATION, path); - verify(dataTreeModification).delete(path); + verify(configSnapshot).delete(path); } @Test public void testSubmit() throws Exception { writeTx.submit(); - verify(dataTreeModification).ready(); - verify(configDataTree).modify(dataTreeModification); + verify(configSnapshot).validate(); + verify(configSnapshot).commit(); } @Test public void testSubmitFailed() throws Exception { - doThrow(mock(DataValidationFailedException.class)).when(configDataTree).modify(dataTreeModification); + doThrow(mock(DataValidationFailedException.class)).when(configSnapshot).commit(); final CheckedFuture future = writeTx.submit(); try { future.get(); -- cgit 1.2.3-korg