Bug 9244: Fix deviate replace of implicit substatements 17/64517/1
authorIgor Foltin <igor.foltin@pantheon.tech>
Tue, 17 Oct 2017 09:07:51 +0000 (11:07 +0200)
committerIgor Foltin <igor.foltin@pantheon.tech>
Thu, 19 Oct 2017 09:52:42 +0000 (11:52 +0200)
In case when a deviate replace of a config/mandatory/max/min-elements
substatement targets a node which does not contain an explicitly declared
config/mandatory/max/min-elements, YANG statement parser throws an exception
because it did not find the substatement in the target node.

However, according to RFC6020/7950, these properties are always implicitly
present. Therefore, perform a deviate add instead of throwing an exception
in this particular case.

Change-Id: I79e5c427040c81db7f2f68ebcfa71b274d48816d
Signed-off-by: Igor Foltin <igor.foltin@pantheon.tech>
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/DeviateStatementImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug9244Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug9244/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug9244/foo.yang [new file with mode: 0644]

index 3e91e08586bb88980fddeebdd40778c0292829f1..c0748c53f760755000fceb73b94913fd299d0975 100644 (file)
@@ -102,6 +102,9 @@ public class DeviateStatementImpl extends AbstractDeclaredStatement<DeviateKind>
                 YangStmtMapping.UNITS, YangStmtMapping.CONFIG, YangStmtMapping.MANDATORY,
                 YangStmtMapping.MIN_ELEMENTS, YangStmtMapping.MAX_ELEMENTS);
 
+        private static final Set<YangStmtMapping> IMPLICIT_STATEMENTS = ImmutableSet.of(YangStmtMapping.CONFIG,
+                YangStmtMapping.MANDATORY, YangStmtMapping.MAX_ELEMENTS, YangStmtMapping.MIN_ELEMENTS);
+
         public Definition() {
             super(YangStmtMapping.DEVIATE);
         }
@@ -270,6 +273,14 @@ public class DeviateStatementImpl extends AbstractDeclaredStatement<DeviateKind>
                 }
             }
 
+            // This is a special case when deviate replace of a config/mandatory/max/min-elements substatement targets
+            // a node which does not contain an explicitly declared config/mandatory/max/min-elements.
+            // However, according to RFC6020/RFC7950, these properties are always implicitly present.
+            if (IMPLICIT_STATEMENTS.contains(stmtToBeReplaced)) {
+                addStatement(stmtCtxToBeReplaced, targetCtx);
+                return;
+            }
+
             throw new InferenceException(stmtCtxToBeReplaced.getStatementSourceReference(), "Deviation cannot " +
                     "replace substatement %s in target node %s because it does not exist in target node.",
                     stmtToBeReplaced.getStatementName(), targetCtx.getStatementArgument());
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug9244Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug9244Test.java
new file mode 100644 (file)
index 0000000..4680bff
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.yangtools.yang.stmt;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Date;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class Bug9244Test {
+
+    @Test
+    public void testDeviateReplaceOfImplicitSubstatements() throws Exception {
+        final SchemaContext schemaContext = StmtTestUtils.parseYangSources("/bugs/bug9244/");
+        assertNotNull(schemaContext);
+
+        final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse("2017-10-13");
+
+        final Module barModule = schemaContext.findModuleByName("bar", revision);
+        assertNotNull(barModule);
+
+        final ContainerSchemaNode barCont = (ContainerSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "bar-cont"));
+        assertNotNull(barCont);
+        assertFalse(barCont.isConfiguration());
+
+        final LeafListSchemaNode barLeafList = (LeafListSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "bar-leaf-list"));
+        assertNotNull(barLeafList);
+        assertEquals(5, barLeafList.getConstraints().getMinElements().intValue());
+        assertEquals(10, barLeafList.getConstraints().getMaxElements().intValue());
+
+        final LeafSchemaNode barLeaf = (LeafSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "bar-leaf"));
+        assertNotNull(barLeaf);
+        assertTrue(barLeaf.getConstraints().isMandatory());
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug9244/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug9244/bar.yang
new file mode 100644 (file)
index 0000000..636f0f0
--- /dev/null
@@ -0,0 +1,18 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-10-13;
+
+    container bar-cont {
+
+    }
+
+    leaf-list bar-leaf-list {
+        type int32;
+    }
+
+    leaf bar-leaf {
+        type int32;
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug9244/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug9244/foo.yang
new file mode 100644 (file)
index 0000000..076ce79
--- /dev/null
@@ -0,0 +1,29 @@
+module foo {
+    namespace foo;
+    prefix foo;
+
+    import bar {
+        prefix bar;
+    }
+
+    revision 2017-10-13;
+
+    deviation "/bar:bar-cont" {
+        deviate replace {
+            config false;
+        }
+    }
+
+    deviation "/bar:bar-leaf-list" {
+        deviate replace {
+            min-elements 5;
+            max-elements 10;
+        }
+    }
+
+    deviation "/bar:bar-leaf" {
+        deviate replace {
+            mandatory true;
+        }
+    }
+}
\ No newline at end of file