diff options
author | Jan Srnicek <jsrnicek@cisco.com> | 2017-11-03 13:33:53 +0100 |
---|---|---|
committer | Marek Gradzki <mgradzki@cisco.com> | 2017-11-03 12:58:01 +0000 |
commit | 9779f4b3ffe24bb2338630c66169da92c880ffbb (patch) | |
tree | fac37c53b70b7bbfcea00f180554b3a0dfddd59c /infra/translate-impl/src/test/java | |
parent | 054eb07de938df56000a8fc5cb41cb77f84bf2b5 (diff) |
HONEYCOMB-359 - Wildcarded writers
Adds option to specify subtree writer that can handle whole subtree
of nodes without having whole subtree specified. Its checking
if node is children at runtime, rather than having pre-computed tree
Change-Id: Ic46f2bd6de84f0dd14865825399f5a90a1f80859
Signed-off-by: Jan Srnicek <jsrnicek@cisco.com>
Diffstat (limited to 'infra/translate-impl/src/test/java')
2 files changed, 181 insertions, 6 deletions
diff --git a/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryTest.java b/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryTest.java index 151436975..01852d13f 100644 --- a/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryTest.java +++ b/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/FlatWriterRegistryTest.java @@ -25,6 +25,7 @@ import static org.mockito.Matchers.any; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.verifyZeroInteractions; @@ -39,15 +40,19 @@ import io.fd.honeycomb.translate.util.DataObjects.DataObject1; import io.fd.honeycomb.translate.util.DataObjects.DataObject2; import io.fd.honeycomb.translate.write.DataObjectUpdate; import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.WriteFailedException; import io.fd.honeycomb.translate.write.Writer; import io.fd.honeycomb.translate.write.registry.UpdateFailedException; import io.fd.honeycomb.translate.write.registry.WriterRegistry; import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.junit.Before; import org.junit.Test; import org.mockito.InOrder; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.mockito.stubbing.Answer; import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -72,6 +77,18 @@ public class FlatWriterRegistryTest { when(writer1.getManagedDataObjectType()).thenReturn(DataObject1.IID); when(writer2.getManagedDataObjectType()).thenReturn(DataObject2.IID); when(writer3.getManagedDataObjectType()).thenReturn(DataObjects.DataObject3.IID); + when(writer4.getManagedDataObjectType()).thenReturn(DataObjects.DataObject1ChildK.IID); + // TODO - HONEYCOMB-412 - thenCallRealMethod doest work with default methods + // https://stackoverflow.com/questions/27663252/can-you-make-mockito-1-10-17-work-with-default-methods-in-interfaces + when(writer1.canProcess(any())).thenAnswer(answerWithImpl()); + when(writer2.canProcess(any())).thenAnswer(answerWithImpl()); + when(writer3.canProcess(any())).thenAnswer(answerWithImpl()); + when(writer4.canProcess(any())).thenAnswer(answerWithImpl()); + } + + private static Answer<Object> answerWithImpl() { + return invocationOnMock -> new CheckedMockWriter(Writer.class.cast(invocationOnMock.getMock())).canProcess( + InstanceIdentifier.class.cast(invocationOnMock.getArguments()[0])); } @Test @@ -112,8 +129,12 @@ public class FlatWriterRegistryTest { inOrder.verify(writer1).processModification(iid, dataObject, dataObject, ctx); inOrder.verify(writer2).processModification(iid2, dataObject2, dataObject2, ctx); - verifyNoMoreInteractions(writer1); - verifyNoMoreInteractions(writer2); + // TODO - HONEYCOMB-412 -reintroduce verifyNoMoreInteractions and remove manual verify + // we are really interested just in invocations of processModification(),so adding specific verify to check that + verify(writer1,times(1)).processModification(any(),any(),any(),any()); + verify(writer2,times(1)).processModification(any(),any(),any(),any()); + //verifyNoMoreInteractions(writer1); + //verifyNoMoreInteractions(writer2); } @Test @@ -136,8 +157,12 @@ public class FlatWriterRegistryTest { inOrder.verify(writer2).processModification(iid2, dataObject2, null, ctx); inOrder.verify(writer1).processModification(iid, dataObject, null, ctx); - verifyNoMoreInteractions(writer1); - verifyNoMoreInteractions(writer2); + // TODO - HONEYCOMB-412 -reintroduce verifyNoMoreInteractions and remove manual verify + // we are really interested just in invocations of processModification(),so adding specific verify to check that + verify(writer1,times(1)).processModification(any(),any(),any(),any()); + verify(writer2,times(1)).processModification(any(),any(),any(),any()); + //verifyNoMoreInteractions(writer1); + //verifyNoMoreInteractions(writer2); } @Test @@ -170,8 +195,12 @@ public class FlatWriterRegistryTest { inOrder.verify(writer1).processModification(iid, dataObject, dataObject, ctx); inOrder.verify(writer2).processModification(iid2, dataObject2, dataObject2, ctx); - verifyNoMoreInteractions(writer1); - verifyNoMoreInteractions(writer2); + // TODO - HONEYCOMB-412 -reintroduce verifyNoMoreInteractions and remove manual verify + // we are really interested just in invocations of processModification(),so adding specific verify to check that + verify(writer1,times(2)).processModification(any(),any(),any(),any()); + verify(writer2,times(2)).processModification(any(),any(),any(),any()); + //verifyNoMoreInteractions(writer1); + //verifyNoMoreInteractions(writer2); } @Test(expected = IllegalArgumentException.class) @@ -298,4 +327,35 @@ public class FlatWriterRegistryTest { final InstanceIdentifier<D> iid) { return DataObjectUpdate.create(iid, mock(type), mock(type)); } + + //TODO - HONEYCOMB-412 - remove after + /** + * Used to utilize default implementation of canProcess() + * */ + static class CheckedMockWriter implements Writer{ + + private final Writer mockedWriter; + + CheckedMockWriter(final Writer mockedWriter) { + this.mockedWriter = mockedWriter; + } + + @Override + public void processModification(@Nonnull final InstanceIdentifier id, @Nullable final DataObject dataBefore, + @Nullable final DataObject dataAfter, @Nonnull final WriteContext ctx) + throws WriteFailedException { + mockedWriter.processModification(id,dataBefore,dataAfter,ctx); + } + + @Override + public boolean supportsDirectUpdate() { + return mockedWriter.supportsDirectUpdate(); + } + + @Nonnull + @Override + public InstanceIdentifier getManagedDataObjectType() { + return mockedWriter.getManagedDataObjectType(); + } + } }
\ No newline at end of file diff --git a/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/WildcardedSubtreeWriterTest.java b/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/WildcardedSubtreeWriterTest.java new file mode 100644 index 000000000..7006eeaf4 --- /dev/null +++ b/infra/translate-impl/src/test/java/io/fd/honeycomb/translate/impl/write/registry/WildcardedSubtreeWriterTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017 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.translate.impl.write.registry; + +import io.fd.honeycomb.translate.write.Writer; +import org.junit.Before; +import org.junit.Test; +import org.mockito.MockitoAnnotations; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.AugTarget; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.FromAugmentAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.FromAugmentListAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.SimpleNestedAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.aug.target.FromAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.aug.target.from.augment.FromAugmentEntry; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithChoice; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.choice.choice.c3.C3; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainer; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.ContainerInList; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.container.in.list.NestedList; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class WildcardedSubtreeWriterTest { + + private static final InstanceIdentifier<ContainerWithList> C_WITH_LIST = InstanceIdentifier.create(ContainerWithList.class); + private static final InstanceIdentifier<ContainerWithChoice> C_WITH_CHOICE = InstanceIdentifier.create(ContainerWithChoice.class); + private static final InstanceIdentifier<AugTarget> C_AUG = InstanceIdentifier.create(AugTarget.class); + + private static final InstanceIdentifier<ListInContainer> L_IN_CONTAINER = C_WITH_LIST.child(ListInContainer.class); + private static final InstanceIdentifier<ContainerInList> C_IN_LIST = L_IN_CONTAINER.child(ContainerInList.class); + + private static final InstanceIdentifier<NestedList> N_LIST = C_IN_LIST.child(NestedList.class); + + private Writer subtreeContainerWithList; + private Writer subtreeContainerWithChoice; + private Writer subtreeAugTarget; + + + @Before + public void init() { + MockitoAnnotations.initMocks(this); + Writer<ContainerWithList> writerContainerWithList = mock(Writer.class); + Writer<ContainerWithChoice> writerContainerWithChoice = mock(Writer.class); + Writer<AugTarget> writerAugTarget = mock(Writer.class); + when(writerContainerWithList.getManagedDataObjectType()).thenReturn(C_WITH_LIST); + when(writerContainerWithChoice.getManagedDataObjectType()).thenReturn(C_WITH_CHOICE); + when(writerAugTarget.getManagedDataObjectType()).thenReturn(C_AUG); + subtreeContainerWithList = SubtreeWriter.createWildcardedForWriter(writerContainerWithList); + subtreeContainerWithChoice = SubtreeWriter.createWildcardedForWriter(writerContainerWithChoice); + subtreeAugTarget = SubtreeWriter.createWildcardedForWriter(writerAugTarget); + } + + @Test + public void testParent() { + assertTrue(subtreeContainerWithList.canProcess(C_WITH_LIST)); + assertFalse(subtreeContainerWithList.canProcess(C_WITH_CHOICE)); + + assertTrue(subtreeContainerWithChoice.canProcess(C_WITH_CHOICE)); + assertFalse(subtreeContainerWithChoice.canProcess(C_WITH_LIST)); + + assertTrue(subtreeAugTarget.canProcess(C_AUG)); + assertFalse(subtreeAugTarget.canProcess(C_WITH_LIST)); + } + + @Test + public void testDirectChild() { + assertTrue(subtreeContainerWithList.canProcess(L_IN_CONTAINER)); + assertFalse(subtreeContainerWithList.canProcess(C_WITH_CHOICE.child(C3.class))); + + assertTrue(subtreeContainerWithChoice.canProcess(C_WITH_CHOICE.child(C3.class))); + assertFalse(subtreeContainerWithChoice.canProcess(L_IN_CONTAINER)); + } + + @Test + public void testIndirectChild() { + assertTrue(subtreeContainerWithList.canProcess(C_IN_LIST)); + assertTrue(subtreeContainerWithList.canProcess(N_LIST)); + } + + @Test + public void testAugDirectChild() { + assertTrue(subtreeAugTarget.canProcess(C_AUG.augmentation(FromAugmentAugment.class).child(FromAugment.class))); + assertFalse(subtreeContainerWithList.canProcess(C_AUG.augmentation(FromAugmentAugment.class).child(FromAugment.class))); + } + + @Test + public void testAugIndirectChild() { + assertTrue(subtreeAugTarget.canProcess(C_AUG.augmentation(FromAugmentAugment.class) + .child(FromAugment.class) + .augmentation(SimpleNestedAugment.class))); + assertFalse(subtreeContainerWithList.canProcess(C_AUG.augmentation(FromAugmentAugment.class) + .child(FromAugment.class) + .augmentation(FromAugmentListAugment.class) + .child(FromAugmentEntry.class))); + } +} |