From 5a3ab6032b66433b9147a3fcad214b6f9a4b56e7 Mon Sep 17 00:00:00 2001 From: Igor Foltin Date: Tue, 12 Sep 2017 14:34:12 +0200 Subject: [PATCH] Avoid module namespace/submodule name conflict when using lib sources The issue comes up when using yang-system-test artifact as a single YANG file validator: A parent module or a submodule is specified as its argument and the same directory is specified as one of the library dirs using the -p option. The parent module/submodule ends up being added twice to the parsed sources which causes a module namespace/submodule name collision later in the parsing process. Therefore remove the conflicting lib sources from the collection of required lib sources before they cause any trouble. Change-Id: Id41d9f57006adec7ff658904792f9bc319b8c11e Signed-off-by: Igor Foltin --- .../stmt/reactor/BuildGlobalContext.java | 17 ++++++++++ .../yangtools/yang/stmt/Bug7480Test.java | 32 +++++++++++++++++++ .../child-module.yang | 7 ++++ .../parent-module.yang | 8 +++++ 4 files changed, 64 insertions(+) create mode 100644 yang/yang-parser-impl/src/test/resources/bugs/bug7480/main-source-lib-source-conflict-test/child-module.yang create mode 100644 yang/yang-parser-impl/src/test/resources/bugs/bug7480/main-source-lib-source-conflict-test/parent-module.yang diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java index 3e77b2cd46..156fbe8c7c 100644 --- a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java +++ b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java @@ -427,6 +427,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh final Set requiredLibs = new HashSet<>(); for (final SourceSpecificContext source : sources) { collectRequiredSourcesFromLib(libSourcesTable, requiredLibs, source); + removeConflictingLibSources(source, requiredLibs); } return requiredLibs; } @@ -455,6 +456,22 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh return sourceMap != null && !sourceMap.isEmpty() ? sourceMap.get(sourceMap.lastKey()) : null; } + // removes required library sources which would cause namespace/name conflict with one of the main sources + // later in the parsing process. this can happen if we add a parent module or a submodule as a main source + // and the same parent module or submodule is added as one of the library sources. + // such situation may occur when using the yang-system-test artifact - if a parent module/submodule is specified + // as its argument and the same dir is specified as one of the library dirs through -p option). + private static void removeConflictingLibSources(final SourceSpecificContext source, + final Set requiredLibs) { + final Iterator requiredLibsIter = requiredLibs.iterator(); + while (requiredLibsIter.hasNext()) { + final SourceSpecificContext currentReqSource = requiredLibsIter.next(); + if (source.getRootIdentifier().equals(currentReqSource.getRootIdentifier())) { + requiredLibsIter.remove(); + } + } + } + private void endPhase(final ModelProcessingPhase phase) { Preconditions.checkState(currentPhase == phase); finishedPhase = currentPhase; diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7480Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7480Test.java index 1c393dba8e..3384c59029 100644 --- a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7480Test.java +++ b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7480Test.java @@ -19,6 +19,8 @@ import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil; import org.opendaylight.yangtools.yang.model.api.Module; import org.opendaylight.yangtools.yang.model.api.SchemaContext; import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException; +import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor; +import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline; public class Bug7480Test { @Test @@ -59,4 +61,34 @@ public class Bug7480Test { assertTrue(message.startsWith("Imported module [missing-lib] was not found.")); } } + + @Test + public void testHandlingOfMainSourceConflictingWithLibSource() throws Exception { + // parent module as main source and as lib source at the same time + // parser should remove it from the required lib sources and thus avoid module namespace collision + final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + reactor.addSource(StmtTestUtils.sourceForResource( + "/bugs/bug7480/main-source-lib-source-conflict-test/parent-module.yang")); + reactor.addLibSources(StmtTestUtils.sourceForResource( + "/bugs/bug7480/main-source-lib-source-conflict-test/child-module.yang"), + StmtTestUtils.sourceForResource( + "/bugs/bug7480/main-source-lib-source-conflict-test/parent-module.yang")); + final SchemaContext schemaContext = reactor.buildEffective(); + assertNotNull(schemaContext); + } + + @Test + public void testHandlingOfMainSourceConflictingWithLibSource2() throws Exception { + // submodule as main source and as lib source at the same time + // parser should remove it from the required lib sources and thus avoid submodule name collision + final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(); + reactor.addSource(StmtTestUtils.sourceForResource( + "/bugs/bug7480/main-source-lib-source-conflict-test/child-module.yang")); + reactor.addLibSources(StmtTestUtils.sourceForResource( + "/bugs/bug7480/main-source-lib-source-conflict-test/parent-module.yang"), + StmtTestUtils.sourceForResource( + "/bugs/bug7480/main-source-lib-source-conflict-test/child-module.yang")); + final SchemaContext schemaContext = reactor.buildEffective(); + assertNotNull(schemaContext); + } } diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7480/main-source-lib-source-conflict-test/child-module.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7480/main-source-lib-source-conflict-test/child-module.yang new file mode 100644 index 0000000000..10c1e2138d --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/bugs/bug7480/main-source-lib-source-conflict-test/child-module.yang @@ -0,0 +1,7 @@ +submodule child-module { + belongs-to parent-module { + prefix pm; + } + + container child-mod-cont {} +} \ No newline at end of file diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7480/main-source-lib-source-conflict-test/parent-module.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7480/main-source-lib-source-conflict-test/parent-module.yang new file mode 100644 index 0000000000..677cb02542 --- /dev/null +++ b/yang/yang-parser-impl/src/test/resources/bugs/bug7480/main-source-lib-source-conflict-test/parent-module.yang @@ -0,0 +1,8 @@ +module parent-module { + namespace pm-ns; + prefix pm; + + include child-module; + + container parent-mod-cont {} +} \ No newline at end of file -- 2.36.6