Bug 7954: Throw an exception when parsing duplicate (sub)modules 83/53283/6
authorIgor Foltin <ifoltin@cisco.com>
Tue, 14 Mar 2017 16:11:33 +0000 (17:11 +0100)
committerRobert Varga <nite@hq.sk>
Thu, 16 Mar 2017 11:53:44 +0000 (11:53 +0000)
In case we add the same YANG (sub)module to the YANG parsing
cycle twice, throw a SourceException which reports the problem
with colliding namespaces/names.

Change-Id: If0a0aff23ace2cdcbb3d87b639c9ef74f2302432
Signed-off-by: Igor Foltin <ifoltin@cisco.com>
13 files changed:
yang/yang-maven-plugin-it/src/test/resources/test-parent/GenerateTest1/src/main/resources/testfile1.yang
yang/yang-maven-plugin-it/src/test/resources/test-parent/GenerateTest1/src/main/resources/testfile2.yang
yang/yang-maven-plugin-it/src/test/resources/test-parent/GenerateTest1/src/main/resources/testfile3.yang
yang/yang-maven-plugin-it/src/test/resources/test-parent/files/testfile1.yang
yang/yang-maven-plugin-it/src/test/resources/test-parent/files/testfile2.yang
yang/yang-maven-plugin-it/src/test/resources/test-parent/files/testfile3.yang
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/ModuleStatementSupport.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/SubmoduleStatementImpl.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7954Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug7954/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug7954/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug7954/subbar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/negative-scenario/testfile3.yang

