From 60e463b17b05458c1f9a7fd72f9e99d71124eedf Mon Sep 17 00:00:00 2001 From: Marek Gradzki Date: Tue, 17 Jan 2017 13:30:50 +0100 Subject: HONEYCOMB-302: add support for nested augmentations Change-Id: I60f1b3f79ddb578d6fca157fe5736de40b30623e Signed-off-by: Marek Gradzki (cherry picked from commit 78886acd688284585c2e219e18d7289f49cc8a45) --- .../fd/honeycomb/data/impl/AbstractInfraTest.java | 9 +- .../data/impl/NestedAugmentationWriteTest.java | 280 +++++++++++++++++++++ 2 files changed, 286 insertions(+), 3 deletions(-) create mode 100644 infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/NestedAugmentationWriteTest.java (limited to 'infra/it/it-test') diff --git a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/AbstractInfraTest.java b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/AbstractInfraTest.java index 3c996f6a6..e2a74ab69 100644 --- a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/AbstractInfraTest.java +++ b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/AbstractInfraTest.java @@ -21,14 +21,13 @@ import static org.mockito.Mockito.when; import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.util.concurrent.Futures; -import java.util.Collections; +import java.util.Arrays; import java.util.Map; import javassist.ClassPool; import org.junit.Before; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.opendaylight.controller.md.sal.binding.impl.BindingToNormalizedNodeCodec; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.$YangModuleInfoImpl; import org.opendaylight.yangtools.binding.data.codec.api.BindingNormalizedNodeSerializer; import org.opendaylight.yangtools.binding.data.codec.gen.impl.DataObjectSerializerGenerator; import org.opendaylight.yangtools.binding.data.codec.gen.impl.StreamWriterGenerator; @@ -70,7 +69,11 @@ abstract class AbstractInfraTest { static ModuleInfoBackedContext getSchemaContext() { final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create(); - moduleInfoBackedContext.addModuleInfos(Collections.singleton($YangModuleInfoImpl.getInstance())); + moduleInfoBackedContext.addModuleInfos(Arrays.asList( + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.$YangModuleInfoImpl.getInstance(), + org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.$YangModuleInfoImpl.getInstance() + + )); return moduleInfoBackedContext; } diff --git a/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/NestedAugmentationWriteTest.java b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/NestedAugmentationWriteTest.java new file mode 100644 index 000000000..ef7430dd3 --- /dev/null +++ b/infra/it/it-test/src/test/java/io/fd/honeycomb/data/impl/NestedAugmentationWriteTest.java @@ -0,0 +1,280 @@ +/* + * 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.data.impl; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import io.fd.honeycomb.data.DataModification; +import io.fd.honeycomb.translate.impl.write.registry.FlatWriterRegistryBuilder; +import io.fd.honeycomb.translate.write.WriteContext; +import io.fd.honeycomb.translate.write.Writer; +import io.fd.honeycomb.translate.write.registry.WriterRegistry; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +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.AugTargetBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.FromAugment2Augment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.FromAugment2AugmentBuilder; +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.FromAugmentAugmentBuilder; +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.FromAugmentListAugmentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.SimpleAugment; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.SimpleAugmentBuilder; +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.SimpleNestedAugmentBuilder; +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.FromAugmentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.aug.target.from.augment.FromAugment2; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.aug.target.from.augment.FromAugment2Builder; +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.aug.test.rev161222.aug.target.from.augment.FromAugmentEntryBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.aug.test.rev161222.aug.target.from.augment.FromAugmentEntryKey; +import org.opendaylight.yangtools.yang.binding.Augmentation; +import org.opendaylight.yangtools.yang.binding.DataObject; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; +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.TipProducingDataTree; +import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType; +import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory; + +/** + * Testing write for model with nested augmentation. + * See HONEYCOMB-302} for more details. + */ +public class NestedAugmentationWriteTest extends AbstractInfraTest { + + private static final InstanceIdentifier AUG_TARGET_ID = InstanceIdentifier.create(AugTarget.class); + private static final InstanceIdentifier FROM_AUGMENT_AUGMENT_ID = + AUG_TARGET_ID.augmentation(FromAugmentAugment.class); + private static final InstanceIdentifier FROM_AUGMENT_ID = + FROM_AUGMENT_AUGMENT_ID.child(FromAugment.class); + private static final InstanceIdentifier SIMPLE_AUGMENT_ID = + AUG_TARGET_ID.augmentation(SimpleAugment.class); + private static final InstanceIdentifier FROM_AUGMENT2_AUGMENT_ID = + FROM_AUGMENT_ID.augmentation(FromAugment2Augment.class); + private static final InstanceIdentifier FROM_AUGMENT2_ID = + FROM_AUGMENT2_AUGMENT_ID.child(FromAugment2.class); + private static final InstanceIdentifier SIMPLE_NESTED_AUGMENT_ID = + FROM_AUGMENT_ID.augmentation(SimpleNestedAugment.class); + private static final InstanceIdentifier FROM_AUGMENT_LIST_AUGMENT_ID = + FROM_AUGMENT_ID.augmentation(FromAugmentListAugment.class); + private static final InstanceIdentifier FROM_AUGMENT_ENTRY_ID = + FROM_AUGMENT_LIST_AUGMENT_ID.child(FromAugmentEntry.class); + + private TipProducingDataTree dataTree; + private WriterRegistry writerRegistry; + + private final Writer augTargetWriter = mockWriter(AUG_TARGET_ID); + private final Writer fromAugmentWriter = mockWriter(FROM_AUGMENT_ID); + private final Writer fromAugment2Writer = mockWriter(FROM_AUGMENT2_ID); + private final Writer fromAugmentListWriter = mockWriter(FROM_AUGMENT_ENTRY_ID); + + private final Writer simpleAugmentWriter = mockWriter(SIMPLE_AUGMENT_ID); + private final Writer simpleNestedAugmentWriter = mockWriter(SIMPLE_NESTED_AUGMENT_ID); + + private static Writer mockWriter(final InstanceIdentifier id) { + final Writer mock = (Writer) mock(Writer.class); + when(mock.getManagedDataObjectType()).thenReturn(id); + return mock; + } + + @Override + void postSetup() { + initDataTree(); + initWriterRegistry(); + } + + private void initDataTree() { + dataTree = InMemoryDataTreeFactory.getInstance().create(TreeType.CONFIGURATION); + dataTree.setSchemaContext(schemaContext); + } + + private void initWriterRegistry() { + writerRegistry = new FlatWriterRegistryBuilder() + .add(augTargetWriter) + .add(fromAugmentWriter) + .add(simpleAugmentWriter) + .add(fromAugment2Writer) + .add(simpleNestedAugmentWriter) + .add(fromAugmentListWriter) + .build(); + } + + @Test + public void testSimpleAugmentationWrite() throws Exception { + final ModifiableDataTreeDelegator modifiableDataTreeDelegator = + new ModifiableDataTreeDelegator(serializer, dataTree, schemaContext, writerRegistry, contextBroker); + + final DataModification dataModification = modifiableDataTreeDelegator.newModification(); + final AugTarget data = new AugTargetBuilder() + .setSomeLeaf("aug-target-leaf-val") + .addAugmentation(SimpleAugment.class, simpleAugment()) + .build(); + + final Map.Entry> normalizedNode = + serializer.toNormalizedNode(AUG_TARGET_ID, data); + dataModification.write(normalizedNode.getKey(), normalizedNode.getValue()); + + dataModification.commit(); + + verify(simpleAugmentWriter).update(eq(SIMPLE_AUGMENT_ID), eq(null), eq(simpleAugment()), any(WriteContext.class)); + } + + @Test + public void testSimpleNestedAugmentationWrite() throws Exception { + final ModifiableDataTreeDelegator modifiableDataTreeDelegator = + new ModifiableDataTreeDelegator(serializer, dataTree, schemaContext, writerRegistry, contextBroker); + + final DataModification dataModification = modifiableDataTreeDelegator.newModification(); + + final SimpleNestedAugment augData = simpleNestedAugment(); + final AugTarget data = augTarget(fromAugmentSimple(augData)); + + final Map.Entry> normalizedNode = + serializer.toNormalizedNode(AUG_TARGET_ID, data); + dataModification.write(normalizedNode.getKey(), normalizedNode.getValue()); + + dataModification.commit(); + + verify(augTargetWriter).update(eq(AUG_TARGET_ID), eq(null), eq(data), any(WriteContext.class)); + verify(fromAugmentWriter).update(eq(FROM_AUGMENT_ID), eq(null), eq(fromAugmentSimple(augData)), any(WriteContext.class)); + verify(simpleNestedAugmentWriter).update(eq(SIMPLE_NESTED_AUGMENT_ID), eq(null), eq(augData), any(WriteContext.class)); + } + + private SimpleAugment simpleAugment() { + return new SimpleAugmentBuilder().setSimpleAugmentLeaf("val").build(); + } + + @Test + public void testNestedAugmentationWrite() throws Exception { + final ModifiableDataTreeDelegator modifiableDataTreeDelegator = + new ModifiableDataTreeDelegator(serializer, dataTree, schemaContext, writerRegistry, contextBroker); + + final DataModification dataModification = modifiableDataTreeDelegator.newModification(); + final AugTarget data = augTarget(fromAugment(FromAugment2Augment.class, fromAugment2Augment(fromAugment2()))); + + final Map.Entry> normalizedNode = + serializer.toNormalizedNode(AUG_TARGET_ID, data); + dataModification.write(normalizedNode.getKey(), normalizedNode.getValue()); + + dataModification.commit(); + + verify(augTargetWriter).update(eq(AUG_TARGET_ID), eq(null), eq(data), any(WriteContext.class)); + verify(fromAugmentWriter).update(eq(FROM_AUGMENT_ID), eq(null), eq(fromAugment()), any(WriteContext.class)); + verify(fromAugment2Writer).update(eq(FROM_AUGMENT2_ID), eq(null), eq(fromAugment2()), any(WriteContext.class)); + } + + @Test + public void testNestedAugmentationListWrite() throws Exception { + final ModifiableDataTreeDelegator modifiableDataTreeDelegator = + new ModifiableDataTreeDelegator(serializer, dataTree, schemaContext, writerRegistry, contextBroker); + + final DataModification dataModification = modifiableDataTreeDelegator.newModification(); + final List entries = Arrays.asList( + new FromAugmentEntryBuilder().setSomeLeaf("1").build(), + new FromAugmentEntryBuilder().setSomeLeaf("2").build() + ); + final FromAugment fromAugment = fromAugment(FromAugmentListAugment.class, fromAugmentList(entries)); + final AugTarget data = augTarget(fromAugment); + + final Map.Entry> normalizedNode = + serializer.toNormalizedNode(AUG_TARGET_ID, data); + dataModification.write(normalizedNode.getKey(), normalizedNode.getValue()); + dataModification.commit(); + + final ArgumentCaptor doCaptor = ArgumentCaptor.forClass(DataObject.class); + verify(augTargetWriter).update(eq(AUG_TARGET_ID), eq(null), doCaptor.capture(), any(WriteContext.class)); + assertEquals(data.getSomeLeaf(), ((AugTarget)doCaptor.getValue()).getSomeLeaf()); + + verify(fromAugmentWriter).update(eq(FROM_AUGMENT_ID), eq(null), doCaptor.capture(), any(WriteContext.class)); + assertEquals(fromAugment.getSomeLeaf(), ((FromAugment)doCaptor.getValue()).getSomeLeaf()); + + + final KeyedInstanceIdentifier keyedNestedList1 = + FROM_AUGMENT_LIST_AUGMENT_ID.child(FromAugmentEntry.class, new FromAugmentEntryKey("1")); + final KeyedInstanceIdentifier keyedNestedList2 = + FROM_AUGMENT_LIST_AUGMENT_ID.child(FromAugmentEntry.class, new FromAugmentEntryKey("2")); + + verify(fromAugmentListWriter) + .update(eq(keyedNestedList1), eq(null), eq(entries.get(0)), any(WriteContext.class)); + verify(fromAugmentListWriter) + .update(eq(keyedNestedList2), eq(null), eq(entries.get(1)), any(WriteContext.class)); + } + + private AugTarget augTarget(FromAugment fromAugment) { + return new AugTargetBuilder() + .setSomeLeaf("aug-target-leaf-val") + .addAugmentation(FromAugmentAugment.class, + new FromAugmentAugmentBuilder().setFromAugment(fromAugment).build()) + .build(); + } + + private FromAugment fromAugment() { + return new FromAugmentBuilder() + .setSomeLeaf("from-augment-leaf-val") + .addAugmentation(FromAugment2Augment.class, new FromAugment2AugmentBuilder() + .setFromAugment2(fromAugment2()).build()) + .build(); + } + + private FromAugment fromAugmentSimple(SimpleNestedAugment simpleNestedAugment) { + return new FromAugmentBuilder() + .setSomeLeaf("from-augment-leaf-val") + .addAugmentation(SimpleNestedAugment.class, simpleNestedAugment) + .build(); + } + + private SimpleNestedAugment simpleNestedAugment() { + return new SimpleNestedAugmentBuilder() + .setSimpleNestedAugmentLeaf("simple-nested-augment-leaf-val").build(); + } + + private FromAugment fromAugment(final Class> augmentationClass, + final Augmentation augmentation) { + return new FromAugmentBuilder() + .setSomeLeaf("from-augment-leaf-val") + .addAugmentation(augmentationClass, augmentation) + .build(); + } + + private FromAugment2Augment fromAugment2Augment(FromAugment2 fromAugment2) { + return new FromAugment2AugmentBuilder().setFromAugment2(fromAugment2).build(); + } + + private FromAugment2 fromAugment2() { + return new FromAugment2Builder() + .setNewLeaf("new-leaf-val") + .build(); + } + + private FromAugmentListAugment fromAugmentList(final List entries) { + return new FromAugmentListAugmentBuilder() + .setFromAugmentEntry(entries) + .build(); + } +} -- cgit 1.2.3-korg