From c75cd8bec9058ce9b0b836be26108b8349b438dd Mon Sep 17 00:00:00 2001 From: "tobias.pobocik" Date: Thu, 1 Dec 2022 09:19:17 +0100 Subject: [PATCH] Add tests for ReadDataTransactionUtil WithDefaultParameters The part of code where default parameter is used was entirely not tested. Added model to create schema context and tests for testing the functionality. Signed-off-by: tobias.pobocik Change-Id: I53493185c40748fa00bfc0c489df743b209fbf43 --- .../utils/ReadDataTransactionUtilTest.java | 124 +++++++++++++++++- .../src/test/resources/modules/container.yang | 31 +++++ 2 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 restconf/restconf-nb/src/test/resources/modules/container.yang diff --git a/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtilTest.java b/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtilTest.java index 668e8d31ce..bc533619ad 100644 --- a/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtilTest.java +++ b/restconf/restconf-nb/src/test/java/org/opendaylight/restconf/nb/rfc8040/rests/utils/ReadDataTransactionUtilTest.java @@ -9,6 +9,7 @@ package org.opendaylight.restconf.nb.rfc8040.rests.utils; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doReturn; import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture; @@ -26,6 +27,8 @@ import org.opendaylight.mdsal.dom.api.DOMDataBroker; import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction; import org.opendaylight.netconf.dom.api.NetconfDataTreeService; import org.opendaylight.restconf.nb.rfc8040.ContentParam; +import org.opendaylight.restconf.nb.rfc8040.TestRestconfUtils; +import org.opendaylight.restconf.nb.rfc8040.WithDefaultsParam; import org.opendaylight.restconf.nb.rfc8040.rests.transactions.MdsalRestconfStrategy; import org.opendaylight.restconf.nb.rfc8040.rests.transactions.NetconfRestconfStrategy; import org.opendaylight.restconf.nb.rfc8040.rests.transactions.RestconfStrategy; @@ -33,13 +36,16 @@ import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode; +import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.MapNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext; +import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils; @RunWith(MockitoJUnitRunner.StrictStubs.class) public class ReadDataTransactionUtilTest { @@ -54,17 +60,20 @@ public class ReadDataTransactionUtilTest { @Mock private DOMDataTreeReadTransaction read; @Mock - private EffectiveModelContext schemaContext; + private EffectiveModelContext mockSchemaContext; @Mock private DOMDataBroker mockDataBroker; + private EffectiveModelContext schemaContext; @Before - public void setUp() { + public void setUp() throws Exception { // FIXME: these tests need to be parameterized somehow. The trouble is we need mocking before we invoke // the strategy. This needs some more thought. doReturn(read).when(mockDataBroker).newReadOnlyTransaction(); mdsalStrategy = new MdsalRestconfStrategy(mockDataBroker); netconfStrategy = new NetconfRestconfStrategy(netconfService); + schemaContext = YangParserTestUtils.parseYangFiles( + TestRestconfUtils.loadFiles("/modules")); } @Test @@ -142,6 +151,115 @@ public class ReadDataTransactionUtilTest { assertEquals(checkingData, normalizedNode); } + @Test + public void readLeafWithDefaultParameters() { + final LeafNode leafNode = Builders.leafBuilder().withNodeIdentifier( + new NodeIdentifier(QName.create(DATA.base, "exampleLeaf"))).withValue("i am leaf").build(); + + final ContainerNode content = Builders.containerBuilder() + .withNodeIdentifier(new NodeIdentifier(QName.create(DATA.base, "cont"))) + .withChild(leafNode) + .build(); + + final YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(content.getIdentifier()).build(); + + doReturn(immediateFluentFuture(Optional.of(content))).when(read) + .read(LogicalDatastoreType.CONFIGURATION, path); + doReturn(immediateFluentFuture(Optional.of(content))).when(read) + .read(LogicalDatastoreType.OPERATIONAL, path); + + final NormalizedNode normalizedNode = ReadDataTransactionUtil.readData( + ContentParam.ALL, path, mdsalStrategy, WithDefaultsParam.TRIM, schemaContext); + assertEquals(content, normalizedNode); + } + + @Test + public void readContainerWithDefaultParameters() { + final QName leafBool = QName.create(DATA.base, "leafBool"); + final QName containerBool = QName.create(DATA.base, "containerBool"); + final QName containerInt = QName.create(DATA.base, "containerInt"); + final QName leafInt = QName.create(DATA.base, "leafInt"); + final QName exampleList = QName.create(DATA.base, "exampleList"); + final QName cont = QName.create(DATA.base, "cont"); + + final LeafNode leafNode = Builders.leafBuilder().withNodeIdentifier( + NodeIdentifier.create(leafBool)) + .withValue(true).build(); + final ContainerNode containerNode = Builders.containerBuilder().withNodeIdentifier( + NodeIdentifier.create(containerBool)) + .withChild(leafNode).build(); + final LeafNode leafNode1 = Builders.leafBuilder().withNodeIdentifier( + NodeIdentifier.create(leafInt)) + .withValue(12).build(); + final ContainerNode containerNode1 = Builders.containerBuilder().withNodeIdentifier( + NodeIdentifier.create(containerInt)) + .withChild(leafNode1).build(); + final MapEntryNode entryNode = Builders.mapEntryBuilder() + .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifierWithPredicates.of(exampleList)) + .withChild(containerNode) + .addChild(containerNode1).build(); + final MapNode mapNode = Builders.mapBuilder().withNodeIdentifier( + NodeIdentifier.create(exampleList)) + .withChild(entryNode).build(); + final ContainerNode content = Builders.containerBuilder() + .withNodeIdentifier(new NodeIdentifier(cont)) + .withChild(mapNode).build(); + + final YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(cont).build(); + + doReturn(immediateFluentFuture(Optional.of(content))).when(read) + .read(LogicalDatastoreType.CONFIGURATION, path); + doReturn(immediateFluentFuture(Optional.of(content))).when(read) + .read(LogicalDatastoreType.OPERATIONAL, path); + + final NormalizedNode normalizedNode = ReadDataTransactionUtil.readData( + ContentParam.ALL, path, mdsalStrategy, WithDefaultsParam.TRIM, schemaContext); + +//assertEquals(content, normalizedNode); is not used because two duplicated child nodes are created in mapEntryNode + assertTrue(normalizedNode instanceof ContainerNode); + assertEquals(((MapNode) ((ContainerNode) normalizedNode).getChildByArg( + NodeIdentifier.create(exampleList))).getChildByArg( + YangInstanceIdentifier.NodeIdentifierWithPredicates.of(exampleList)), + ((MapNode) content.getChildByArg( + NodeIdentifier.create(exampleList))).childByArg( + YangInstanceIdentifier.NodeIdentifierWithPredicates.of(exampleList))); + } + + @Test + public void readLeafInListWithDefaultParameters() { + final QName leafInList = QName.create(DATA.base, "leafInList"); + final QName exampleList = QName.create(DATA.base, "exampleList"); + final QName container = QName.create(DATA.base, "cont"); + + final LeafNode leafNode = Builders.leafBuilder().withNodeIdentifier( + NodeIdentifier.create(leafInList)) + .withValue("I am leaf in list").build(); + + final MapEntryNode entryNode = Builders.mapEntryBuilder() + .withNodeIdentifier( + YangInstanceIdentifier.NodeIdentifierWithPredicates.of(exampleList)) + .addChild(leafNode).build(); + + final MapNode mapNode = Builders.mapBuilder().withNodeIdentifier( + NodeIdentifier.create(QName.create(DATA.base, "exampleList"))) + .withChild(entryNode).build(); + + final ContainerNode content = Builders.containerBuilder() + .withNodeIdentifier(new NodeIdentifier(container)) + .withChild(mapNode).build(); + + final YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(container).build(); + + doReturn(immediateFluentFuture(Optional.of(content))).when(read) + .read(LogicalDatastoreType.CONFIGURATION, path); + doReturn(immediateFluentFuture(Optional.of(content))).when(read) + .read(LogicalDatastoreType.OPERATIONAL, path); + + final NormalizedNode normalizedNode = ReadDataTransactionUtil.readData( + ContentParam.ALL, path, mdsalStrategy, WithDefaultsParam.TRIM, schemaContext); + assertEquals(content, normalizedNode); + } + @Test public void readContainerDataConfigNoValueOfContentTest() { doReturn(immediateFluentFuture(Optional.of(DATA.data3))).when(read) @@ -297,6 +415,6 @@ public class ReadDataTransactionUtilTest { */ private @Nullable NormalizedNode readData(final @NonNull ContentParam content, final YangInstanceIdentifier path, final @NonNull RestconfStrategy strategy) { - return ReadDataTransactionUtil.readData(content, path, strategy, null, schemaContext); + return ReadDataTransactionUtil.readData(content, path, strategy, null, mockSchemaContext); } } diff --git a/restconf/restconf-nb/src/test/resources/modules/container.yang b/restconf/restconf-nb/src/test/resources/modules/container.yang new file mode 100644 index 0000000000..14a39ab290 --- /dev/null +++ b/restconf/restconf-nb/src/test/resources/modules/container.yang @@ -0,0 +1,31 @@ +module base { +namespace "ns"; +prefix "mod1"; +revision "2016-02-28"; + + + container cont { + leaf exampleLeaf { + type string; + default "i am leaf"; + } + list exampleList{ + leaf leafInList{ + type string; + default "I am leaf in list"; + } + container containerBool{ + leaf leafBool{ + type boolean; + default true; + } + } + container containerInt{ + leaf leafInt{ + type int8; + default 12; + } + } + } + } +} \ No newline at end of file -- 2.36.6