summaryrefslogtreecommitdiffstats
path: root/v3po/it/it-test
diff options
context:
space:
mode:
authorMaros Marsalek <mmarsale@cisco.com>2016-07-14 10:41:49 +0200
committerMaros Marsalek <mmarsale@cisco.com>2016-07-25 10:34:16 +0200
commit4778a809ba1321629c3a3d70dbdddb0beb189341 (patch)
treefee1be0494c263be86475594f3baf8882573fdf9 /v3po/it/it-test
parentd4b205bc665bebffec8545af5c4992327149c9c3 (diff)
HONEYCOMB-122: Reader registry integration tests
Add IT test for read infrastructure + some additional unit tests + Make Read/Write Factory autoCloseable Change-Id: I6eab8e6df2c2132af01cea0a9c4b9bece7dc9b74 Signed-off-by: Maros Marsalek <mmarsale@cisco.com>
Diffstat (limited to 'v3po/it/it-test')
-rw-r--r--v3po/it/it-test/pom.xml5
-rw-r--r--v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/AbstractInfraTest.java106
-rw-r--r--v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombReadInfraTest.java460
-rw-r--r--v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombSubtreeReadInfraTest.java150
-rw-r--r--v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java176
-rw-r--r--v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/Ids.java62
6 files changed, 838 insertions, 121 deletions
diff --git a/v3po/it/it-test/pom.xml b/v3po/it/it-test/pom.xml
index 04e70e948..74bb545a6 100644
--- a/v3po/it/it-test/pom.xml
+++ b/v3po/it/it-test/pom.xml
@@ -35,6 +35,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>io.fd.honeycomb.v3po</groupId>
+ <artifactId>translate-impl</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
<groupId>org.skinny-framework</groupId>
<artifactId>skinny-logback</artifactId>
<version>1.0.8</version>
diff --git a/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/AbstractInfraTest.java b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/AbstractInfraTest.java
new file mode 100644
index 000000000..47644cc70
--- /dev/null
+++ b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/AbstractInfraTest.java
@@ -0,0 +1,106 @@
+/*
+ * 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.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.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;
+import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
+import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
+import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
+import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+/**
+ * Base IT test infrastructure.
+ */
+abstract class AbstractInfraTest {
+
+ protected BindingNormalizedNodeSerializer serializer;
+ protected SchemaContext schemaContext;
+
+ @Mock
+ protected org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker;
+ @Mock
+ private org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction ctxTx;
+
+ static BindingToNormalizedNodeCodec getSerializer(final ModuleInfoBackedContext moduleInfoBackedContext,
+ final SchemaContext schemaContext) {
+ final DataObjectSerializerGenerator serializerGenerator = new StreamWriterGenerator(JavassistUtils.forClassPool(
+ ClassPool.getDefault()));
+ final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(serializerGenerator);
+ final BindingRuntimeContext ctx =
+ BindingRuntimeContext.create(moduleInfoBackedContext, schemaContext);
+ codecRegistry.onBindingRuntimeContextUpdated(ctx);
+ return new BindingToNormalizedNodeCodec(moduleInfoBackedContext, codecRegistry);
+ }
+
+ static ModuleInfoBackedContext getSchemaContext() {
+ final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
+ moduleInfoBackedContext.addModuleInfos(Collections.singleton($YangModuleInfoImpl.getInstance()));
+ return moduleInfoBackedContext;
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ when(contextBroker.newReadWriteTransaction()).thenReturn(ctxTx);
+ when(ctxTx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
+
+ initSerializer();
+ postSetup();
+ }
+
+ abstract void postSetup();
+
+ private void initSerializer() {
+ final ModuleInfoBackedContext moduleInfoBackedContext = getSchemaContext();
+ schemaContext = moduleInfoBackedContext.tryToCreateSchemaContext().get();
+ serializer = getSerializer(moduleInfoBackedContext, schemaContext);
+ }
+
+ protected Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> toBinding(
+ final NormalizedNode<?, ?> read) {
+ Multimap<InstanceIdentifier<? extends DataObject>, DataObject> baNodes = HashMultimap.create();
+
+ for (DataContainerChild<?, ?> o : ((DataContainerNode<?>) read).getValue()) {
+ final YangInstanceIdentifier yid = YangInstanceIdentifier.of(o.getNodeType());
+ final Map.Entry<InstanceIdentifier<?>, DataObject> baEntry = serializer.fromNormalizedNode(yid, o);
+ baNodes.put(baEntry.getKey(), baEntry.getValue());
+ }
+ return baNodes;
+ }
+}
diff --git a/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombReadInfraTest.java b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombReadInfraTest.java
new file mode 100644
index 000000000..b1f3a196a
--- /dev/null
+++ b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombReadInfraTest.java
@@ -0,0 +1,460 @@
+/*
+ * 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.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.util.concurrent.CheckedFuture;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericListReader;
+import io.fd.honeycomb.v3po.translate.read.ListReader;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
+import io.fd.honeycomb.v3po.translate.util.RWUtils;
+import io.fd.honeycomb.v3po.translate.util.read.ReflexiveListReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.util.read.ReflexiveReader;
+import io.fd.honeycomb.v3po.translate.util.read.registry.CompositeReaderRegistryBuilder;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.Mock;
+import org.mockito.exceptions.misusing.MockitoConfigurationException;
+import org.mockito.invocation.InvocationOnMock;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ComplexAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ComplexAugmentBuilder;
+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.ContainerWithListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleAugmentBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleContainerBuilder;
+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.ListInContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainerKey;
+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.ContainerInListBuilder;
+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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.container.in.list.NestedListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.list.in.container.container.in.list.NestedListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.simple.container.ComplexAugmentContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.simple.container.ComplexAugmentContainerBuilder;
+import org.opendaylight.yangtools.concepts.Builder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.Identifiable;
+import org.opendaylight.yangtools.yang.binding.Identifier;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class HoneycombReadInfraTest extends AbstractInfraTest {
+
+ @Mock
+ private ReadContext ctx;
+ private ReaderRegistry registry;
+
+ // 1
+ private Reader<SimpleContainer, SimpleContainerBuilder> simpleContainerReader =
+ mockReader(Ids.SIMPLE_CONTAINER_ID, this::readSimpleContainer, SimpleContainerBuilder.class);
+ // 1.1
+ private Reader<SimpleAugment, SimpleAugmentBuilder> simpleAugmentReader =
+ mockReader(Ids.SIMPLE_AUGMENT_ID, this::readSimpleAugment, SimpleAugmentBuilder.class);
+ // 1.2
+ // Noop reader(no real attributes)
+ private Reader<ComplexAugment, ComplexAugmentBuilder> complexAugmentReader =
+ mockReader(Ids.COMPLEX_AUGMENT_ID, HoneycombReadInfraTest::noopRead, ComplexAugmentBuilder.class);
+ // 1.2.1
+ private Reader<ComplexAugmentContainer, ComplexAugmentContainerBuilder> complexAugmentContainerReader =
+ mockReader(Ids.COMPLEX_AUGMENT_CONTAINER_ID, this::readComplexAugmentContainer, ComplexAugmentContainerBuilder.class);
+ // 2
+ // Noop reader(no real attributes)
+ private Reader<ContainerWithList, ContainerWithListBuilder> containerWithListReader =
+ mockReader(Ids.CONTAINER_WITH_LIST_ID, HoneycombReadInfraTest::noopRead, ContainerWithListBuilder.class);
+ // 2.1
+ private ListReader<ListInContainer, ListInContainerKey, ListInContainerBuilder> listInContainerReader =
+ mockListReader(Ids.LIST_IN_CONTAINER_ID, this::readListInContainer, this::getListInContainerIds,
+ ListInContainerBuilder.class);
+ // 2.1.1
+ private Reader<ContainerInList, ContainerInListBuilder> containerInListReader =
+ mockReader(Ids.CONTAINER_IN_LIST_ID, this::readContainerInList, ContainerInListBuilder.class);
+ // 2.1.1.1
+ private ListReader<NestedList, NestedListKey, NestedListBuilder> nestedListReader =
+ mockListReader(Ids.NESTED_LIST_ID, this::readNestedList, this::getNestedListIds,
+ NestedListBuilder.class);
+
+ @Override
+ void postSetup() {
+ initReaderRegistry();
+ }
+
+ private void initReaderRegistry() {
+ registry = new CompositeReaderRegistryBuilder()
+ .add(containerWithListReader) // 2
+ .addBefore(simpleContainerReader, Ids.CONTAINER_WITH_LIST_ID) // 1
+ .add(simpleAugmentReader) // 1.1
+ .addAfter(complexAugmentReader, Ids.SIMPLE_AUGMENT_ID) // 1.2
+ .add(complexAugmentContainerReader) // 1.2.1
+ .add(listInContainerReader) // 2.1
+ .add(containerInListReader) // 2.1.1
+ .addBefore(nestedListReader, Ids.SIMPLE_AUGMENT_ID) // 2.1.1.1 - Before relationship should be ignored
+ .build();
+ }
+
+ private Reader<?, ?>[] getOrderedReaders() {
+ return new Reader<?, ?>[]{simpleContainerReader, // 1
+ simpleAugmentReader, // 1.1
+ complexAugmentReader, // 1.2
+ complexAugmentContainerReader, // 1.2.1
+ containerWithListReader, // 2
+ listInContainerReader, // 2.1
+ containerInListReader, // 2.1.1
+ nestedListReader}; // 2.1.1.1
+ }
+
+ @Test
+ public void testReadAll() throws Exception {
+ final ReadableDataTreeDelegator readableDataTreeDelegator =
+ new ReadableDataTreeDelegator(serializer, schemaContext, registry, contextBroker);
+ final CheckedFuture<Optional<NormalizedNode<?, ?>>, org.opendaylight.controller.md.sal.common.api.data.ReadFailedException>
+ read = readableDataTreeDelegator.read(YangInstanceIdentifier.EMPTY);
+
+ final Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> readAll =
+ toBinding(read.checkedGet().get());
+ assertThat(readAll.size(), is(2));
+ assertTrue(readAll.containsKey(Ids.CONTAINER_WITH_LIST_ID));
+ assertEquals(readContainerWithList(), readAll.get(Ids.CONTAINER_WITH_LIST_ID).stream().findFirst().get());
+ assertTrue(readAll.containsKey(Ids.SIMPLE_CONTAINER_ID));
+ assertEquals(readSimpleContainer(), readAll.get(Ids.SIMPLE_CONTAINER_ID).stream().findFirst().get());
+
+ final Reader<?, ?>[] ordered = getOrderedReaders();
+ final InOrder inOrder = inOrder(ordered);
+
+ final List<ListInContainerKey> listInContainerKeys = getListInContainerIds(Ids.LIST_IN_CONTAINER_ID, ctx);
+
+ verifyRootReader(inOrder, simpleContainerReader, Ids.SIMPLE_CONTAINER_ID, SimpleContainerBuilder.class);
+ verifyLeafChildReader(inOrder, simpleAugmentReader, Ids.SIMPLE_AUGMENT_ID);
+ verifyCompositeChildReader(inOrder, complexAugmentReader, ComplexAugmentBuilder.class, Ids.COMPLEX_AUGMENT_ID);
+ verifyLeafChildReader(inOrder, complexAugmentContainerReader, Ids.COMPLEX_AUGMENT_CONTAINER_ID);
+ verifyRootReader(inOrder, containerWithListReader, Ids.CONTAINER_WITH_LIST_ID, ContainerWithListBuilder.class);
+ verifyCompositeListReader(inOrder, listInContainerReader, Ids.LIST_IN_CONTAINER_ID,
+ listInContainerKeys, ListInContainerBuilder.class);
+
+ for (ListInContainerKey k : listInContainerKeys) {
+ final InstanceIdentifier<ContainerInList> id =
+ Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, k).child(ContainerInList.class);
+ verifyCompositeChildReader(inOrder, containerInListReader, ContainerInListBuilder.class, id);
+ final InstanceIdentifier<NestedList> nestedId = id.child(NestedList.class);
+ verifyLeafListReader(inOrder, nestedListReader, nestedId);
+ }
+
+ for (Reader<?, ?> reader : ordered) {
+ verifyNoMoreReadInteractions(reader);
+ }
+ }
+
+ private <D extends DataObject, B extends Builder<D>> void verifyNoMoreReadInteractions(final Reader<D, B> reader) {
+ verify(reader, atLeastOnce()).getManagedDataObjectType();
+ verifyNoMoreInteractions(reader);
+ }
+
+ private <D extends DataObject, B extends Builder<D>> void verifyCompositeChildReader(final InOrder inOrder,
+ final Reader<D, B> reader,
+ final Class<B> builderCls,
+ final InstanceIdentifier<D> id)
+ throws ReadFailedException {
+ verifyRootReader(inOrder, reader, id, builderCls);
+ verify(reader, atLeastOnce()).merge(any(Builder.class), any(id.getTargetType()));
+ }
+
+ private <D extends DataObject & Identifiable<K>, K extends Identifier<D>, B extends Builder<D>> void verifyCompositeListReader(
+ final InOrder inOrder,
+ final ListReader<D, K, B> reader,
+ final InstanceIdentifier<D> id,
+ final List<K> keys,
+ final Class<B> builderCls)
+ throws ReadFailedException {
+
+ // Id has to be wildcarded, since it was created using InstanceIdentifier.child() method
+ inOrder.verify(reader).getAllIds(eq(RWUtils.makeIidLastWildcarded(id)), any(ReadContext.class));
+ keys.stream()
+ .map(k -> RWUtils.replaceLastInId(id, RWUtils.getCurrentIdItem(id, k)))
+ .forEach(keyedId -> {
+ try {
+ verify(reader).getBuilder(keyedId);
+ verify(reader).readCurrentAttributes(eq(keyedId), any(builderCls), any(ReadContext.class));
+ } catch (ReadFailedException e) { throw new RuntimeException(e); }
+ });
+ verify(reader, atLeastOnce()).merge(any(Builder.class), anyListOf(id.getTargetType()));
+ }
+
+ private <D extends DataObject & Identifiable<K>, K extends Identifier<D>, B extends Builder<D>> void verifyLeafListReader(
+ final InOrder inOrder,
+ final ListReader<D, K, B> reader,
+ final InstanceIdentifier<D> id)
+ throws ReadFailedException {
+
+ // Id has to be wildcarded, since it was created using InstanceIdentifier.child() method
+ inOrder.verify(reader).readList(eq(RWUtils.makeIidLastWildcarded(id)), any(ReadContext.class));
+ verify(reader, atLeastOnce()).merge(any(Builder.class), anyListOf(id.getTargetType()));
+ }
+
+ private <D extends DataObject, B extends Builder<D>> void verifyRootReader(final InOrder inOrder,
+ final Reader<D, B> reader,
+ final InstanceIdentifier<D> id,
+ final Class<B> builderCls)
+ throws ReadFailedException {
+ inOrder.verify(reader).readCurrentAttributes(eq(id), any(builderCls), any(ReadContext.class));
+ verify(reader).getBuilder(id);
+ }
+
+
+ private <D extends DataObject, B extends Builder<D>> void verifyLeafChildReader(final InOrder inOrder,
+ final Reader<D, B> reader,
+ final InstanceIdentifier<D>... id)
+ throws ReadFailedException {
+ for (InstanceIdentifier<D> singleId : id) {
+ inOrder.verify(reader).read(eq(singleId), any(ReadContext.class));
+ verify(reader, atLeastOnce()).merge(any(Builder.class), any(singleId.getTargetType()));
+ }
+ }
+
+ static <D extends DataObject, B extends Builder<D>> Reader<D, B> mockReader(InstanceIdentifier<D> id,
+ CurrentAttributesReader<D, B> currentAttributesReader,
+ Class<B> builderClass) {
+ final ReflexiveReader<D, B> reflex = new ReflexiveReader<D, B>(id, builderClass) {
+
+ @Override
+ public void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
+ @Nonnull final B builder,
+ @Nonnull final ReadContext ctx)
+ throws ReadFailedException {
+ currentAttributesReader.readCurrentAttributes(id, builder, ctx);
+ }
+ };
+
+ // Simple spy on top of this reflexive reader cannot be used, spy also checks protected methods for invocation
+ // but those cannot be verified by mockito
+ final Reader<D, B> mock = mock(Reader.class);
+ try {
+ doAnswer(i -> reflexiveAnswer(reflex, i)).when(mock).read(any(InstanceIdentifier.class), any(ReadContext.class));
+ doAnswer(i -> reflexiveAnswer(reflex, i)).when(mock)
+ .readCurrentAttributes(any(InstanceIdentifier.class), any(builderClass), any(ReadContext.class));
+ doAnswer(i -> reflexiveAnswer(reflex, i)).when(mock).merge(any(Builder.class), any(id.getTargetType()));
+ doReturn(id).when(mock).getManagedDataObjectType();
+ doReturn(builderClass.newInstance()).when(mock).getBuilder(any(InstanceIdentifier.class));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return mock;
+ }
+
+ static <D extends DataObject & Identifiable<K>, K extends Identifier<D>, B extends Builder<D>> ListReader<D, K, B> mockListReader(
+ InstanceIdentifier<D> id,
+ CurrentAttributesReader<D, B> currentAttributesReader,
+ ListKeysReader<D, K> listKeysReader,
+ Class<B> builderClass) {
+
+ ListReader<D, K, B> reflex = new GenericListReader<>(id,
+ new ReflexiveListReaderCustomizer<D, K, B>(id.getTargetType(), builderClass) {
+
+ @Nonnull
+ @Override
+ public List<K> getAllIds(@Nonnull final InstanceIdentifier<D> id, @Nonnull final ReadContext context)
+ throws ReadFailedException {
+ return listKeysReader.getAllIds(id, context);
+ }
+
+ @Override
+ public void readCurrentAttributes(final InstanceIdentifier<D> id, final B builder,
+ final ReadContext context)
+ throws ReadFailedException {
+ currentAttributesReader.readCurrentAttributes(id, builder, context);
+ }
+ });
+
+ final ListReader<D, K, B> mock = mock(ListReader.class /*, withSettings().verboseLogging()*/);
+ try {
+ // not using eq(id) instead using any(InstanceIdentifier.class) due to InstanceIdentifier.equals weird behavior
+ // with wildcarded instance identifiers for lists
+ doAnswer(i -> reflexiveAnswer(reflex, i)).when(mock).read(any(InstanceIdentifier.class), any(ReadContext.class));
+ doAnswer(i -> reflexiveAnswer(reflex, i)).when(mock)
+ .readCurrentAttributes(any(InstanceIdentifier.class), any(builderClass), any(ReadContext.class));
+ doAnswer(i -> reflexiveAnswer(reflex, i)).when(mock).merge(any(Builder.class), any(id.getTargetType()));
+ doAnswer(i -> reflexiveAnswer(reflex, i)).when(mock).merge(any(Builder.class), anyListOf(id.getTargetType()));
+ doAnswer(i -> reflexiveAnswer(reflex, i)).when(mock).getAllIds(any(InstanceIdentifier.class), any(ReadContext.class));
+ doAnswer(i -> reflexiveAnswer(reflex, i)).when(mock).readList(any(InstanceIdentifier.class), any(ReadContext.class));
+ doReturn(id).when(mock).getManagedDataObjectType();
+ doReturn(builderClass.newInstance()).when(mock).getBuilder(any(InstanceIdentifier.class));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ return mock;
+ }
+
+ private static <D extends DataObject, B extends Builder<D>> Object reflexiveAnswer(final Reader<D, B> instance,
+ final InvocationOnMock i) {
+ try {
+ return i.getMethod().invoke(instance, i.getArguments());
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new MockitoConfigurationException("Unable to invoke stubbed method invocation: " + i + " on " + instance);
+ }
+ }
+
+ @FunctionalInterface
+ interface CurrentAttributesReader<D extends DataObject, B extends Builder<D>> {
+ void readCurrentAttributes(@Nonnull final InstanceIdentifier<D> id,
+ @Nonnull final B builder,
+ @Nonnull final ReadContext ctx);
+ }
+
+ @FunctionalInterface
+ interface ListKeysReader<D extends DataObject & Identifiable<K>, K extends Identifier<D>> {
+ List<K> getAllIds(@Nonnull final InstanceIdentifier<D> id,
+ @Nonnull final ReadContext ctx);
+ }
+
+
+ private void readSimpleContainer(final InstanceIdentifier<SimpleContainer> id,
+ final SimpleContainerBuilder b,
+ final ReadContext readContext) {
+ b.setSimpleContainerName("simple");
+ }
+
+ private SimpleContainer readSimpleContainer() {
+ final SimpleContainerBuilder b = new SimpleContainerBuilder();
+ readSimpleContainer(Ids.SIMPLE_CONTAINER_ID, b, ctx);
+ b.addAugmentation(SimpleAugment.class, readSimpleAugment());
+ b.addAugmentation(ComplexAugment.class,
+ new ComplexAugmentBuilder().setComplexAugmentContainer(readComplexAugmentContainer()).build());
+ return b.build();
+ }
+
+ private void readSimpleAugment(final InstanceIdentifier<SimpleAugment> id,
+ final SimpleAugmentBuilder b,
+ final ReadContext readContext) {
+ b.setSimpleAugmentLeaf("simple augment");
+ }
+
+ private SimpleAugment readSimpleAugment() {
+ final SimpleAugmentBuilder b = new SimpleAugmentBuilder();
+ readSimpleAugment(Ids.SIMPLE_AUGMENT_ID, b, ctx);
+ return b.build();
+ }
+
+ private void readComplexAugmentContainer(final InstanceIdentifier<ComplexAugmentContainer> id,
+ final ComplexAugmentContainerBuilder b,
+ final ReadContext readContext) {
+ b.setSomeLeaf("nested container in augment");
+ }
+
+ private ComplexAugmentContainer readComplexAugmentContainer() {
+ final ComplexAugmentContainerBuilder b = new ComplexAugmentContainerBuilder();
+ readComplexAugmentContainer(Ids.COMPLEX_AUGMENT_CONTAINER_ID, b, ctx);
+ return b.build();
+ }
+
+ private ContainerWithList readContainerWithList() {
+ final ContainerWithListBuilder b = new ContainerWithListBuilder();
+ b.setListInContainer(readListInContainer());
+ return b.build();
+ }
+
+ private List<ListInContainerKey> getListInContainerIds(final InstanceIdentifier<ListInContainer> id,
+ final ReadContext readContext) {
+ return Lists.newArrayList(1L, 2L)
+ .stream()
+ .map(ListInContainerKey::new)
+ .collect(Collectors.toList());
+ }
+
+ private List<NestedListKey> getNestedListIds(final InstanceIdentifier<NestedList> id,
+ final ReadContext readContext) {
+ return Lists.newArrayList("one", "two")
+ .stream()
+ .map(NestedListKey::new)
+ .collect(Collectors.toList());
+ }
+
+ private void readListInContainer(final InstanceIdentifier<ListInContainer> id,
+ final ListInContainerBuilder b,
+ final ReadContext readContext) {
+ final ListInContainerKey key = id.firstKeyOf(ListInContainer.class);
+ b.setId(key.getId());
+ final ContainerInListBuilder cilBuilder = new ContainerInListBuilder();
+ readContainerInList(id.child(ContainerInList.class), cilBuilder, readContext);
+ b.setContainerInList(cilBuilder.build());
+ }
+
+ private void readNestedList(final InstanceIdentifier<NestedList> id,
+ final NestedListBuilder b,
+ final ReadContext readContext) {
+ final NestedListKey key = id.firstKeyOf(NestedList.class);
+ b.setNestedId(key.getNestedId());
+ b.setNestedName(key.getNestedId() + "name");
+ }
+
+ private void readContainerInList(final InstanceIdentifier<ContainerInList> id,
+ final ContainerInListBuilder b,
+ final ReadContext readContext) {
+ b.setName(id.firstKeyOf(ListInContainer.class).getId().toString());
+ b.setNestedList(getNestedListIds(Ids.NESTED_LIST_ID, ctx).stream()
+ .map(key -> id.child(NestedList.class, key))
+ .map(nestedId -> {
+ final NestedListBuilder nestedB = new NestedListBuilder();
+ readNestedList(nestedId, nestedB, readContext);
+ return nestedB.build();
+ })
+ .collect(Collectors.toList()));
+ }
+
+ private List<ListInContainer> readListInContainer() {
+ return getListInContainerIds(Ids.LIST_IN_CONTAINER_ID, ctx).stream()
+ .map(key -> Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, key))
+ .map(id -> {
+ final ListInContainerBuilder b = new ListInContainerBuilder();
+ readListInContainer(id, b, ctx);
+ return b.build();
+ }).collect(Collectors.toList());
+ }
+
+ static <D extends DataObject, B extends Builder<D>> void noopRead(final InstanceIdentifier<D> id, final B b,
+ final ReadContext readContext) {
+ // NOOP
+ }
+
+}
diff --git a/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombSubtreeReadInfraTest.java b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombSubtreeReadInfraTest.java
new file mode 100644
index 000000000..8faeb84b6
--- /dev/null
+++ b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombSubtreeReadInfraTest.java
@@ -0,0 +1,150 @@
+/*
+ * 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.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.Sets;
+import com.google.common.util.concurrent.CheckedFuture;
+import io.fd.honeycomb.v3po.translate.impl.read.GenericListReader;
+import io.fd.honeycomb.v3po.translate.read.ListReader;
+import io.fd.honeycomb.v3po.translate.read.ReadContext;
+import io.fd.honeycomb.v3po.translate.read.ReadFailedException;
+import io.fd.honeycomb.v3po.translate.read.Reader;
+import io.fd.honeycomb.v3po.translate.read.registry.ReaderRegistry;
+import io.fd.honeycomb.v3po.translate.util.read.ReflexiveListReaderCustomizer;
+import io.fd.honeycomb.v3po.translate.util.read.registry.CompositeReaderRegistryBuilder;
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
+import org.junit.Test;
+import org.mockito.Mock;
+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.ContainerWithListBuilder;
+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.ListInContainerBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.container.with.list.ListInContainerKey;
+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.ContainerInListBuilder;
+import org.opendaylight.yangtools.yang.binding.DataObject;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class HoneycombSubtreeReadInfraTest extends AbstractInfraTest {
+
+ @Mock
+ private ReadContext ctx;
+ private ReaderRegistry registry;
+
+ private Reader<ContainerWithList, ContainerWithListBuilder> containerWithListReader =
+ HoneycombReadInfraTest.mockReader(Ids.CONTAINER_WITH_LIST_ID, this::readSubtree, ContainerWithListBuilder.class);
+
+ private ListReader<ListInContainer, ListInContainerKey, ListInContainerBuilder> listInContainerReader =
+ new GenericListReader<>(Ids.LIST_IN_CONTAINER_ID,
+ new ReflexiveListReaderCustomizer<ListInContainer, ListInContainerKey, ListInContainerBuilder>(Ids.LIST_IN_CONTAINER_ID.getTargetType(), ListInContainerBuilder.class) {
+
+ @Nonnull
+ @Override
+ public List<ListInContainerKey> getAllIds(@Nonnull final InstanceIdentifier<ListInContainer> id,
+ @Nonnull final ReadContext context)
+ throws ReadFailedException {
+ // FIXME this is the only way of extending subtree reader via its list child
+ // Reflexive list reader has to be used in place of the list(managed by subtree reader perent)
+ // to enable further children readers. However, it will not work out of the box, because
+ // reflexive list reader has no way to tell what are the IDs to correctly invoke its children.
+ // Only way is to override the getAllIds method in reflexive reader and return the same list
+ // as parent used (this can be done using cache or repeated dump call)
+ return Lists.newArrayList(new ListInContainerKey(1L), new ListInContainerKey(2L));
+ }
+
+ @Override
+ public void readCurrentAttributes(final InstanceIdentifier<ListInContainer> id,
+ final ListInContainerBuilder builder,
+ final ReadContext context) throws ReadFailedException {
+ super.readCurrentAttributes(id, builder, context);
+ builder.setKey(id.firstKeyOf(ListInContainer.class));
+ }
+ });
+
+ private Reader<ContainerInList, ContainerInListBuilder> containerInListReader =
+ HoneycombReadInfraTest.mockReader(Ids.CONTAINER_IN_LIST_ID, this::readContainerInList, ContainerInListBuilder.class);
+
+ // TODO Test subtree readers especially composite structure where readers are under subtree reader
+
+ @Override
+ void postSetup() {
+ initReaderRegistry();
+ }
+
+ private void initReaderRegistry() {
+ registry = new CompositeReaderRegistryBuilder()
+ // Subtree reader handling its child list
+ .subtreeAdd(Sets.newHashSet(Ids.LIST_IN_CONTAINER_ID), containerWithListReader)
+ // Reflexive
+ .add(listInContainerReader)
+ .add(containerInListReader)
+ .build();
+ }
+
+ @Test
+ public void testReadAll() throws Exception {
+ final ReadableDataTreeDelegator readableDataTreeDelegator =
+ new ReadableDataTreeDelegator(serializer, schemaContext, registry, contextBroker);
+ final CheckedFuture<Optional<NormalizedNode<?, ?>>, org.opendaylight.controller.md.sal.common.api.data.ReadFailedException>
+ read = readableDataTreeDelegator.read(YangInstanceIdentifier.EMPTY);
+
+ final Multimap<InstanceIdentifier<? extends DataObject>, ? extends DataObject> readAll =
+ toBinding(read.checkedGet().get());
+ assertThat(readAll.size(), is(1));
+ assertEquals(readEntireSubtree(), readAll.get(Ids.CONTAINER_WITH_LIST_ID).stream().findFirst().get());
+ }
+
+ private void readSubtree(final InstanceIdentifier<ContainerWithList> id,
+ final ContainerWithListBuilder b,
+ final ReadContext readContext) {
+ b.setListInContainer(Lists.newArrayList(1L, 2L).stream()
+ .map(l -> new ListInContainerBuilder().setId(l).build())
+ .collect(Collectors.toList()));
+ }
+
+ private ContainerWithList readEntireSubtree() {
+ final ContainerWithListBuilder b = new ContainerWithListBuilder();
+ b.setListInContainer(Lists.newArrayList(1L, 2L).stream()
+ .map(l -> {
+ final ContainerInListBuilder containerInListBuilder = new ContainerInListBuilder();
+ readContainerInList(
+ Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey(l)).child(ContainerInList.class),
+ containerInListBuilder,
+ ctx);
+ return new ListInContainerBuilder().setId(l).setContainerInList(containerInListBuilder.build()).build();
+ })
+ .collect(Collectors.toList()));
+ return b.build();
+ }
+
+ private void readContainerInList(final InstanceIdentifier<ContainerInList> id,
+ final ContainerInListBuilder b,
+ final ReadContext readContext) {
+ b.setName(id.firstKeyOf(ListInContainer.class).getId().toString());
+ }
+}
diff --git a/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java
index 51fc22744..b3a06ec46 100644
--- a/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java
+++ b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/HoneycombWriteInfraTest.java
@@ -28,7 +28,6 @@ import static org.mockito.Mockito.when;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
-import com.google.common.util.concurrent.Futures;
import io.fd.honeycomb.v3po.data.DataModification;
import io.fd.honeycomb.v3po.translate.util.write.registry.FlatWriterRegistryBuilder;
import io.fd.honeycomb.v3po.translate.write.WriteContext;
@@ -39,14 +38,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import javassist.ClassPool;
-import org.junit.Before;
import org.junit.Test;
import org.mockito.InOrder;
-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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ComplexAugment;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ComplexAugmentBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ContainerWithChoice;
@@ -72,13 +65,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.simple.container.ComplexAugmentContainerBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.some.attributes.ContainerFromGrouping;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.some.attributes.ContainerFromGroupingBuilder;
-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;
-import org.opendaylight.yangtools.binding.data.codec.impl.BindingNormalizedNodeCodecRegistry;
-import org.opendaylight.yangtools.sal.binding.generator.impl.ModuleInfoBackedContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.BindingRuntimeContext;
-import org.opendaylight.yangtools.sal.binding.generator.util.JavassistUtils;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
@@ -87,61 +73,28 @@ 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;
-import org.opendaylight.yangtools.yang.model.api.SchemaContext;
/**
- * Testing honeycomb writes from data tree up to mocked writers
+ * Testing honeycomb writes from data tree up to mocked writers.
*/
-public class HoneycombWriteInfraTest {
+public class HoneycombWriteInfraTest extends AbstractInfraTest {
private TipProducingDataTree dataTree;
- private BindingNormalizedNodeSerializer serializer;
private WriterRegistry writerRegistry;
- private SchemaContext schemaContext;
-
- @Mock
- private org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction ctxTx;
- @Mock
- private org.opendaylight.controller.md.sal.binding.api.DataBroker contextBroker;
-
- // Simple container
- // ORDER = 3
- static final InstanceIdentifier<SimpleContainer> SIMPLE_CONTAINER_ID = InstanceIdentifier.create(SimpleContainer.class);
- Writer<SimpleContainer> simpleContainerWriter = mockWriter(SIMPLE_CONTAINER_ID);
- // UNORDERED
- static final InstanceIdentifier<ComplexAugment> COMPLEX_AUGMENT_ID = SIMPLE_CONTAINER_ID.augmentation(ComplexAugment.class);
- Writer<ComplexAugment> complexAugmentWriter = mockWriter(COMPLEX_AUGMENT_ID);
- // 1
- static final InstanceIdentifier<ComplexAugmentContainer> COMPLEX_AUGMENT_CONTAINER_ID = COMPLEX_AUGMENT_ID.child(ComplexAugmentContainer.class);
- Writer<ComplexAugmentContainer> complexAugmentContainerWriter = mockWriter(COMPLEX_AUGMENT_CONTAINER_ID);
- // 2
- static final InstanceIdentifier<SimpleAugment> SIMPLE_AUGMENT_ID = SIMPLE_CONTAINER_ID.augmentation(SimpleAugment.class);
- Writer<SimpleAugment> simpleAugmentWriter = mockWriter(SIMPLE_AUGMENT_ID);
-
- // Container with list
- // 9
- static final InstanceIdentifier<ContainerWithList> CONTAINER_WITH_LIST_ID = InstanceIdentifier.create(ContainerWithList.class);
- Writer<ContainerWithList> containerWithListWriter = mockWriter(CONTAINER_WITH_LIST_ID);
- // 7
- static final InstanceIdentifier<ListInContainer> LIST_IN_CONTAINER_ID = CONTAINER_WITH_LIST_ID.child(ListInContainer.class);
- Writer<ListInContainer> listInContainerWriter = mockWriter(LIST_IN_CONTAINER_ID);
- // 8
- static final InstanceIdentifier<ContainerInList> CONTAINER_IN_LIST_ID = LIST_IN_CONTAINER_ID.child(ContainerInList.class);
- Writer<ContainerInList> containerInListWriter = mockWriter(CONTAINER_IN_LIST_ID);
- // 6
- static final InstanceIdentifier<NestedList> NESTED_LIST_ID = CONTAINER_IN_LIST_ID.child(NestedList.class);
- Writer<NestedList> nestedListWriter = mockWriter(NESTED_LIST_ID);
-
- // Container with choice
- // 4
- static final InstanceIdentifier<ContainerWithChoice> CONTAINER_WITH_CHOICE_ID = InstanceIdentifier.create(ContainerWithChoice.class);
- Writer<ContainerWithChoice> containerWithChoiceWriter = mockWriter(CONTAINER_WITH_CHOICE_ID);
- // 5
- static final InstanceIdentifier<ContainerFromGrouping> CONTAINER_FROM_GROUPING_ID = CONTAINER_WITH_CHOICE_ID.child(ContainerFromGrouping.class);
- Writer<ContainerFromGrouping> containerFromGroupingWriter = mockWriter(CONTAINER_FROM_GROUPING_ID);
- // 2
- static final InstanceIdentifier<C3> C3_ID = CONTAINER_WITH_CHOICE_ID.child(C3.class);
- Writer<C3> c3Writer = mockWriter(C3_ID);
+
+ Writer<SimpleContainer> simpleContainerWriter = mockWriter(Ids.SIMPLE_CONTAINER_ID);
+ Writer<ComplexAugment> complexAugmentWriter = mockWriter(Ids.COMPLEX_AUGMENT_ID);
+ Writer<ComplexAugmentContainer> complexAugmentContainerWriter = mockWriter(Ids.COMPLEX_AUGMENT_CONTAINER_ID);
+ Writer<SimpleAugment> simpleAugmentWriter = mockWriter(Ids.SIMPLE_AUGMENT_ID);
+
+ Writer<ContainerWithList> containerWithListWriter = mockWriter(Ids.CONTAINER_WITH_LIST_ID);
+ Writer<ListInContainer> listInContainerWriter = mockWriter(Ids.LIST_IN_CONTAINER_ID);
+ Writer<ContainerInList> containerInListWriter = mockWriter(Ids.CONTAINER_IN_LIST_ID);
+ Writer<NestedList> nestedListWriter = mockWriter(Ids.NESTED_LIST_ID);
+
+ Writer<ContainerWithChoice> containerWithChoiceWriter = mockWriter(Ids.CONTAINER_WITH_CHOICE_ID);
+ Writer<ContainerFromGrouping> containerFromGroupingWriter = mockWriter(Ids.CONTAINER_FROM_GROUPING_ID);
+ Writer<C3> c3Writer = mockWriter(Ids.C3_ID);
private static <D extends DataObject> Writer<D> mockWriter(final InstanceIdentifier<D> id) {
@@ -150,13 +103,8 @@ public class HoneycombWriteInfraTest {
return mock;
}
- @Before
- public void setUp() throws Exception {
- MockitoAnnotations.initMocks(this);
- when(contextBroker.newReadWriteTransaction()).thenReturn(ctxTx);
- when(ctxTx.submit()).thenReturn(Futures.immediateCheckedFuture(null));
-
- initSerializer();
+ @Override
+ void postSetup() {
initDataTree();
initWriterRegistry();
}
@@ -166,33 +114,19 @@ public class HoneycombWriteInfraTest {
dataTree.setSchemaContext(schemaContext);
}
- private void initSerializer() {
- final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
- moduleInfoBackedContext.addModuleInfos(Collections.singleton($YangModuleInfoImpl.getInstance()));
- schemaContext = moduleInfoBackedContext.tryToCreateSchemaContext().get();
-
- final DataObjectSerializerGenerator serializerGenerator = new StreamWriterGenerator(JavassistUtils.forClassPool(
- ClassPool.getDefault()));
- final BindingNormalizedNodeCodecRegistry codecRegistry = new BindingNormalizedNodeCodecRegistry(serializerGenerator);
- serializer = new BindingToNormalizedNodeCodec(moduleInfoBackedContext, codecRegistry);
- final BindingRuntimeContext ctx =
- BindingRuntimeContext.create(moduleInfoBackedContext, schemaContext);
- codecRegistry.onBindingRuntimeContextUpdated(ctx);
- }
-
private void initWriterRegistry() {
writerRegistry = new FlatWriterRegistryBuilder()
.add(complexAugmentWriter) // unordered
.add(nestedListWriter) // 6
- .addAfter(listInContainerWriter, NESTED_LIST_ID) // 7
- .addAfter(containerInListWriter, LIST_IN_CONTAINER_ID) // 8
- .addAfter(containerWithListWriter, CONTAINER_IN_LIST_ID) // 9
- .addBefore(containerFromGroupingWriter, NESTED_LIST_ID) // 5
- .addBefore(containerWithChoiceWriter, CONTAINER_FROM_GROUPING_ID) // 4
- .addBefore(simpleContainerWriter, CONTAINER_WITH_CHOICE_ID) // 3
- .addBefore(c3Writer, SIMPLE_CONTAINER_ID) // 2
- .addBefore(simpleAugmentWriter, SIMPLE_CONTAINER_ID) // 2
- .addBefore(complexAugmentContainerWriter, Sets.newHashSet(C3_ID, SIMPLE_AUGMENT_ID)) // 1
+ .addAfter(listInContainerWriter, Ids.NESTED_LIST_ID) // 7
+ .addAfter(containerInListWriter, Ids.LIST_IN_CONTAINER_ID) // 8
+ .addAfter(containerWithListWriter, Ids.CONTAINER_IN_LIST_ID) // 9
+ .addBefore(containerFromGroupingWriter, Ids.NESTED_LIST_ID) // 5
+ .addBefore(containerWithChoiceWriter, Ids.CONTAINER_FROM_GROUPING_ID) // 4
+ .addBefore(simpleContainerWriter, Ids.CONTAINER_WITH_CHOICE_ID) // 3
+ .addBefore(c3Writer, Ids.SIMPLE_CONTAINER_ID) // 2
+ .addBefore(simpleAugmentWriter, Ids.SIMPLE_CONTAINER_ID) // 2
+ .addBefore(complexAugmentContainerWriter, Sets.newHashSet(Ids.C3_ID, Ids.SIMPLE_AUGMENT_ID)) // 1
.build();
}
@@ -206,7 +140,7 @@ public class HoneycombWriteInfraTest {
.build();
final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
- serializer.toNormalizedNode(SIMPLE_CONTAINER_ID, data);
+ serializer.toNormalizedNode(Ids.SIMPLE_CONTAINER_ID, data);
dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
dataModification.commit();
@@ -239,29 +173,29 @@ public class HoneycombWriteInfraTest {
// verify(complexAugmentWriter).update(eq(COMPLEX_AUGMENT_ID), eq(null), eq(getComplexAugment()), any(WriteContext.class));
// 1
inOrder.verify(complexAugmentContainerWriter)
- .update(eq(COMPLEX_AUGMENT_CONTAINER_ID), eq(null), eq(getComplexAugmentContainer()), any(WriteContext.class));
+ .update(eq(Ids.COMPLEX_AUGMENT_CONTAINER_ID), eq(null), eq(getComplexAugmentContainer()), any(WriteContext.class));
// 2
inOrder.verify(c3Writer)
- .update(eq(C3_ID), eq(null), eq(getC3()), any(WriteContext.class));
+ .update(eq(Ids.C3_ID), eq(null), eq(getC3()), any(WriteContext.class));
// 2
verify(simpleAugmentWriter)
- .update(eq(SIMPLE_AUGMENT_ID), eq(null), eq(getSimpleAugment()), any(WriteContext.class));
+ .update(eq(Ids.SIMPLE_AUGMENT_ID), eq(null), eq(getSimpleAugment()), any(WriteContext.class));
// 3
inOrder.verify(simpleContainerWriter)
- .update(eq(SIMPLE_CONTAINER_ID), eq(null), eq(getSimpleContainer()), any(WriteContext.class));
+ .update(eq(Ids.SIMPLE_CONTAINER_ID), eq(null), eq(getSimpleContainer()), any(WriteContext.class));
// 4
inOrder.verify(containerWithChoiceWriter)
- .update(eq(CONTAINER_WITH_CHOICE_ID), eq(null), eq(getContainerWithChoiceWithComplexCase()), any(WriteContext.class));
+ .update(eq(Ids.CONTAINER_WITH_CHOICE_ID), eq(null), eq(getContainerWithChoiceWithComplexCase()), any(WriteContext.class));
// 5
inOrder.verify(containerFromGroupingWriter)
- .update(eq(CONTAINER_FROM_GROUPING_ID), eq(null), eq(getContainerFromGrouping()), any(WriteContext.class));
+ .update(eq(Ids.CONTAINER_FROM_GROUPING_ID), eq(null), eq(getContainerFromGrouping()), any(WriteContext.class));
final KeyedInstanceIdentifier<ListInContainer, ListInContainerKey> keyedListInContainer1 =
- CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 1));
+ Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 1));
final KeyedInstanceIdentifier<NestedList, NestedListKey> keyedNestedList1 =
keyedListInContainer1.child(ContainerInList.class).child(NestedList.class, new NestedListKey("1"));
final KeyedInstanceIdentifier<ListInContainer, ListInContainerKey> keyedListInContainer2 =
- CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 2));
+ Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 2));
final KeyedInstanceIdentifier<NestedList, NestedListKey> keyedNestedList2 =
keyedListInContainer2.child(ContainerInList.class).child(NestedList.class, new NestedListKey("2"));
@@ -332,11 +266,11 @@ public class HoneycombWriteInfraTest {
final InOrder inOrder = inOrder(orderedWriters);
final KeyedInstanceIdentifier<ListInContainer, ListInContainerKey> keyedListInContainer1 =
- CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 1));
+ Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 1));
final KeyedInstanceIdentifier<NestedList, NestedListKey> keyedNestedList1 =
keyedListInContainer1.child(ContainerInList.class).child(NestedList.class, new NestedListKey("1"));
final KeyedInstanceIdentifier<ListInContainer, ListInContainerKey> keyedListInContainer2 =
- CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 2));
+ Ids.CONTAINER_WITH_LIST_ID.child(ListInContainer.class, new ListInContainerKey((long) 2));
final KeyedInstanceIdentifier<NestedList, NestedListKey> keyedNestedList2 =
keyedListInContainer2.child(ContainerInList.class).child(NestedList.class, new NestedListKey("2"));
@@ -360,22 +294,22 @@ public class HoneycombWriteInfraTest {
.update(eq(keyedNestedList2), eq(getSingleNestedList("2")), eq(null), any(WriteContext.class));
// 4
inOrder.verify(containerFromGroupingWriter)
- .update(eq(CONTAINER_FROM_GROUPING_ID), eq(getContainerFromGrouping()), eq(null), any(WriteContext.class));
+ .update(eq(Ids.CONTAINER_FROM_GROUPING_ID), eq(getContainerFromGrouping()), eq(null), any(WriteContext.class));
// 5
inOrder.verify(containerWithChoiceWriter)
- .update(eq(CONTAINER_WITH_CHOICE_ID), eq(getContainerWithChoiceWithComplexCase()), eq(null), any(WriteContext.class));
+ .update(eq(Ids.CONTAINER_WITH_CHOICE_ID), eq(getContainerWithChoiceWithComplexCase()), eq(null), any(WriteContext.class));
// 6
inOrder.verify(simpleContainerWriter)
- .update(eq(SIMPLE_CONTAINER_ID), eq(getSimpleContainer()), eq(null), any(WriteContext.class));
+ .update(eq(Ids.SIMPLE_CONTAINER_ID), eq(getSimpleContainer()), eq(null), any(WriteContext.class));
// 7
verify(simpleAugmentWriter)
- .update(eq(SIMPLE_AUGMENT_ID), eq(getSimpleAugment()), eq(null), any(WriteContext.class));
+ .update(eq(Ids.SIMPLE_AUGMENT_ID), eq(getSimpleAugment()), eq(null), any(WriteContext.class));
// 8
inOrder.verify(c3Writer)
- .update(eq(C3_ID), eq(getC3()), eq(null), any(WriteContext.class));
+ .update(eq(Ids.C3_ID), eq(getC3()), eq(null), any(WriteContext.class));
// 9
inOrder.verify(complexAugmentContainerWriter)
- .update(eq(COMPLEX_AUGMENT_CONTAINER_ID), eq(getComplexAugmentContainer()), eq(null), any(WriteContext.class));
+ .update(eq(Ids.COMPLEX_AUGMENT_CONTAINER_ID), eq(getComplexAugmentContainer()), eq(null), any(WriteContext.class));
for (Writer<?> orderedWriter : orderedWriters) {
verify(orderedWriter).getManagedDataObjectType();
@@ -385,12 +319,12 @@ public class HoneycombWriteInfraTest {
private void writeContainerWithList(final DataModification dataModification) {
final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
- serializer.toNormalizedNode(CONTAINER_WITH_LIST_ID, getContainerWithList());
+ serializer.toNormalizedNode(Ids.CONTAINER_WITH_LIST_ID, getContainerWithList());
dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
}
private void deleteContainerWithList(final DataModification dataModification) {
- dataModification.delete(serializer.toYangInstanceIdentifier(CONTAINER_WITH_LIST_ID));
+ dataModification.delete(serializer.toYangInstanceIdentifier(Ids.CONTAINER_WITH_LIST_ID));
}
private ContainerWithList getContainerWithList() {
@@ -442,13 +376,13 @@ public class HoneycombWriteInfraTest {
private void deleteContainerWithChoice(final DataModification dataModification) {
- dataModification.delete(serializer.toYangInstanceIdentifier(CONTAINER_WITH_CHOICE_ID));
+ dataModification.delete(serializer.toYangInstanceIdentifier(Ids.CONTAINER_WITH_CHOICE_ID));
}
private void writeContainerWithChoice(final DataModification dataModification,
final ContainerWithChoice containerWithChoice) {
final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
- serializer.toNormalizedNode(CONTAINER_WITH_CHOICE_ID, containerWithChoice);
+ serializer.toNormalizedNode(Ids.CONTAINER_WITH_CHOICE_ID, containerWithChoice);
dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
}
@@ -475,7 +409,7 @@ public class HoneycombWriteInfraTest {
private void writeContainerFromGrouping(final DataModification dataModification) {
final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
- serializer.toNormalizedNode(CONTAINER_FROM_GROUPING_ID, getContainerFromGrouping());
+ serializer.toNormalizedNode(Ids.CONTAINER_FROM_GROUPING_ID, getContainerFromGrouping());
dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
}
@@ -488,13 +422,13 @@ public class HoneycombWriteInfraTest {
private void writeSimpleContainer(final DataModification dataModification) {
final Map.Entry<YangInstanceIdentifier, NormalizedNode<?, ?>> normalizedNode =
- serializer.toNormalizedNode(SIMPLE_CONTAINER_ID, getSimpleContainer());
+ serializer.toNormalizedNode(Ids.SIMPLE_CONTAINER_ID, getSimpleContainer());
dataModification.write(normalizedNode.getKey(), normalizedNode.getValue());
}
private void deleteSimpleContainer(final DataModification dataModification) {
final YangInstanceIdentifier yangId =
- serializer.toYangInstanceIdentifier(SIMPLE_CONTAINER_ID);
+ serializer.toYangInstanceIdentifier(Ids.SIMPLE_CONTAINER_ID);
dataModification.delete(yangId);
}
@@ -540,7 +474,7 @@ public class HoneycombWriteInfraTest {
public void testSubtreeWriter() throws Exception {
writerRegistry = new FlatWriterRegistryBuilder()
// Handles also container from grouping
- .subtreeAdd(Sets.newHashSet(CONTAINER_FROM_GROUPING_ID), containerWithChoiceWriter)
+ .subtreeAdd(Sets.newHashSet(Ids.CONTAINER_FROM_GROUPING_ID), containerWithChoiceWriter)
.build();
final ModifiableDataTreeDelegator modifiableDataTreeDelegator =
@@ -556,7 +490,7 @@ public class HoneycombWriteInfraTest {
verify(containerWithChoiceWriter, atLeastOnce()).getManagedDataObjectType();
verify(containerWithChoiceWriter)
- .update(eq(CONTAINER_WITH_CHOICE_ID), eq(null), eq(containerWithChoice), any(WriteContext.class));
+ .update(eq(Ids.CONTAINER_WITH_CHOICE_ID), eq(null), eq(containerWithChoice), any(WriteContext.class));
verifyNoMoreInteractions(containerWithChoiceWriter);
// Test delete sub-node
@@ -567,7 +501,7 @@ public class HoneycombWriteInfraTest {
verify(containerWithChoiceWriter, atLeastOnce()).getManagedDataObjectType();
verify(containerWithChoiceWriter)
- .update(eq(CONTAINER_WITH_CHOICE_ID), eq(containerWithChoice), eq(containerWithChoiceEmpty), any(WriteContext.class));
+ .update(eq(Ids.CONTAINER_WITH_CHOICE_ID), eq(containerWithChoice), eq(containerWithChoiceEmpty), any(WriteContext.class));
verifyNoMoreInteractions(containerWithChoiceWriter);
// Test write with subtree node that's not handled by subtree writer
@@ -582,6 +516,6 @@ public class HoneycombWriteInfraTest {
}
private void deleteContainerFromGrouping(final DataModification dataModification) {
- dataModification.delete(serializer.toYangInstanceIdentifier(CONTAINER_FROM_GROUPING_ID));
+ dataModification.delete(serializer.toYangInstanceIdentifier(Ids.CONTAINER_FROM_GROUPING_ID));
}
} \ No newline at end of file
diff --git a/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/Ids.java b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/Ids.java
new file mode 100644
index 000000000..200f50c32
--- /dev/null
+++ b/v3po/it/it-test/src/test/java/io/fd/honeycomb/v3po/data/impl/Ids.java
@@ -0,0 +1,62 @@
+/*
+ * 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 org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.ComplexAugment;
+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.SimpleAugment;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.SimpleContainer;
+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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.simple.container.ComplexAugmentContainer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.hc.test.rev150105.some.attributes.ContainerFromGrouping;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
+
+/**
+ * Instance identifiers referencing all complex nodes within IT test-model.
+ */
+interface Ids {
+
+ // Simple container
+ // ORDER = 3
+ InstanceIdentifier<SimpleContainer> SIMPLE_CONTAINER_ID = InstanceIdentifier.create(SimpleContainer.class);
+ // 2
+ InstanceIdentifier<SimpleAugment> SIMPLE_AUGMENT_ID = SIMPLE_CONTAINER_ID.augmentation(SimpleAugment.class);
+ // UNORDERED
+ InstanceIdentifier<ComplexAugment> COMPLEX_AUGMENT_ID = SIMPLE_CONTAINER_ID.augmentation(ComplexAugment.class);
+ // 1
+ InstanceIdentifier<ComplexAugmentContainer> COMPLEX_AUGMENT_CONTAINER_ID = COMPLEX_AUGMENT_ID.child(ComplexAugmentContainer.class);
+ // Container with list
+ // 9
+ InstanceIdentifier<ContainerWithList> CONTAINER_WITH_LIST_ID = InstanceIdentifier.create(ContainerWithList.class);
+ // 7
+ InstanceIdentifier<ListInContainer> LIST_IN_CONTAINER_ID = CONTAINER_WITH_LIST_ID.child(ListInContainer.class);
+ // 8
+ InstanceIdentifier<ContainerInList> CONTAINER_IN_LIST_ID = LIST_IN_CONTAINER_ID.child(ContainerInList.class);
+ // 6
+ InstanceIdentifier<NestedList> NESTED_LIST_ID = CONTAINER_IN_LIST_ID.child(NestedList.class);
+ // Container with choice
+ // 4
+ InstanceIdentifier<ContainerWithChoice> CONTAINER_WITH_CHOICE_ID = InstanceIdentifier.create(ContainerWithChoice.class);
+ // 2
+ InstanceIdentifier<C3> C3_ID = CONTAINER_WITH_CHOICE_ID.child(C3.class);
+ // 5
+ InstanceIdentifier<ContainerFromGrouping> CONTAINER_FROM_GROUPING_ID = CONTAINER_WITH_CHOICE_ID.child(ContainerFromGrouping.class);
+}