index a725d3d62ff5261520efc1d345a6a0bd934d8f23..dd5065552a81208f222b3396951da83b69b992a2 100644 (file)
@@ -7,7 +7,7 @@
  */
 module types1 {
     yang-version 1;
-    namespace "urn:simple.container.demo";
+    namespace "urn:simple.container.demo.types1";
     prefix "t1";
 
     import types2 {
index 14f2dc7a7797b7dca51022aa8cdb049ece05e5ab..9eec4b4a62da603292b8ca30a3ee9f10ac2c006c 100644 (file)
@@ -7,7 +7,7 @@
  */
 module types2 {
     yang-version 1;
-    namespace "urn:simple.types.data.demo";
+    namespace "urn:simple.types.data.demo.types2";
     prefix "t2";
     
     organization "opendaylight";
index be255a500203a44c753419ab13d8c029cc14101d..12901adedfcf19fa3aa53f8d5da0fe954d3b55a4 100644 (file)
@@ -7,7 +7,7 @@
  */
 module types3 {
     yang-version 1;
-    namespace "urn:simple.container.demo.test";
+    namespace "urn:simple.container.demo.types3";
     prefix "t3";
 
     import types2 {
index a725d3d62ff5261520efc1d345a6a0bd934d8f23..dd5065552a81208f222b3396951da83b69b992a2 100644 (file)
@@ -7,7 +7,7 @@
  */
 module types1 {
     yang-version 1;
-    namespace "urn:simple.container.demo";
+    namespace "urn:simple.container.demo.types1";
     prefix "t1";
 
     import types2 {
index 5284e19508badea7eaf93b34d6fd44aaa1006aff..f856acb3a62ec1e55457557a6483be39d53940f4 100644 (file)
@@ -7,7 +7,7 @@
  */
 module types2 {
     yang-version 1;
-    namespace "urn:simple.types.data.demo";
+    namespace "urn:simple.types.data.demo.types2";
     prefix "t2";
     
     organization "opendaylight";
index be255a500203a44c753419ab13d8c029cc14101d..12901adedfcf19fa3aa53f8d5da0fe954d3b55a4 100644 (file)
@@ -7,7 +7,7 @@
  */
 module types3 {
     yang-version 1;
-    namespace "urn:simple.container.demo.test";
+    namespace "urn:simple.container.demo.types3";
     prefix "t3";
 
     import types2 {
index a1a76db263182dfa12166eeb4fc1a55fa3edac1c..2fbdad58e6fd3ee36e41cd8e754b1a4d7b34ccbf 100644 (file)
@@ -142,6 +142,14 @@ public class ModuleStatementSupport extends
         }
 
         final QNameModule qNameModule = QNameModule.create(moduleNs.get(), revisionDate.orElse(null)).intern();
+
+        final StmtContext<?, ModuleStatement, EffectiveStatement<String, ModuleStatement>> possibleDuplicateModule =
+                stmt.getFromNamespace(NamespaceToModule.class, qNameModule);
+        if (possibleDuplicateModule != null && possibleDuplicateModule != stmt) {
+            throw new SourceException(stmt.getStatementSourceReference(), "Module namespace collision: %s. At %s",
+                    qNameModule.getNamespace(), possibleDuplicateModule.getStatementSourceReference());
+        }
+
         final ModuleIdentifier moduleIdentifier = ModuleIdentifierImpl.create(stmt.getStatementArgument(),
                 Optional.empty(), revisionDate);
 
index fabaed56dfc856d898de26c8424c45443eff1735..968fd4f92ad8c8e8d96e7448ab86dcaa644b9b1d 100644 (file)
@@ -100,6 +100,14 @@ public class SubmoduleStatementImpl extends AbstractRootStatement<SubmoduleState
         public void onLinkageDeclared(
                 final Mutable<String, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>> stmt) {
             final ModuleIdentifier submoduleIdentifier = getSubmoduleIdentifier(stmt);
+
+            final StmtContext<?, SubmoduleStatement, EffectiveStatement<String, SubmoduleStatement>> possibleDuplicateSubmodule =
+                    stmt.getFromNamespace(SubmoduleNamespace.class, submoduleIdentifier);
+            if (possibleDuplicateSubmodule != null && possibleDuplicateSubmodule != stmt) {
+                throw new SourceException(stmt.getStatementSourceReference(), "Submodule name collision: %s. At %s",
+                        stmt.getStatementArgument(), possibleDuplicateSubmodule.getStatementSourceReference());
+            }
+
             stmt.addContext(SubmoduleNamespace.class, submoduleIdentifier, stmt);
 
             final String belongsToModuleName = firstAttributeOf(stmt.declaredSubstatements(), BelongsToStatement.class);
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7954Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7954Test.java
new file mode 100644 (file)
index 0000000..5492924
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. 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.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
+
+public class Bug7954Test {
+
+    @Test
+    public void testParsingTheSameModuleTwice() throws Exception {
+        final File yang = new File(getClass().getResource("/bugs/bug7954/foo.yang").toURI());
+
+        try {
+            StmtTestUtils.parseYangSources(yang, yang);
+            fail("An exception should have been thrown because of adding the same YANG module twice.");
+        } catch (final ReactorException ex) {
+            final Throwable cause = ex.getCause();
+            assertTrue(cause instanceof SourceException);
+            assertTrue(cause.getMessage().startsWith("Module namespace collision: foo-ns."));
+        }
+    }
+
+    @Test
+    public void testParsingTheSameSubmoduleTwice() throws Exception {
+        final File yang = new File(getClass().getResource("/bugs/bug7954/bar.yang").toURI());
+        final File childYang = new File(getClass().getResource("/bugs/bug7954/subbar.yang").toURI());
+
+        try {
+            StmtTestUtils.parseYangSources(yang, childYang, childYang);
+            fail("An exception should have been thrown because of adding the same YANG submodule twice.");
+        } catch (final ReactorException ex) {
+            final Throwable cause = ex.getCause();
+            assertTrue(cause instanceof SourceException);
+            assertTrue(cause.getMessage().startsWith("Submodule name collision: subbar."));
+        }
+    }
+}
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7954/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7954/bar.yang
new file mode 100644 (file)
index 0000000..d1c2734
--- /dev/null
@@ -0,0 +1,16 @@
+module bar {
+    namespace bar-ns;
+    prefix bar-prefix;
+
+    include subbar {
+        revision-date 2017-03-14;
+    }
+
+    revision 2017-03-14;
+
+    container my-cont {
+        leaf my-leaf {
+            type string;
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7954/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7954/foo.yang
new file mode 100644 (file)
index 0000000..9e73917
--- /dev/null
@@ -0,0 +1,12 @@
+module foo {
+    namespace foo-ns;
+    prefix foo-prefix;
+
+    revision 2017-03-14;
+
+    container my-cont {
+        leaf my-leaf {
+            type string;
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7954/subbar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7954/subbar.yang
new file mode 100644 (file)
index 0000000..4bbcf93
--- /dev/null
@@ -0,0 +1,13 @@
+submodule subbar {
+    belongs-to bar {
+        prefix bar-prefix;
+    }
+
+    revision 2017-03-14;
+
+    container sub-container {
+        leaf sub-leaf {
+            type string;
+        }
+    }
+}
\ No newline at end of file
index 187e9dd6d8db066353bb5eeb02f2d32cf047df9b..a2d9a198b595f631185d403a0c8eaa0ffc6dfd4c 100644 (file)
@@ -1,6 +1,6 @@
 module test3 {
     yang-version 1;
-    namespace "urn:simple.container.demo";
+    namespace "urn:simple.container.demo.test3";
     prefix "t1";
 
     import test0 {