Bug 8307: Add the option for activating deviation statements 52/56452/5
authorIgor Foltin <igor.foltin@pantheon.tech>
Tue, 16 May 2017 12:04:38 +0000 (14:04 +0200)
committerRobert Varga <nite@hq.sk>
Thu, 18 May 2017 09:06:53 +0000 (09:06 +0000)
YANG statement parser currently resolves all deviation statements.
Add the option to specify which of the processed YANG modules
can be deviated by the specified YANG modules. This information is
passed down to the statement parser in the form of
Map<QNameModule, Set<QNameModule>>. If no deviations should be
activated, use an empty Map. In default mode, that is when
the Map is not provided at all, all deviations are activated.

This patch handles only the statement reactor part.
SchemaContextFactory should be fixed in a separate patch.

Moreover, change the rules for allowed deviation target path.
A deviation statement cannot target nodes in the same module
as the one it is defined in. Adjust existing unit tests accordingly.

Change-Id: Ica0f8c09218e50fd4c3efeb4dc08acb4fa418798
Signed-off-by: Igor Foltin <ifoltin@cisco.com>
Signed-off-by: Igor Foltin <igor.foltin@pantheon.tech>
67 files changed:
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModulesDeviatedByModules.java [new file with mode: 0644]
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/BuildGlobalContext.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/reactor/CrossSourceStatementReactor.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/DeviateStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/DeviationStatementImpl.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/YangInferencePipeline.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug4933Test.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug7440Test.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug8307Test.java [new file with mode: 0644]
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/DeviationResolutionTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/DeviationStmtTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/EffectiveModuleTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/IfFeatureResolutionTest.java
yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/StmtTestUtils.java
yang/yang-parser-impl/src/test/resources/bugs/bug4933/correct/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug4933/correct/foo.yang
yang/yang-parser-impl/src/test/resources/bugs/bug4933/incorrect/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug4933/incorrect/foo.yang
yang/yang-parser-impl/src/test/resources/bugs/bug7440/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug7440/foo.yang
yang/yang-parser-impl/src/test/resources/bugs/bug8307/bar-invalid.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug8307/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug8307/baz-invalid.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug8307/baz.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug8307/foo-invalid.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug8307/foo.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/bugs/bug8307/foobar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid-2.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid-3.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid-4.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar10-invalid.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/foo-invalid-2.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/foo-invalid-3.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/foo-invalid-4.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/foo-invalid.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/foo.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/foo10-invalid.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar-invalid-2.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar-invalid.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar10-invalid.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/foo-invalid-2.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/foo-invalid.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/foo.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/foo10-invalid.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-not-supported/imported.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-not-supported/root.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar-invalid-2.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar-invalid-3.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar-invalid.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/foo-invalid-2.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/foo-invalid-3.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/foo-invalid.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/foo.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/foo-invalid-deviation-path.yang
yang/yang-parser-impl/src/test/resources/deviation-resolution-test/foo-invalid-deviation-target.yang
yang/yang-parser-impl/src/test/resources/deviation-stmt-test/bar-imp.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-stmt-test/bar.yang
yang/yang-parser-impl/src/test/resources/deviation-stmt-test/foo-imp.yang [new file with mode: 0644]
yang/yang-parser-impl/src/test/resources/deviation-stmt-test/foo.yang
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/imported.yang
yang/yang-parser-impl/src/test/resources/semantic-statement-parser/effective-module/root.yang
yang/yang-system-test/src/main/java/org/opendaylight/yangtools/yang/parser/system/test/SystemTestUtils.java

diff --git a/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModulesDeviatedByModules.java b/yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/spi/source/ModulesDeviatedByModules.java
new file mode 100644 (file)
index 0000000..77caed5
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * 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.parser.spi.source;
+
+import com.google.common.annotations.Beta;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.model.api.meta.IdentifierNamespace;
+
+/**
+ * Namespace used for storing information about modules that support deviation resolution.
+ * Map key (QNameModule) denotes a module which can be deviated by the modules specified in the Map value.
+ */
+@Beta
+public interface ModulesDeviatedByModules
+        extends IdentifierNamespace<ModulesDeviatedByModules.SupportedModules, Map<QNameModule, Set<QNameModule>>> {
+
+    enum SupportedModules {
+        SUPPORTED_MODULES
+    }
+}
index 5fc5db2061aeedd89c0a82bba01b468b56630549..322b05ffb624c31fbdba2158b6771772896b664c 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Verify;
 import com.google.common.collect.HashBasedTable;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Table;
@@ -30,6 +31,7 @@ import java.util.Set;
 import java.util.SortedMap;
 import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
 import org.opendaylight.yangtools.yang.common.YangVersion;
 import org.opendaylight.yangtools.yang.model.api.ModuleIdentifier;
@@ -49,6 +51,8 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.SomeModifiersUnresolvedException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupport;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StatementSupportBundle;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules.SupportedModules;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
 import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
 import org.opendaylight.yangtools.yang.parser.spi.source.SupportedFeaturesNamespace;
@@ -84,7 +88,7 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
 
     BuildGlobalContext(final Map<ModelProcessingPhase, StatementSupportBundle> supports,
             final Map<ValidationBundleType, Collection<?>> supportedValidation,
-            final StatementParserMode statementParserMode, final Set<QName> supportedFeatures) {
+            final StatementParserMode statementParserMode) {
         this.supports = Preconditions.checkNotNull(supports, "BuildGlobalContext#supports cannot be null");
 
         switch (statementParserMode) {
@@ -102,10 +106,6 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
             addToNs(ValidationBundlesNamespace.class, validationBundle.getKey(), validationBundle.getValue());
         }
 
-        if (supportedFeatures != null) {
-            addToNs(SupportedFeaturesNamespace.class, SupportedFeatures.SUPPORTED_FEATURES,
-                    ImmutableSet.copyOf(supportedFeatures));
-        }
         this.supportedVersions = ImmutableSet.copyOf(supports.get(ModelProcessingPhase.INIT).getSupportedVersions());
     }
 
@@ -129,6 +129,16 @@ class BuildGlobalContext extends NamespaceStorageSupport implements NamespaceBeh
         libSources.add(new SourceSpecificContext(this, libSource));
     }
 
+    void setSupportedFeatures(final Set<QName> supportedFeatures) {
+        addToNs(SupportedFeaturesNamespace.class, SupportedFeatures.SUPPORTED_FEATURES,
+                    ImmutableSet.copyOf(supportedFeatures));
+    }
+
+    void setModulesDeviatedByModules(final Map<QNameModule, Set<QNameModule>> modulesDeviatedByModules) {
+        addToNs(ModulesDeviatedByModules.class, SupportedModules.SUPPORTED_MODULES,
+                    ImmutableMap.copyOf(modulesDeviatedByModules));
+    }
+
     @Override
     public StorageNodeType getStorageNodeType() {
         return StorageNodeType.GLOBAL;
index f116991ab7943d5319b9adc2918463010966596e..c44e2463bc24f42f847062a01e068340288c4c8b 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.parser.stmt.reactor;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.io.ByteSource;
 import java.io.IOException;
@@ -18,7 +19,9 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.parser.api.YangSyntaxErrorException;
 import org.opendaylight.yangtools.yang.model.repo.api.StatementParserMode;
@@ -56,7 +59,7 @@ public final class CrossSourceStatementReactor {
     }
 
     /**
-     * Start a new reactor build using default statement parser mode and enabling all features.
+     * Start a new reactor build using the default statement parser mode with all features and deviations enabled.
      *
      * @return A new {@link BuildAction}.
      */
@@ -65,67 +68,99 @@ public final class CrossSourceStatementReactor {
     }
 
     /**
-     * Start a new reactor build using default statement parser mode and only specified features.
+     * Start a new reactor build using the default statement parser mode and enabling only the specified features
+     * and all deviations.
      *
      * @param supportedFeatures The set of supported features in the final SchemaContext
      * @return A new {@link BuildAction}.
      *
-     * @deprecated Use {@link #newBuild(Optional)} instead.
+     * @deprecated Use {@link #newBuild()} and then call setSupportedFeatures() on the created BuildAction instead.
      */
     @Deprecated
     public BuildAction newBuild(final Set<QName> supportedFeatures) {
-        return new BuildAction(warnOnNull(supportedFeatures), StatementParserMode.DEFAULT_MODE);
+        final BuildAction buildAction = newBuild();
+        if (supportedFeatures != null) {
+            buildAction.setSupportedFeatures(supportedFeatures);
+        }
+
+        return buildAction;
     }
 
     /**
-     * Start a new reactor build using default statement parser mode and only specified features.
+     * Start a new reactor build using the default statement parser mode and enabling only the specified features
+     * and all deviations.
      *
      * @param supportedFeatures The set of supported features in the final SchemaContext, if present.
      * @return A new {@link BuildAction}.
+     *
+     * @deprecated Use {@link #newBuild()} and then call setSupportedFeatures() on the created BuildAction instead.
      */
+    @Deprecated
     public BuildAction newBuild(final Optional<Set<QName>> supportedFeatures) {
-        return new BuildAction(supportedFeatures.orElse(null), StatementParserMode.DEFAULT_MODE);
+        final BuildAction buildAction = newBuild();
+        if (supportedFeatures.isPresent()) {
+            buildAction.setSupportedFeatures(supportedFeatures.get());
+        }
+
+        return buildAction;
     }
 
     /**
-     * Start a new reactor build using specified statement parser mode and enabling all features.
+     * Start a new reactor build using the specified statement parser mode and enabling all features and deviations.
      *
      * @param statementParserMode Parser mode to use
      * @return A new {@link BuildAction}.
      * @throws NullPointerException if statementParserMode is null
      */
     public BuildAction newBuild(final StatementParserMode statementParserMode) {
-        return new BuildAction(null, statementParserMode);
+        return new BuildAction(statementParserMode);
     }
 
     /**
-     * Start a new reactor build using default statement parser mode and only specified features.
+     * Start a new reactor build using the specified statement parser mode and enabling only the specified features
+     * and all deviations.
      *
      * @param statementParserMode Parser mode to use
      * @param supportedFeatures The set of supported features in the final SchemaContext
      * @return A new {@link BuildAction}.
      * @throws NullPointerException if statementParserMode is null
      *
-     * @deprecated Use {@link #newBuild(StatementParserMode, Optional)} instead.
+     * @deprecated Use {@link #newBuild(StatementParserMode)} and then call setSupportedFeatures()
+     * on the created BuildAction instead.
      */
     @Deprecated
     public BuildAction newBuild(final StatementParserMode statementParserMode,
             final Set<QName> supportedFeatures) {
-        return new BuildAction(warnOnNull(supportedFeatures), statementParserMode);
+        final BuildAction buildAction = new BuildAction(statementParserMode);
+        if (supportedFeatures != null) {
+            buildAction.setSupportedFeatures(supportedFeatures);
+        }
+
+        return buildAction;
     }
 
     /**
-     * Start a new reactor build using default statement parser mode and only specified features.
+     * Start a new reactor build using the specified statement parser mode and enabling only the specified features
+     * and all deviations.
      *
      * @param statementParserMode Parser mode to use
      * @param supportedFeatures The set of supported features in the final SchemaContext, or absent if all features
      *                          encountered should be supported.
      * @return A new {@link BuildAction}.
      * @throws NullPointerException if statementParserMode is null
+     *
+     * @deprecated Use {@link #newBuild(StatementParserMode)} and then call setSupportedFeatures()
+     * on the created BuildAction instead.
      */
+    @Deprecated
     public BuildAction newBuild(final StatementParserMode statementParserMode,
             final Optional<Set<QName>> supportedFeatures) {
-        return new BuildAction(supportedFeatures.orElse(null), statementParserMode);
+        final BuildAction buildAction = new BuildAction(statementParserMode);
+        if (supportedFeatures.isPresent()) {
+            buildAction.setSupportedFeatures(supportedFeatures.get());
+        }
+
+        return buildAction;
     }
 
     private static <T> T warnOnNull(final T obj) {
@@ -159,10 +194,12 @@ public final class CrossSourceStatementReactor {
 
     public class BuildAction {
         private final BuildGlobalContext context;
+        private boolean supportedFeaturesSet = false;
+        private boolean modulesDeviatedByModulesSet = false;
 
-        BuildAction(final Set<QName> supportedFeatures, final StatementParserMode statementParserMode) {
-            this.context = new BuildGlobalContext(supportedTerminology, supportedValidation, statementParserMode,
-                supportedFeatures);
+        BuildAction(@Nonnull final StatementParserMode statementParserMode) {
+            this.context = new BuildGlobalContext(supportedTerminology,supportedValidation,
+                    Preconditions.checkNotNull(statementParserMode));
         }
 
         /**
@@ -209,6 +246,36 @@ public final class CrossSourceStatementReactor {
             }
         }
 
+        /**
+         * Set supported features based on which all if-feature statements in the
+         * parsed YANG modules will be resolved.
+         *
+         * @param supportedFeatures
+         *            Set of supported features in the final SchemaContext.
+         *            If the set is empty, no features encountered will be supported.
+         */
+        public void setSupportedFeatures(@Nonnull final Set<QName> supportedFeatures) {
+            Preconditions.checkState(!supportedFeaturesSet, "Supported features should be set only once.");
+            context.setSupportedFeatures(Preconditions.checkNotNull(supportedFeatures));
+            supportedFeaturesSet = true;
+        }
+
+        /**
+         * Set YANG modules which can be deviated by specified modules during the parsing process.
+         * Map key (QNameModule) denotes a module which can be deviated by the modules in the Map value.
+         *
+         * @param modulesDeviatedByModules
+         *            Map of YANG modules (Map key) which can be deviated by specified modules (Map value) in the final
+         *            SchemaContext. If the map is empty, no deviations encountered will be supported.
+         */
+        public void setModulesWithSupportedDeviations(
+                @Nonnull final Map<QNameModule, Set<QNameModule>> modulesDeviatedByModules) {
+            Preconditions.checkState(!modulesDeviatedByModulesSet,
+                    "Modules with supported deviations should be set only once.");
+            context.setModulesDeviatedByModules(Preconditions.checkNotNull(modulesDeviatedByModules));
+            modulesDeviatedByModulesSet = true;
+        }
+
         /**
          * @throws org.opendaylight.yangtools.yang.parser.spi.source.SourceException
          * @throws ReactorException
index 94f8ac2f90e77d0a3baf851c91e8146484070ff9..8377d172054d84fc9cb9d3b6c64d4416774cf789 100644 (file)
@@ -10,9 +10,11 @@ package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import java.util.Collection;
+import java.util.Map;
 import java.util.Objects;
 import java.util.Set;
 import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.common.YangVersion;
 import org.opendaylight.yangtools.yang.model.api.DeviateKind;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
@@ -31,6 +33,9 @@ import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prereq
 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContextUtils;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules.SupportedModules;
 import org.opendaylight.yangtools.yang.parser.stmt.reactor.StatementContextBase;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DeviateEffectiveStatementImpl;
 import org.slf4j.Logger;
@@ -108,12 +113,16 @@ public class DeviateStatementImpl extends AbstractDeclaredStatement<DeviateKind>
             final DeviateKind deviateKind = deviateStmtCtx.getStatementArgument();
             getSubstatementValidatorForDeviate(deviateKind).validate(deviateStmtCtx);
 
-            final ModelActionBuilder deviateAction = deviateStmtCtx.newInferenceAction(
-                    ModelProcessingPhase.EFFECTIVE_MODEL);
-
             final SchemaNodeIdentifier deviationTarget =
                     (SchemaNodeIdentifier) deviateStmtCtx.getParentContext().getStatementArgument();
 
+            if (!isDeviationSupported(deviateStmtCtx, deviationTarget)) {
+                return;
+            }
+
+            final ModelActionBuilder deviateAction = deviateStmtCtx.newInferenceAction(
+                    ModelProcessingPhase.EFFECTIVE_MODEL);
+
             final Prerequisite<StmtContext<DeviateKind, DeviateStatement, EffectiveStatement<DeviateKind,
                     DeviateStatement>>> sourceCtxPrerequisite =
                     deviateAction.requiresCtx(deviateStmtCtx, ModelProcessingPhase.EFFECTIVE_MODEL);
@@ -155,6 +164,27 @@ public class DeviateStatementImpl extends AbstractDeclaredStatement<DeviateKind>
                     });
         }
 
+        private static boolean isDeviationSupported(final StmtContext.Mutable<DeviateKind, DeviateStatement,
+                EffectiveStatement<DeviateKind, DeviateStatement>> deviateStmtCtx,
+                final SchemaNodeIdentifier deviationTarget) {
+            final Map<QNameModule, Set<QNameModule>> modulesDeviatedByModules = deviateStmtCtx.getFromNamespace(
+                    ModulesDeviatedByModules.class, SupportedModules.SUPPORTED_MODULES);
+            if (modulesDeviatedByModules == null) {
+                return true;
+            }
+
+            final QNameModule currentModule = deviateStmtCtx.getFromNamespace(ModuleCtxToModuleQName.class,
+                    deviateStmtCtx.getRoot());
+            final QNameModule targetModule = deviationTarget.getLastComponent().getModule();
+
+            final Set<QNameModule> deviationModulesSupportedByTargetModule = modulesDeviatedByModules.get(targetModule);
+            if (deviationModulesSupportedByTargetModule != null) {
+                return deviationModulesSupportedByTargetModule.contains(currentModule);
+            }
+
+            return false;
+        }
+
         private static void performDeviateAdd(final StatementContextBase<?, ?, ?> deviateStmtCtx,
                 final StatementContextBase<?, ?, ?> targetCtx) {
             for (StatementContextBase<?, ?, ?> originalStmtCtx : deviateStmtCtx.declaredSubstatements()) {
index d75e3d6b939c88c8487db3ae18822c062f1ca9e6..68cb1fb8aecb769995730a21faa1b8437f1bdab4 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.yangtools.yang.parser.stmt.rfc6020;
 
 import javax.annotation.Nonnull;
+import org.opendaylight.yangtools.yang.common.QNameModule;
 import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
 import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
 import org.opendaylight.yangtools.yang.model.api.stmt.DeviationStatement;
@@ -15,7 +16,9 @@ import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier;
 import org.opendaylight.yangtools.yang.parser.spi.SubstatementValidator;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractDeclaredStatement;
 import org.opendaylight.yangtools.yang.parser.spi.meta.AbstractStatementSupport;
+import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.DeviationEffectiveStatementImpl;
 
 public class DeviationStatementImpl extends AbstractDeclaredStatement<SchemaNodeIdentifier> implements DeviationStatement {
@@ -52,6 +55,19 @@ public class DeviationStatementImpl extends AbstractDeclaredStatement<SchemaNode
             return new DeviationEffectiveStatementImpl(ctx);
         }
 
+        @Override
+        public void onFullDefinitionDeclared(final StmtContext.Mutable<SchemaNodeIdentifier, DeviationStatement,
+                EffectiveStatement<SchemaNodeIdentifier, DeviationStatement>> ctx) {
+            final QNameModule currentModule = ctx.getFromNamespace(ModuleCtxToModuleQName.class,
+                    ctx.getRoot());
+            final QNameModule targetModule = ctx.getStatementArgument().getLastComponent().getModule();
+
+            if (currentModule.equals(targetModule)) {
+                throw new InferenceException(ctx.getStatementSourceReference(),
+                        "Deviation must not target the same module as the one it is defined in: %s", currentModule);
+            }
+        }
+
         @Override
         protected SubstatementValidator getSubstatementValidator() {
             return SUBSTATEMENT_VALIDATOR;
index b43e4bc8bf762647d14950e194d69715a0e51a72..7b283fcb61bb7fc0f773005099184456315ccd10 100644 (file)
@@ -53,6 +53,7 @@ import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToModuleQName
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNameToNamespace;
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleNamespaceForBelongsTo;
 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleQNameToModuleName;
+import org.opendaylight.yangtools.yang.parser.spi.source.ModulesDeviatedByModules;
 import org.opendaylight.yangtools.yang.parser.spi.source.PrefixToModule;
 import org.opendaylight.yangtools.yang.parser.spi.source.QNameToStatementDefinition;
 import org.opendaylight.yangtools.yang.parser.spi.source.StmtOrderingNamespace;
@@ -92,6 +93,7 @@ public final class YangInferencePipeline {
     public static final StatementSupportBundle INIT_BUNDLE = StatementSupportBundle
             .builder(SUPPORTED_VERSIONS).addSupport(global(ValidationBundlesNamespace.class))
             .addSupport(global(SupportedFeaturesNamespace.class))
+            .addSupport(global(ModulesDeviatedByModules.class))
             .build();
 
     public static final StatementSupportBundle PRE_LINKAGE_BUNDLE = StatementSupportBundle
index 2019d64c05f58b62d67358bac28955bf0cf97caa..e22cc13aebe4d5a29ffb36d2964b233b19b19f15 100644 (file)
@@ -15,6 +15,7 @@ import static org.junit.Assert.fail;
 import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.model.api.Deviation;
+import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
@@ -26,7 +27,9 @@ public class Bug4933Test {
         SchemaContext context = StmtTestUtils.parseYangSources("/bugs/bug4933/correct");
         assertNotNull(context);
 
-        Set<Deviation> deviations = context.getModules().iterator().next().getDeviations();
+        final Module foo = context.findModuleByName("foo", null);
+
+        Set<Deviation> deviations = foo.getDeviations();
         assertEquals(4, deviations.size());
     }
 
index d09a80b9d6201473975009d13d682ed5cc42d240..a2bb499dd3cc9c2aab2ce99daf510d760b7d919f 100644 (file)
@@ -28,13 +28,15 @@ public class Bug7440Test {
 
     @Test
     public void testRestrictedTypeParentSchemaPathInDeviate() throws Exception {
-        final SchemaContext schemaContext = StmtTestUtils.parseYangSource("/bugs/bug7440/foo.yang");
+        final SchemaContext schemaContext = StmtTestUtils.parseYangSources("/bugs/bug7440");
         assertNotNull(schemaContext);
 
         final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse("2016-12-23");
 
         final Module foo = schemaContext.findModuleByName("foo", revision);
         assertNotNull(foo);
+        final Module bar = schemaContext.findModuleByName("bar", revision);
+        assertNotNull(bar);
 
         final Set<Deviation> deviations = foo.getDeviations();
         assertEquals(1, deviations.size());
@@ -44,8 +46,8 @@ public class Bug7440Test {
         assertEquals(1, deviates.size());
         final DeviateDefinition deviateReplace = deviates.iterator().next();
 
-        final SchemaPath deviatedTypePath = SchemaPath.create(true, QName.create(foo.getQNameModule(), "test-leaf"),
-                QName.create(foo.getQNameModule(), "uint32"));
+        final SchemaPath deviatedTypePath = SchemaPath.create(true, QName.create(bar.getQNameModule(), "test-leaf"),
+                QName.create(bar.getQNameModule(), "uint32"));
 
         final TypeDefinition<?> deviatedType = deviateReplace.getDeviatedType();
         assertEquals(deviatedTypePath, deviatedType.getPath());
diff --git a/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug8307Test.java b/yang/yang-parser-impl/src/test/java/org/opendaylight/yangtools/yang/stmt/Bug8307Test.java
new file mode 100644 (file)
index 0000000..471495f
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * 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.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.net.URI;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Map;
+import java.util.Set;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
+import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
+import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
+import org.opendaylight.yangtools.yang.parser.spi.source.StatementStreamSource;
+import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
+import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
+
+public class Bug8307Test {
+
+    private static final StatementStreamSource FOO_MODULE = sourceForResource("/bugs/bug8307/foo.yang");
+    private static final StatementStreamSource BAR_MODULE = sourceForResource("/bugs/bug8307/bar.yang");
+    private static final StatementStreamSource BAZ_MODULE = sourceForResource("/bugs/bug8307/baz.yang");
+    private static final StatementStreamSource FOOBAR_MODULE = sourceForResource("/bugs/bug8307/foobar.yang");
+    private static final StatementStreamSource FOO_INVALID_MODULE = sourceForResource("/bugs/bug8307/foo-invalid.yang");
+    private static final StatementStreamSource BAR_INVALID_MODULE = sourceForResource("/bugs/bug8307/bar-invalid.yang");
+    private static final StatementStreamSource BAZ_INVALID_MODULE = sourceForResource("/bugs/bug8307/baz-invalid.yang");
+
+    private static final URI FOO_NS = URI.create("foo-ns");
+    private static final URI BAR_NS = URI.create("bar-ns");
+    private static final URI BAZ_NS = URI.create("baz-ns");
+
+    private static Date revision;
+    private static QNameModule foo;
+    private static QName myFooContA;
+    private static QName myFooContB;
+    private static QName myFooContC;
+    private static QNameModule bar;
+    private static QName myBarContA;
+    private static QName myBarContB;
+    private static QNameModule baz;
+    private static QName myBazCont;
+
+    @BeforeClass
+    public static void setup() throws ParseException {
+        revision = SimpleDateFormatUtil.getRevisionFormat().parse("2017-05-16");
+        foo = QNameModule.create(FOO_NS, revision);
+        myFooContA = QName.create(foo, "my-foo-cont-a");
+        myFooContB = QName.create(foo, "my-foo-cont-b");
+        myFooContC = QName.create(foo, "my-foo-cont-c");
+        bar = QNameModule.create(BAR_NS, revision);
+        myBarContA = QName.create(bar, "my-bar-cont-a");
+        myBarContB = QName.create(bar, "my-bar-cont-b");
+        baz = QNameModule.create(BAZ_NS, revision);
+        myBazCont = QName.create(baz, "my-baz-cont");
+    }
+
+    @Test
+    public void testDeviationsSupportedInSomeModules() throws Exception {
+        final Map<QNameModule, Set<QNameModule>> modulesWithSupportedDeviations = ImmutableMap.of(
+                foo, ImmutableSet.of(bar, baz), bar, ImmutableSet.of(baz));
+
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+        reactor.addSources(FOO_MODULE, BAR_MODULE, BAZ_MODULE, FOOBAR_MODULE);
+        reactor.setModulesWithSupportedDeviations(modulesWithSupportedDeviations);
+
+        final SchemaContext schemaContext = reactor.buildEffective();
+        assertNotNull(schemaContext);
+
+        assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myFooContA)));
+        assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myFooContB)));
+        assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myFooContC)));
+        assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myBarContA)));
+        assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myBarContB)));
+    }
+
+    @Test
+    public void testDeviationsSupportedInAllModules() throws Exception {
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+        reactor.addSources(FOO_MODULE, BAR_MODULE, BAZ_MODULE, FOOBAR_MODULE);
+
+        final SchemaContext schemaContext = reactor.buildEffective();
+        assertNotNull(schemaContext);
+
+        assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myFooContA)));
+        assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myFooContB)));
+        assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myFooContC)));
+        assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myBarContA)));
+        assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myBarContB)));
+    }
+
+    @Test
+    public void testDeviationsSupportedInNoModule() throws Exception {
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+        reactor.addSources(FOO_MODULE, BAR_MODULE, BAZ_MODULE, FOOBAR_MODULE);
+        reactor.setModulesWithSupportedDeviations(ImmutableMap.of());
+
+        final SchemaContext schemaContext = reactor.buildEffective();
+        assertNotNull(schemaContext);
+
+        assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myFooContA)));
+        assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myFooContB)));
+        assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myFooContC)));
+        assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myBarContA)));
+        assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, myBarContB)));
+    }
+
+    @Test
+    public void shouldFailOnAttemptToDeviateTheSameModule() {
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+        reactor.addSources(FOO_INVALID_MODULE);
+
+        try {
+            reactor.buildEffective();
+            fail("Deviation that targets the same module as the one it is defined is forbidden.");
+        } catch (final ReactorException ex) {
+            final Throwable cause = ex.getCause();
+            assertTrue(cause instanceof InferenceException);
+            assertTrue(cause.getMessage().startsWith(
+                    "Deviation must not target the same module as the one it is defined in"));
+        }
+    }
+
+    @Test
+    public void shouldFailOnAttemptToDeviateTheSameModule2() {
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
+        reactor.addSources(BAR_INVALID_MODULE, BAZ_INVALID_MODULE);
+
+        try {
+            reactor.buildEffective();
+            fail("Deviation that targets the same module as the one it is defined is forbidden.");
+        } catch (final ReactorException ex) {
+            final Throwable cause = ex.getCause();
+            assertTrue(cause instanceof InferenceException);
+            assertTrue(cause.getMessage().startsWith(
+                    "Deviation must not target the same module as the one it is defined in"));
+        }
+    }
+}
index 4f716aa4c0b26b05221b4c841699188cdaba6f9c..b31ebaba6c5550cc896c5cec728ea7803ca60b01 100644 (file)
@@ -14,8 +14,10 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
 
 import java.io.ByteArrayOutputStream;
+import java.io.File;
 import java.io.PrintStream;
 import java.util.Date;
 import org.junit.Test;
@@ -46,23 +48,20 @@ public class DeviationResolutionTest {
 
         final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse("2017-01-20");
 
-        final Module rootModule = schemaContext.findModuleByName("root", revision);
-        assertNotNull(rootModule);
+        final Module importedModule = schemaContext.findModuleByName("imported", revision);
+        assertNotNull(importedModule);
 
-        final ContainerSchemaNode myContA = (ContainerSchemaNode) rootModule.getDataChildByName(
-                QName.create(rootModule.getQNameModule(), "my-cont-a"));
+        final ContainerSchemaNode myContA = (ContainerSchemaNode) importedModule.getDataChildByName(
+                QName.create(importedModule.getQNameModule(), "my-cont-a"));
         assertNotNull(myContA);
 
         assertEquals(1, myContA.getChildNodes().size());
-        assertNotNull(myContA.getDataChildByName(QName.create(rootModule.getQNameModule(), "my-leaf-a3")));
+        assertNotNull(myContA.getDataChildByName(QName.create(importedModule.getQNameModule(), "my-leaf-a3")));
 
-        final ContainerSchemaNode myContB = (ContainerSchemaNode) rootModule.getDataChildByName(
-                QName.create(rootModule.getQNameModule(), "my-cont-b"));
+        final ContainerSchemaNode myContB = (ContainerSchemaNode) importedModule.getDataChildByName(
+                QName.create(importedModule.getQNameModule(), "my-cont-b"));
         assertNull(myContB);
 
-        final Module importedModule = schemaContext.findModuleByName("imported", revision);
-        assertNotNull(importedModule);
-
         final ContainerSchemaNode myContC = (ContainerSchemaNode) importedModule.getDataChildByName(
                 QName.create(importedModule.getQNameModule(), "my-cont-c"));
         assertNotNull(myContC);
@@ -74,17 +73,18 @@ public class DeviationResolutionTest {
 
     @Test
     public void testDeviateAdd() throws Exception {
-        final SchemaContext schemaContext = StmtTestUtils.parseYangSource(
-                "/deviation-resolution-test/deviation-add/foo.yang");
+        final SchemaContext schemaContext = StmtTestUtils.parseYangSources(
+                sourceForResource("/deviation-resolution-test/deviation-add/foo.yang"),
+                sourceForResource("/deviation-resolution-test/deviation-add/bar.yang"));
         assertNotNull(schemaContext);
 
         final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse("2017-01-20");
 
-        final Module fooModule = schemaContext.findModuleByName("foo", revision);
-        assertNotNull(fooModule);
+        final Module barModule = schemaContext.findModuleByName("bar", revision);
+        assertNotNull(barModule);
 
-        final LeafListSchemaNode myLeafList = (LeafListSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-leaf-list"));
+        final LeafListSchemaNode myLeafList = (LeafListSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-leaf-list"));
         assertNotNull(myLeafList);
 
         assertFalse(myLeafList.isConfiguration());
@@ -93,27 +93,27 @@ public class DeviationResolutionTest {
         assertEquals(5, myLeafList.getConstraints().getMinElements().intValue());
         assertNotNull(myLeafList.getType().getUnits());
 
-        final ListSchemaNode myList = (ListSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-list"));
+        final ListSchemaNode myList = (ListSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-list"));
         assertNotNull(myList);
         assertEquals(2, myList.getUniqueConstraints().size());
 
-        final ChoiceSchemaNode myChoice = (ChoiceSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-choice"));
+        final ChoiceSchemaNode myChoice = (ChoiceSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-choice"));
         assertNotNull(myChoice);
         assertEquals("c2", myChoice.getDefaultCase());
 
-        final RpcDefinition myRpc = fooModule.getRpcs().iterator().next();
+        final RpcDefinition myRpc = barModule.getRpcs().iterator().next();
         final ContainerSchemaNode input = myRpc.getInput();
         assertEquals(2, input.getConstraints().getMustConstraints().size());
         final ContainerSchemaNode output = myRpc.getOutput();
         assertEquals(2, output.getConstraints().getMustConstraints().size());
 
-        final NotificationDefinition myNotification = fooModule.getNotifications().iterator().next();
+        final NotificationDefinition myNotification = barModule.getNotifications().iterator().next();
         assertEquals(2, myNotification.getConstraints().getMustConstraints().size());
 
-        final AnyXmlSchemaNode myAnyxml = (AnyXmlSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-anyxml"));
+        final AnyXmlSchemaNode myAnyxml = (AnyXmlSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-anyxml"));
         assertNotNull(myAnyxml);
         assertTrue(myAnyxml.getConstraints().isMandatory());
         assertEquals(2, myAnyxml.getUnknownSchemaNodes().size());
@@ -121,17 +121,18 @@ public class DeviationResolutionTest {
 
     @Test
     public void testDeviateReplace() throws Exception {
-        final SchemaContext schemaContext = StmtTestUtils.parseYangSource(
-                "/deviation-resolution-test/deviation-replace/foo.yang");
+        final SchemaContext schemaContext = StmtTestUtils.parseYangSources(
+                sourceForResource("/deviation-resolution-test/deviation-replace/foo.yang"),
+                sourceForResource("/deviation-resolution-test/deviation-replace/bar.yang"));
         assertNotNull(schemaContext);
 
         final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse("2017-01-20");
 
-        final Module fooModule = schemaContext.findModuleByName("foo", revision);
-        assertNotNull(fooModule);
+        final Module barModule = schemaContext.findModuleByName("bar", revision);
+        assertNotNull(barModule);
 
-        final LeafSchemaNode myLeaf = (LeafSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-leaf"));
+        final LeafSchemaNode myLeaf = (LeafSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-leaf"));
         assertNotNull(myLeaf);
 
         assertTrue(myLeaf.getType() instanceof UnsignedIntegerTypeDefinition);
@@ -140,28 +141,28 @@ public class DeviationResolutionTest {
         assertNotNull(myLeaf.getDefault());
         assertEquals("10", myLeaf.getDefault());
 
-        final LeafListSchemaNode myLeafList = (LeafListSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-leaf-list-test"));
+        final LeafListSchemaNode myLeafList = (LeafListSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-leaf-list-test"));
         assertNotNull(myLeafList);
 
         assertEquals(6, myLeafList.getConstraints().getMaxElements().intValue());
         assertEquals(3, myLeafList.getConstraints().getMinElements().intValue());
         assertTrue(myLeafList.isConfiguration());
 
-        final ChoiceSchemaNode myChoice = (ChoiceSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-choice"));
+        final ChoiceSchemaNode myChoice = (ChoiceSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-choice"));
         assertNotNull(myChoice);
 
         assertFalse(myChoice.getConstraints().isMandatory());
         assertEquals(1, myChoice.getUnknownSchemaNodes().size());
         assertEquals("new arg", myChoice.getUnknownSchemaNodes().iterator().next().getNodeParameter());
 
-        final ContainerSchemaNode myCont = (ContainerSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-cont"));
+        final ContainerSchemaNode myCont = (ContainerSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-cont"));
         assertNotNull(myCont);
 
         final LeafSchemaNode myAugLeaf = (LeafSchemaNode) myCont.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-aug-leaf"));
+                QName.create(barModule.getQNameModule(), "my-aug-leaf"));
         assertNotNull(myAugLeaf);
         assertTrue(myAugLeaf.getType() instanceof UnsignedIntegerTypeDefinition);
         assertNotNull(myAugLeaf.getUnits());
@@ -172,7 +173,7 @@ public class DeviationResolutionTest {
         assertEquals("new arg", myAugLeaf.getUnknownSchemaNodes().iterator().next().getNodeParameter());
 
         final LeafSchemaNode myUsedLeaf = (LeafSchemaNode) myCont.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-used-leaf"));
+                QName.create(barModule.getQNameModule(), "my-used-leaf"));
         assertNotNull(myUsedLeaf);
         assertTrue(myUsedLeaf.getType() instanceof UnsignedIntegerTypeDefinition);
         assertNotNull(myUsedLeaf.getUnits());
@@ -185,43 +186,44 @@ public class DeviationResolutionTest {
 
     @Test
     public void testDeviateDelete() throws Exception {
-        final SchemaContext schemaContext = StmtTestUtils.parseYangSource(
-                "/deviation-resolution-test/deviation-delete/foo.yang");
+        final SchemaContext schemaContext = StmtTestUtils.parseYangSources(
+                sourceForResource("/deviation-resolution-test/deviation-delete/foo.yang"),
+                sourceForResource("/deviation-resolution-test/deviation-delete/bar.yang"));
         assertNotNull(schemaContext);
 
         final Date revision = SimpleDateFormatUtil.getRevisionFormat().parse("2017-01-20");
 
-        final Module fooModule = schemaContext.findModuleByName("foo", revision);
-        assertNotNull(fooModule);
+        final Module barModule = schemaContext.findModuleByName("bar", revision);
+        assertNotNull(barModule);
 
-        final LeafSchemaNode myLeaf = (LeafSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-leaf"));
+        final LeafSchemaNode myLeaf = (LeafSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-leaf"));
         assertNotNull(myLeaf);
 
         assertNull(myLeaf.getDefault());
         assertNull(myLeaf.getUnits());
         assertEquals(0, myLeaf.getUnknownSchemaNodes().size());
 
-        final LeafListSchemaNode myLeafList = (LeafListSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-leaf-list"));
+        final LeafListSchemaNode myLeafList = (LeafListSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-leaf-list"));
         assertNotNull(myLeafList);
 
         assertEquals(0, myLeafList.getDefaults().size());
         assertEquals(0, myLeafList.getConstraints().getMustConstraints().size());
 
-        final ListSchemaNode myList = (ListSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-list"));
+        final ListSchemaNode myList = (ListSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-list"));
         assertNotNull(myList);
 
         assertEquals(0, myList.getUniqueConstraints().size());
         assertEquals(0, myList.getUnknownSchemaNodes().size());
 
-        final ContainerSchemaNode myCont = (ContainerSchemaNode) fooModule.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-cont"));
+        final ContainerSchemaNode myCont = (ContainerSchemaNode) barModule.getDataChildByName(
+                QName.create(barModule.getQNameModule(), "my-cont"));
         assertNotNull(myCont);
 
         final LeafSchemaNode myAugLeaf = (LeafSchemaNode) myCont.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-aug-leaf"));
+                QName.create(barModule.getQNameModule(), "my-aug-leaf"));
         assertNotNull(myAugLeaf);
         assertNull(myAugLeaf.getDefault());
         assertNull(myAugLeaf.getUnits());
@@ -229,7 +231,7 @@ public class DeviationResolutionTest {
         assertEquals(0, myAugLeaf.getUnknownSchemaNodes().size());
 
         final LeafSchemaNode myUsedLeaf = (LeafSchemaNode) myCont.getDataChildByName(
-                QName.create(fooModule.getQNameModule(), "my-used-leaf"));
+                QName.create(barModule.getQNameModule(), "my-used-leaf"));
         assertNotNull(myUsedLeaf);
         assertNull(myUsedLeaf.getDefault());
         assertNull(myUsedLeaf.getUnits());
@@ -240,7 +242,9 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidYang10Model() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-add/foo10-invalid.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/deviation-add/foo10-invalid.yang"),
+                    sourceForResource("/deviation-resolution-test/deviation-add/bar10-invalid.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
@@ -252,7 +256,9 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidYang10Model2() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-delete/foo10-invalid.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/deviation-delete/foo10-invalid.yang"),
+                    sourceForResource("/deviation-resolution-test/deviation-delete/bar10-invalid.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
@@ -264,12 +270,14 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidDeviationTarget() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/foo-invalid-deviation-target.yang");
+            StmtTestUtils.parseYangSources(sourceForResource(
+                    "/deviation-resolution-test/foo-invalid-deviation-target.yang"),
+                    sourceForResource("/deviation-resolution-test/bar.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
             assertTrue(cause instanceof InferenceException);
-            assertTrue(cause.getMessage().startsWith("(foo?revision=2017-01-20)my-cont is not a valid deviation " +
+            assertTrue(cause.getMessage().startsWith("(bar?revision=2017-01-20)my-cont is not a valid deviation " +
                     "target for substatement (urn:ietf:params:xml:ns:yang:yin:1)max-elements."));
         }
     }
@@ -277,26 +285,30 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidDeviationPath() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/foo-invalid-deviation-path.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/foo-invalid-deviation-path.yang"),
+                    sourceForResource("/deviation-resolution-test/bar.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause().getCause();
             assertTrue(cause instanceof InferenceException);
-            assertTrue(cause.getMessage().startsWith("Deviation target 'Absolute{path=[(foo?revision=2017-01-20)invalid, " +
-                    "(foo?revision=2017-01-20)path]}' not found"));
+            assertTrue(cause.getMessage().startsWith("Deviation target 'Absolute{path=[(bar?revision=2017-01-20)" +
+                    "invalid, (bar?revision=2017-01-20)path]}' not found"));
         }
     }
 
     @Test
     public void shouldFailOnInvalidDeviateAdd() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-add/foo-invalid.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/deviation-add/foo-invalid.yang"),
+                    sourceForResource("/deviation-resolution-test/deviation-add/bar-invalid.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
             assertTrue(cause instanceof InferenceException);
             assertTrue(cause.getMessage().startsWith("Deviation cannot add substatement (urn:ietf:params:xml:ns:yang" +
-                    ":yin:1)config to target node (foo?revision=2017-01-20)my-leaf because it is already defined in" +
+                    ":yin:1)config to target node (bar?revision=2017-01-20)my-leaf because it is already defined in" +
                     " target and can appear only once."));
         }
     }
@@ -304,13 +316,15 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidDeviateAdd2() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-add/foo-invalid-2.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/deviation-add/foo-invalid-2.yang"),
+                    sourceForResource("/deviation-resolution-test/deviation-add/bar-invalid-2.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
             assertTrue(cause instanceof InferenceException);
             assertTrue(cause.getMessage().startsWith("Deviation cannot add substatement (urn:ietf:params:xml:ns:yang" +
-                    ":yin:1)default to target node (foo?revision=2017-01-20)my-leaf because it is already defined in" +
+                    ":yin:1)default to target node (bar?revision=2017-01-20)my-leaf because it is already defined in" +
                     " target and can appear only once."));
         }
     }
@@ -318,13 +332,15 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidDeviateAdd3() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-add/foo-invalid-4.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/deviation-add/foo-invalid-4.yang"),
+                    sourceForResource("/deviation-resolution-test/deviation-add/bar-invalid-4.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
             assertTrue(cause instanceof InferenceException);
             assertTrue(cause.getMessage().startsWith("Deviation cannot add substatement (urn:ietf:params:xml:ns:yang" +
-                    ":yin:1)default to target node (foo?revision=2017-02-01)my-used-leaf because it is already " +
+                    ":yin:1)default to target node (bar?revision=2017-02-01)my-used-leaf because it is already " +
                     "defined in target and can appear only once."));
         }
     }
@@ -332,13 +348,15 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidDeviateReplace() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-replace/foo-invalid.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/deviation-replace/foo-invalid.yang"),
+                    sourceForResource("/deviation-resolution-test/deviation-replace/bar-invalid.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
             assertTrue(cause instanceof InferenceException);
             assertTrue(cause.getMessage().startsWith("Deviation cannot replace substatement " +
-                    "(urn:ietf:params:xml:ns:yang:yin:1)units in target node (foo?revision=2017-01-20)my-leaf " +
+                    "(urn:ietf:params:xml:ns:yang:yin:1)units in target node (bar?revision=2017-01-20)my-leaf " +
                     "because it does not exist in target node."));
         }
     }
@@ -351,11 +369,13 @@ public class DeviationResolutionTest {
 
         System.setOut(new PrintStream(output, true, "UTF-8"));
 
-        StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-replace/foo-invalid-2.yang");
+        StmtTestUtils.parseYangSources(
+                sourceForResource("/deviation-resolution-test/deviation-replace/foo-invalid-2.yang"),
+                sourceForResource("/deviation-resolution-test/deviation-replace/bar-invalid-2.yang"));
 
         testLog = output.toString();
         assertTrue(testLog.contains("Deviation cannot replace substatement (urn:ietf:params:xml:ns:yang:yin:1)default" +
-                " in target leaf-list (foo?revision=2017-01-20)my-leaf-list because a leaf-list can have multiple " +
+                " in target leaf-list (bar?revision=2017-01-20)my-leaf-list because a leaf-list can have multiple " +
                 "default statements."));
         System.setOut(stdout);
     }
@@ -368,11 +388,13 @@ public class DeviationResolutionTest {
 
         System.setOut(new PrintStream(output, true, "UTF-8"));
 
-        StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-delete/foo-invalid.yang");
+        StmtTestUtils.parseYangSources(
+                sourceForResource("/deviation-resolution-test/deviation-delete/foo-invalid.yang"),
+                sourceForResource("/deviation-resolution-test/deviation-delete/bar-invalid.yang"));
 
         testLog = output.toString();
         assertTrue(testLog.contains("Deviation cannot delete substatement (urn:ietf:params:xml:ns:yang:yin:1)units " +
-                "with argument 'seconds' in target node (foo?revision=2017-01-20)my-leaf because it does not exist " +
+                "with argument 'seconds' in target node (bar?revision=2017-01-20)my-leaf because it does not exist " +
                 "in the target node."));
         System.setOut(stdout);
     }
@@ -380,7 +402,9 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidDeviateAddSubstatement() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-add/foo-invalid-3.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/deviation-add/foo-invalid-3.yang"),
+                    sourceForResource("/deviation-resolution-test/deviation-add/bar-invalid-3.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
@@ -392,7 +416,9 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidDeviateReplaceSubstatement() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-replace/foo-invalid-3.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/deviation-replace/foo-invalid-3.yang"),
+                    sourceForResource("/deviation-resolution-test/deviation-replace/bar-invalid-3.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
@@ -404,7 +430,9 @@ public class DeviationResolutionTest {
     @Test
     public void shouldFailOnInvalidDeviateDeleteSubstatement() throws Exception {
         try {
-            StmtTestUtils.parseYangSource("/deviation-resolution-test/deviation-delete/foo-invalid-2.yang");
+            StmtTestUtils.parseYangSources(
+                    sourceForResource("/deviation-resolution-test/deviation-delete/foo-invalid-2.yang"),
+                    sourceForResource("/deviation-resolution-test/deviation-delete/bar-invalid-2.yang"));
             fail("An exception should have been thrown.");
         } catch (final ReactorException ex) {
             final Throwable cause = ex.getCause();
index a7f9658595508362108b508268ff40e0dffb7a9a..7adc4f9595fefc7398cb56011a708ec472b3fab6 100644 (file)
@@ -34,12 +34,14 @@ import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline
 public class DeviationStmtTest {
 
     private static final StatementStreamSource FOO_MODULE = sourceForResource("/deviation-stmt-test/foo.yang");
+    private static final StatementStreamSource FOO_IMP_MODULE = sourceForResource("/deviation-stmt-test/foo-imp.yang");
     private static final StatementStreamSource BAR_MODULE = sourceForResource("/deviation-stmt-test/bar.yang");
+    private static final StatementStreamSource BAR_IMP_MODULE = sourceForResource("/deviation-stmt-test/bar-imp.yang");
 
     @Test
     public void testDeviationAndDeviate() throws ReactorException, ParseException {
         final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
-        reactor.addSources(FOO_MODULE, BAR_MODULE);
+        reactor.addSources(FOO_MODULE, FOO_IMP_MODULE, BAR_MODULE, BAR_IMP_MODULE);
 
         final SchemaContext schemaContext = reactor.buildEffective();
         assertNotNull(schemaContext);
index 0a6bcd876de85cad0c44e186e920687e7216bde2..0891fcc054e9dbc06d7b56a75d92276a168339c4 100644 (file)
@@ -119,7 +119,10 @@ public class EffectiveModuleTest {
         assertEquals(1, deviations.size());
         final Deviation deviationStmt = deviations.iterator().next();
         assertNotNull(deviationStmt);
-        assertEquals(contSchemaPath, deviationStmt.getTargetPath());
+        final QNameModule importedModuleQName = QNameModule.create(URI.create("imported"), revision);
+        final QName importedContQName = QName.create(importedModuleQName, "cont");
+        final SchemaPath importedContSchemaPath = SchemaPath.create(true, importedContQName);
+        assertEquals(importedContSchemaPath, deviationStmt.getTargetPath());
         assertEquals(DeviateKind.ADD, deviationStmt.getDeviates().iterator().next().getDeviateType());
         assertEquals("deviate reference", deviationStmt.getReference());
 
index ea7983c08d336916f8b26dcf07c3b95eeb57a9f9..49b3cf6ee107075ebba56a8ce19430771b9ffe48 100644 (file)
@@ -14,7 +14,6 @@ import static org.junit.Assert.assertNull;
 import static org.opendaylight.yangtools.yang.stmt.StmtTestUtils.sourceForResource;
 
 import com.google.common.collect.ImmutableSet;
-import java.util.Optional;
 import java.util.Set;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -41,9 +40,9 @@ public class IfFeatureResolutionTest {
                 QName.create("foo-namespace", "1970-01-01", "test-feature-3"),
                 QName.create("bar-namespace", "1970-01-01", "imp-feature"));
 
-        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(
-            Optional.of(supportedFeatures));
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
         reactor.addSources(FOO_MODULE, BAR_MODULE);
+        reactor.setSupportedFeatures(supportedFeatures);
 
         final SchemaContext schemaContext = reactor.buildEffective();
         assertNotNull(schemaContext);
@@ -275,9 +274,9 @@ public class IfFeatureResolutionTest {
 
     @Test
     public void testNoFeaturesSupported() throws ReactorException {
-        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(
-            Optional.of(ImmutableSet.of()));
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
         reactor.addSources(FOO_MODULE, BAR_MODULE);
+        reactor.setSupportedFeatures(ImmutableSet.of());
 
         final SchemaContext schemaContext = reactor.buildEffective();
         assertNotNull(schemaContext);
index c9dca5f8581acc3ec2498a297babf74d9c97f7b7..fe86a265d9bbb57bbbb5d742fc09cbb5cae2f5ea 100644 (file)
@@ -115,8 +115,11 @@ public class StmtTestUtils {
             final Set<QName> supportedFeatures, final Collection<? extends StatementStreamSource> sources)
             throws SourceException, ReactorException {
         final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild(
-            statementParserMode, supportedFeatures);
+            statementParserMode);
         reactor.addSources(sources);
+        if (supportedFeatures != null) {
+            reactor.setSupportedFeatures(supportedFeatures);
+        }
 
         return reactor.buildEffective();
     }
@@ -265,10 +268,12 @@ public class StmtTestUtils {
     private static SchemaContext parseYangSources(final StatementStreamSource[] yangSources,
             final StatementStreamSource[] libSources, final Set<QName> supportedFeatures) throws ReactorException {
 
-        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
-                .newBuild(supportedFeatures);
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
         reactor.addSources(yangSources);
         reactor.addLibSources(libSources);
+        if (supportedFeatures != null) {
+            reactor.setSupportedFeatures(supportedFeatures);
+        }
 
         return reactor.buildEffective();
     }
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug4933/correct/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug4933/correct/bar.yang
new file mode 100644 (file)
index 0000000..19746fc
--- /dev/null
@@ -0,0 +1,15 @@
+module bar {
+    namespace bar-ns;
+    prefix bar;
+
+    container my-container {
+        leaf-list my-leaf-list {
+            type string;
+            max-elements 5;
+            must "0 != 1";
+        }
+    }
+
+    container my-container2 {
+    }
+}
\ No newline at end of file
index 282e24245907c1c7bee722b002e2b6ae644fe6d2..0ae8d614522112a09f53629aabf0518e971dbfd4 100644 (file)
@@ -3,36 +3,29 @@ module foo {
     namespace "foo";
     prefix foo;
 
-    container my-container {
-        leaf-list my-leaf-list {
-            type string;
-            max-elements 5;
-            must "0 != 1";
-        }
+    import bar {
+        prefix bar;
     }
 
-    deviation /my-container/my-leaf-list {
+    deviation /bar:my-container/bar:my-leaf-list {
         deviate add {
             min-elements 1;
         }
     }
 
-    deviation /my-container/my-leaf-list {
+    deviation /bar:my-container/bar:my-leaf-list {
         deviate replace {
             max-elements 10;
         }
     }
 
-    deviation /my-container/my-leaf-list {
+    deviation /bar:my-container/bar:my-leaf-list {
         deviate delete {
             must "0 != 1";
         }
     }
 
-    container my-container2 {
-    }
-
-    deviation /my-container2 {
+    deviation /bar:my-container2 {
         deviate not-supported;
     }
 }
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug4933/incorrect/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug4933/incorrect/bar.yang
new file mode 100644 (file)
index 0000000..19746fc
--- /dev/null
@@ -0,0 +1,15 @@
+module bar {
+    namespace bar-ns;
+    prefix bar;
+
+    container my-container {
+        leaf-list my-leaf-list {
+            type string;
+            max-elements 5;
+            must "0 != 1";
+        }
+    }
+
+    container my-container2 {
+    }
+}
\ No newline at end of file
index 2993abd154d3b3e8b85a97ca59c8a078611d38ce..51ff1fe928e4fd7326902dba595dee5084e839e6 100644 (file)
@@ -3,36 +3,29 @@ module foo {
     namespace "foo";
     prefix foo;
 
-    container my-container {
-        leaf-list my-leaf-list {
-            type string;
-            max-elements 5;
-            must "0 != 1";
-        }
+    import bar {
+        prefix bar;
     }
 
-    deviation /my-container/my-leaf-list {
+    deviation /bar:my-container/bar:my-leaf-list {
         deviate add {
             min-elements 1;
         }
     }
 
-    deviation /my-container/my-leaf-list {
+    deviation /bar:my-container/bar:my-leaf-list {
         deviate replace {
             max-elements 10;
         }
     }
 
-    deviation /my-container/my-leaf-list {
+    deviation /bar:my-container/bar:my-leaf-list {
         deviate delete {
             must "0 != 1";
         }
     }
 
-    container my-container2 {
-    }
-
-    deviation /my-container2 {
+    deviation /bar:my-container2 {
         deviate not_supported;
     }
 }
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug7440/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug7440/bar.yang
new file mode 100644 (file)
index 0000000..883b4a7
--- /dev/null
@@ -0,0 +1,10 @@
+module bar {
+    namespace bar-ns;
+    prefix bar;
+
+    revision 2016-12-23;
+
+    leaf test-leaf {
+            type int32;
+        }
+}
\ No newline at end of file
index 3afa573d9db50333753507fbcae3e399d10f06aa..7ca75a1d60604142730be7b9bb4821143912c40b 100644 (file)
@@ -2,17 +2,18 @@ module foo {
     namespace foo-ns;
     prefix foo-prfx;
 
+    import bar {
+        prefix bar;
+        revision-date 2016-12-23;
+    }
+
     revision 2016-12-23;
 
-    deviation "/test-leaf" {
+    deviation "/bar:test-leaf" {
         deviate replace {
             type uint32 {
                 range "5..50";
             }
         }
     }
-
-    leaf test-leaf {
-        type int32;
-    }
 }
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug8307/bar-invalid.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug8307/bar-invalid.yang
new file mode 100644 (file)
index 0000000..d49ab16
--- /dev/null
@@ -0,0 +1,19 @@
+module bar {
+    namespace bar-ns;
+    prefix bar;
+
+    import baz {
+        prefix baz;
+        revision-date 2017-05-16;
+    }
+
+    revision 2017-05-16;
+
+    deviation "/baz:my-baz-cont/bar:my-aug-cont" {
+        deviate not-supported;
+    }
+
+    augment "/baz:my-baz-cont" {
+        container my-aug-cont {}
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug8307/bar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug8307/bar.yang
new file mode 100644 (file)
index 0000000..46e15df
--- /dev/null
@@ -0,0 +1,19 @@
+module bar {
+    namespace bar-ns;
+    prefix bar-prefix;
+
+    import foo {
+        prefix foo;
+        revision-date 2017-05-16;
+    }
+
+    revision 2017-05-16;
+
+    deviation "/foo:my-foo-cont-a" {
+        deviate not-supported;
+    }
+
+    container my-bar-cont-a {}
+
+    container my-bar-cont-b {}
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug8307/baz-invalid.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug8307/baz-invalid.yang
new file mode 100644 (file)
index 0000000..39d1cfe
--- /dev/null
@@ -0,0 +1,8 @@
+module baz {
+    namespace baz-ns;
+    prefix baz;
+
+    revision 2017-05-16;
+
+    container my-baz-cont {}
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug8307/baz.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug8307/baz.yang
new file mode 100644 (file)
index 0000000..05df3ad
--- /dev/null
@@ -0,0 +1,26 @@
+module baz {
+    namespace baz-ns;
+    prefix baz-prefix;
+
+    import foo {
+        prefix foo;
+        revision-date 2017-05-16;
+    }
+
+    import bar {
+        prefix bar;
+        revision-date 2017-05-16;
+    }
+
+    revision 2017-05-16;
+
+    deviation "/foo:my-foo-cont-b" {
+        deviate not-supported;
+    }
+
+    deviation "/bar:my-bar-cont-a" {
+        deviate not-supported;
+    }
+
+    container my-baz-cont {}
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug8307/foo-invalid.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug8307/foo-invalid.yang
new file mode 100644 (file)
index 0000000..b1cad54
--- /dev/null
@@ -0,0 +1,12 @@
+module foo {
+    namespace foo-ns;
+    prefix foo;
+
+    revision 2017-05-16;
+
+    deviation "/my-foo-cont" {
+        deviate not-supported;
+    }
+
+    container my-foo-cont {}
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug8307/foo.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug8307/foo.yang
new file mode 100644 (file)
index 0000000..4027fee
--- /dev/null
@@ -0,0 +1,12 @@
+module foo {
+    namespace foo-ns;
+    prefix foo-prefix;
+
+    revision 2017-05-16;
+
+    container my-foo-cont-a {}
+
+    container my-foo-cont-b {}
+
+    container my-foo-cont-c {}
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/bugs/bug8307/foobar.yang b/yang/yang-parser-impl/src/test/resources/bugs/bug8307/foobar.yang
new file mode 100644 (file)
index 0000000..97d4478
--- /dev/null
@@ -0,0 +1,24 @@
+module foobar {
+    namespace foobar-ns;
+    prefix foobar-prefix;
+
+    import foo {
+        prefix foo;
+        revision-date 2017-05-16;
+    }
+
+    import bar {
+        prefix bar;
+        revision-date 2017-05-16;
+    }
+
+    revision 2017-05-16;
+
+    deviation "/foo:my-foo-cont-c" {
+        deviate not-supported;
+    }
+
+    deviation "/bar:my-bar-cont-b" {
+        deviate not-supported;
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/bar.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/bar.yang
new file mode 100644 (file)
index 0000000..76e70f6
--- /dev/null
@@ -0,0 +1,10 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    container my-cont {
+
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid-2.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid-2.yang
new file mode 100644 (file)
index 0000000..dc93a72
--- /dev/null
@@ -0,0 +1,11 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    leaf my-leaf {
+        type int32;
+        default 100;
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid-3.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid-3.yang
new file mode 100644 (file)
index 0000000..2b0ec52
--- /dev/null
@@ -0,0 +1,10 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    leaf my-leaf {
+        type int32;
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid-4.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid-4.yang
new file mode 100644 (file)
index 0000000..98bd9f9
--- /dev/null
@@ -0,0 +1,20 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-02-01;
+
+    container my-cont {
+        uses my-grouping {
+            refine my-used-leaf {
+                default "def-val-added-by-refine";
+            }
+        }
+    }
+
+    grouping my-grouping {
+        leaf my-used-leaf {
+            type int32;
+        }
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar-invalid.yang
new file mode 100644 (file)
index 0000000..b3a2fa1
--- /dev/null
@@ -0,0 +1,11 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    leaf my-leaf {
+        type int32;
+        config false;
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar.yang
new file mode 100644 (file)
index 0000000..d04bc8b
--- /dev/null
@@ -0,0 +1,74 @@
+module bar {
+    namespace bar;
+    prefix bar;
+    yang-version 1.1;
+
+    revision 2017-01-20;
+
+    leaf-list my-leaf-list {
+        type int32;
+        default 50;
+    }
+
+    list my-list {
+        key key-leaf;
+
+        leaf key-leaf {
+            type string;
+        }
+
+        leaf my-leaf-a {
+            type string;
+        }
+
+        leaf my-leaf-b {
+            type string;
+        }
+
+        leaf my-leaf-c {
+            type string;
+        }
+
+        leaf my-leaf-d {
+            type string;
+        }
+    }
+
+    choice my-choice {
+        case c1 {
+            leaf c1-leaf {
+                type string;
+                default "heaven";
+            }
+        }
+
+        case c2 {
+            leaf c2-leaf {
+                type string;
+                default "hell";
+            }
+        }
+    }
+
+    rpc my-rpc {
+        input {
+            leaf my-rpc-input-leaf {
+                type string;
+            }
+        }
+
+        output {
+            leaf my-rpc-output-leaf {
+                type string;
+            }
+        }
+    }
+
+    notification my-notification {
+
+    }
+
+    anyxml my-anyxml {
+
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar10-invalid.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-add/bar10-invalid.yang
new file mode 100644 (file)
index 0000000..9892f6a
--- /dev/null
@@ -0,0 +1,10 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    leaf-list my-leaf-list {
+        type int32;
+    }
+}
\ No newline at end of file
index 4c04bedf69817019c6770961131161d6cca122de..2efe0f1840dffd1e9da32cf6aeac3270234b2121 100644 (file)
@@ -2,16 +2,16 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf" {
+    deviation "/bar:my-leaf" {
         deviate add {
             default 200;
         }
     }
-
-    leaf my-leaf {
-        type int32;
-        default 100;
-    }
 }
\ No newline at end of file
index 325d1393cbbc05e3b3647840d90ab4be00a05935..219614ad6fa23aabe8656d1d268b0225d486f58a 100644 (file)
@@ -2,15 +2,16 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf" {
+    deviation "/bar:my-leaf" {
         deviate add {
             type string;
         }
     }
-
-    leaf my-leaf {
-        type int32;
-    }
 }
\ No newline at end of file
index b48742aa16647045e80f7b82a2d3596bcc72cb11..2070d7718a5b0c57ec197fb4c9bd9c2f648fd7ac 100644 (file)
@@ -2,25 +2,16 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-02-01;
+    }
+
     revision 2017-02-01;
 
-    deviation "/my-cont/my-used-leaf" {
+    deviation "/bar:my-cont/bar:my-used-leaf" {
         deviate add {
             default 50;
         }
     }
-
-    container my-cont {
-        uses my-grouping {
-            refine my-used-leaf {
-                default "def-val-added-by-refine";
-            }
-        }
-    }
-
-    grouping my-grouping {
-        leaf my-used-leaf {
-            type int32;
-        }
-    }
 }
\ No newline at end of file
index 771c698d835b5744696fb08053dd228d25f9255d..1916b6e337113b2033eebcb3144fcc7cabeddd0f 100644 (file)
@@ -2,16 +2,16 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf" {
+    deviation "/bar:my-leaf" {
         deviate add {
             config true;
         }
     }
-
-    leaf my-leaf {
-        type int32;
-        config false;
-    }
 }
\ No newline at end of file
index af0d925629ee6f9d3c1b7839d9e95d254acd8919..c1edf965f39f0b4f233abe27c694f4db7a22f139 100644 (file)
@@ -3,9 +3,14 @@ module foo {
     prefix foo;
     yang-version 1.1;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf-list" {
+    deviation "/bar:my-leaf-list" {
         deviate add {
             config false;
             min-elements 5;
@@ -16,41 +21,41 @@ module foo {
         }
     }
 
-    deviation "/my-list" {
+    deviation "/bar:my-list" {
         deviate add {
             unique "my-leaf-a my-leaf-b";
             unique "my-leaf-c my-leaf-d";
         }
     }
 
-    deviation "/my-choice" {
+    deviation "/bar:my-choice" {
         deviate add {
             default c2;
         }
     }
 
-    deviation "/my-rpc/input" {
+    deviation "/bar:my-rpc/bar:input" {
         deviate add {
             must "day or night";
             must "black and white";
         }
     }
 
-    deviation "/my-rpc/output" {
+    deviation "/bar:my-rpc/bar:output" {
         deviate add {
             must "day or night";
             must "black and white";
         }
     }
 
-    deviation "/my-notification" {
+    deviation "/bar:my-notification" {
         deviate add {
             must "day or night";
             must "black and white";
         }
     }
 
-    deviation "/my-anyxml" {
+    deviation "/bar:my-anyxml" {
         deviate add {
             mandatory true;
             foo:custom-property "arg";
@@ -61,71 +66,4 @@ module foo {
     extension custom-property {
         argument name;
     }
-
-    leaf-list my-leaf-list {
-        type int32;
-        default 50;
-    }
-
-    list my-list {
-        key key-leaf;
-
-        leaf key-leaf {
-            type string;
-        }
-
-        leaf my-leaf-a {
-            type string;
-        }
-
-        leaf my-leaf-b {
-            type string;
-        }
-
-        leaf my-leaf-c {
-            type string;
-        }
-
-        leaf my-leaf-d {
-            type string;
-        }
-    }
-
-    choice my-choice {
-        case c1 {
-            leaf c1-leaf {
-                type string;
-                default "heaven";
-            }
-        }
-
-        case c2 {
-            leaf c2-leaf {
-                type string;
-                default "hell";
-            }
-        }
-    }
-
-    rpc my-rpc {
-        input {
-            leaf my-rpc-input-leaf {
-                type string;
-            }
-        }
-
-        output {
-            leaf my-rpc-output-leaf {
-                type string;
-            }
-        }
-    }
-
-    notification my-notification {
-
-    }
-
-    anyxml my-anyxml {
-
-    }
 }
\ No newline at end of file
index 6f636a7b3d6e7e32eb9702f6fe7d08eb0d10a0b5..410f5b615de0e6e61f5a7bbb1af220745015256a 100644 (file)
@@ -2,16 +2,17 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf-list" {
+    deviation "/bar:my-leaf-list" {
         deviate add {
             default 10;
             default 100;
         }
     }
-
-    leaf-list my-leaf-list {
-        type int32;
-    }
 }
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar-invalid-2.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar-invalid-2.yang
new file mode 100644 (file)
index 0000000..b3a2fa1
--- /dev/null
@@ -0,0 +1,11 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    leaf my-leaf {
+        type int32;
+        config false;
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar-invalid.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar-invalid.yang
new file mode 100644 (file)
index 0000000..2b0ec52
--- /dev/null
@@ -0,0 +1,10 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    leaf my-leaf {
+        type int32;
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar.yang
new file mode 100644 (file)
index 0000000..c66768d
--- /dev/null
@@ -0,0 +1,84 @@
+module bar {
+    namespace bar;
+    prefix bar;
+    yang-version 1.1;
+
+    revision 2017-01-20;
+
+    leaf my-leaf {
+        type int32;
+        units seconds;
+        default 100;
+        bar:custom-property-without-arg;
+    }
+
+    leaf-list my-leaf-list {
+        type string;
+        default "def-val-1";
+        default "def-val-2";
+        must "a = 1 or b = 2";
+        must "x != y";
+    }
+
+    list my-list {
+        key key-leaf;
+
+        unique "my-leaf-a my-leaf-b";
+        unique "my-leaf-c my-leaf-d";
+        bar:custom-property "arg";
+        bar:custom-property "another arg";
+
+        leaf key-leaf {
+            type string;
+        }
+
+        leaf my-leaf-a {
+            type string;
+        }
+
+        leaf my-leaf-b {
+            type string;
+        }
+
+        leaf my-leaf-c {
+            type string;
+        }
+
+        leaf my-leaf-d {
+            type string;
+        }
+    }
+
+    container my-cont {
+        uses my-grouping {
+            refine my-used-leaf {
+                default "def-val-added-by-refine";
+                bar:custom-property-without-arg;
+            }
+        }
+    }
+
+    augment "/my-cont" {
+        leaf my-aug-leaf {
+            type int32;
+            default "def-val";
+            units "minutes";
+            must "x = 1";
+            bar:custom-property-without-arg;
+        }
+    }
+
+    grouping my-grouping {
+        leaf my-used-leaf {
+            type int32;
+            units "days";
+            must "y = 5";
+        }
+    }
+
+    extension custom-property {
+        argument name;
+    }
+
+    extension custom-property-without-arg;
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar10-invalid.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-delete/bar10-invalid.yang
new file mode 100644 (file)
index 0000000..9892f6a
--- /dev/null
@@ -0,0 +1,10 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    leaf-list my-leaf-list {
+        type int32;
+    }
+}
\ No newline at end of file
index d0d3f95f84cfda84d4e5c70b88ef44162db2264b..4c4a55532782956f9b397666c66f211070467700 100644 (file)
@@ -2,6 +2,11 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
     deviation "/my-leaf" {
@@ -9,9 +14,4 @@ module foo {
             config false;
         }
     }
-
-    leaf my-leaf {
-        type int32;
-        config false;
-    }
 }
\ No newline at end of file
index 8cfbd63200ea890f5db0c1b28f156f0b03171ced..87b127229fb360e5dd72c4a1d12af5b48f52862a 100644 (file)
@@ -2,15 +2,16 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf" {
+    deviation "/bar:my-leaf" {
         deviate delete {
             units "seconds";
         }
     }
-
-    leaf my-leaf {
-        type int32;
-    }
 }
\ No newline at end of file
index f001ac6b37f9793142a08129ceb9651182a5feb6..57abb1f9cd7914df6820343590166e85c312ec1e 100644 (file)
@@ -3,17 +3,22 @@ module foo {
     prefix foo;
     yang-version 1.1;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf" {
+    deviation "/bar:my-leaf" {
         deviate delete {
             units seconds;
             default 100;
-            foo:custom-property-without-arg;
+            bar:custom-property-without-arg;
         }
     }
 
-    deviation "/my-leaf-list" {
+    deviation "/bar:my-leaf-list" {
         deviate delete {
             default "def-val-1";
             default "def-val-2";
@@ -22,105 +27,28 @@ module foo {
         }
     }
 
-    deviation "/my-list" {
+    deviation "/bar:my-list" {
         deviate delete {
             unique "my-leaf-a my-leaf-b";
             unique "my-leaf-c my-leaf-d";
-            foo:custom-property "arg";
-            foo:custom-property "another arg";
-        }
-    }
-
-    extension custom-property {
-        argument name;
-    }
-
-    extension custom-property-without-arg;
-
-    leaf my-leaf {
-        type int32;
-        units seconds;
-        default 100;
-        foo:custom-property-without-arg;
-    }
-
-    leaf-list my-leaf-list {
-        type string;
-        default "def-val-1";
-        default "def-val-2";
-        must "a = 1 or b = 2";
-        must "x != y";
-    }
-
-    list my-list {
-        key key-leaf;
-
-        unique "my-leaf-a my-leaf-b";
-        unique "my-leaf-c my-leaf-d";
-        foo:custom-property "arg";
-        foo:custom-property "another arg";
-
-        leaf key-leaf {
-            type string;
-        }
-
-        leaf my-leaf-a {
-            type string;
-        }
-
-        leaf my-leaf-b {
-            type string;
-        }
-
-        leaf my-leaf-c {
-            type string;
-        }
-
-        leaf my-leaf-d {
-            type string;
-        }
-    }
-
-    container my-cont {
-        uses my-grouping {
-            refine my-used-leaf {
-                default "def-val-added-by-refine";
-                foo:custom-property-without-arg;
-            }
-        }
-    }
-
-    augment "/my-cont" {
-        leaf my-aug-leaf {
-            type int32;
-            default "def-val";
-            units "minutes";
-            must "x = 1";
-            foo:custom-property-without-arg;
+            bar:custom-property "arg";
+            bar:custom-property "another arg";
         }
     }
 
-    deviation "/my-cont/my-aug-leaf" {
+    deviation "/bar:my-cont/bar:my-aug-leaf" {
         deviate delete {
             default "def-val";
             units "minutes";
             must "x = 1";
-            foo:custom-property-without-arg;
-        }
-    }
-
-    grouping my-grouping {
-        leaf my-used-leaf {
-            type int32;
-            units "days";
-            must "y = 5";
+            bar:custom-property-without-arg;
         }
     }
 
-    deviation "/my-cont/my-used-leaf" {
+    deviation "/bar:my-cont/bar:my-used-leaf" {
         deviate delete {
             default "def-val-added-by-refine";
-            foo:custom-property-without-arg;
+            bar:custom-property-without-arg;
             units "days";
             must "y = 5";
         }
index a54f21c17c665eb51ae3aac5d164de1f7d6c8900..b5f76dcddd3a4a1fa3a5e773371f937c536d1bdb 100644 (file)
@@ -2,16 +2,17 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf-list" {
+    deviation "/bar:my-leaf-list" {
         deviate delete {
             default 10;
             default 100;
         }
     }
-
-    leaf-list my-leaf-list {
-        type int32;
-    }
 }
\ No newline at end of file
index 162d0002d052e001e444c88037a904a0608d9b73..559fec247ea95ac23e469c43b52defaf2a4703d4 100644 (file)
@@ -4,6 +4,34 @@ module imported {
 
     revision 2017-01-20;
 
+    container my-cont-a {
+        leaf my-leaf-a1 {
+            type int8;
+        }
+
+        leaf my-leaf-a2 {
+            type int16;
+        }
+
+        leaf my-leaf-a3 {
+            type int32;
+        }
+    }
+
+    container my-cont-b {
+        leaf my-leaf-b1 {
+            type int8;
+        }
+
+        leaf my-leaf-b2 {
+            type int16;
+        }
+
+        leaf my-leaf-b3 {
+            type int32;
+        }
+    }
+
     container my-cont-c {
         leaf my-leaf-c1 {
             type int8;
index 6e448640a0971b8b9e8b791070659b3c0152d7ac..6a19cbc59654c40938b073854496d16946c75cc7 100644 (file)
@@ -9,47 +9,19 @@ module root {
 
     revision 2017-01-20;
 
-    deviation "/my-cont-a/my-leaf-a1" {
+    deviation "/imp:my-cont-a/imp:my-leaf-a1" {
         deviate not-supported;
     }
 
-    deviation "/my-cont-a/my-leaf-a2" {
+    deviation "/imp:my-cont-a/imp:my-leaf-a2" {
         deviate not-supported;
     }
 
-    deviation "/my-cont-b" {
+    deviation "/imp:my-cont-b" {
         deviate not-supported;
     }
 
     deviation "/imp:my-cont-c/imp:my-leaf-c3" {
         deviate not-supported;
     }
-
-    container my-cont-a {
-        leaf my-leaf-a1 {
-            type int8;
-        }
-
-        leaf my-leaf-a2 {
-            type int16;
-        }
-
-        leaf my-leaf-a3 {
-            type int32;
-        }
-    }
-
-    container my-cont-b {
-        leaf my-leaf-b1 {
-            type int8;
-        }
-
-        leaf my-leaf-b2 {
-            type int16;
-        }
-
-        leaf my-leaf-b3 {
-            type int32;
-        }
-    }
 }
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar-invalid-2.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar-invalid-2.yang
new file mode 100644 (file)
index 0000000..290267a
--- /dev/null
@@ -0,0 +1,13 @@
+module bar {
+    namespace bar;
+    prefix bar;
+    yang-version 1.1;
+
+    revision 2017-01-20;
+
+    leaf-list my-leaf-list {
+        type string;
+        default "default value one";
+        default "default value two";
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar-invalid-3.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar-invalid-3.yang
new file mode 100644 (file)
index 0000000..0e4f1fe
--- /dev/null
@@ -0,0 +1,11 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    leaf my-leaf {
+        type int32;
+        must "a != b";
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar-invalid.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar-invalid.yang
new file mode 100644 (file)
index 0000000..2b0ec52
--- /dev/null
@@ -0,0 +1,10 @@
+module bar {
+    namespace bar;
+    prefix bar;
+
+    revision 2017-01-20;
+
+    leaf my-leaf {
+        type int32;
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar.yang b/yang/yang-parser-impl/src/test/resources/deviation-resolution-test/deviation-replace/bar.yang
new file mode 100644 (file)
index 0000000..24a5e42
--- /dev/null
@@ -0,0 +1,65 @@
+module bar {
+    namespace bar;
+    prefix bar;
+    yang-version 1.1;
+
+    revision 2017-01-20;
+
+    leaf my-leaf {
+        type int32;
+        default 100;
+        units kilobytes;
+    }
+
+    leaf-list my-leaf-list-test {
+        type string;
+        min-elements 5;
+        max-elements 10;
+        config false;
+    }
+
+    choice my-choice {
+        mandatory true;
+        bar:custom-property "original arg";
+        case c1 {
+            leaf c1-leaf {
+                type string;
+            }
+        }
+
+        case c2 {
+            leaf c2-leaf {
+                type string;
+            }
+        }
+    }
+
+    augment "/my-cont" {
+        leaf my-aug-leaf {
+            type int32;
+            default "def-val";
+            units "minutes";
+            bar:custom-property "arg";
+        }
+    }
+
+    container my-cont {
+        uses my-grouping {
+            refine my-used-leaf {
+                default "def-val-added-by-refine";
+                bar:custom-property "arg";
+            }
+        }
+    }
+
+    grouping my-grouping {
+        leaf my-used-leaf {
+            type int32;
+            units "days";
+        }
+    }
+
+    extension custom-property {
+        argument name;
+    }
+}
\ No newline at end of file
index 98fe768c31a39b37c97575dace2359cf788431f9..9ebf435350750c71343ac2e5164c643a311a0d86 100644 (file)
@@ -3,17 +3,16 @@ module foo {
     prefix foo;
     yang-version 1.1;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf-list" {
+    deviation "/bar:my-leaf-list" {
         deviate replace {
             default "new default value";
         }
     }
-
-    leaf-list my-leaf-list {
-        type string;
-        default "default value one";
-        default "default value two";
-    }
 }
\ No newline at end of file
index 7829568f783ebc55fd756bc39a051fe99d08b925..f3a9ab742bd16895c58be0105ba4e599109d558d 100644 (file)
@@ -2,16 +2,16 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf" {
+    deviation "/bar:my-leaf" {
         deviate replace {
             must "a != b";
         }
     }
-
-    leaf my-leaf {
-        type int32;
-        must "a != b";
-    }
 }
\ No newline at end of file
index 43004cf105da6f77b85ba2d7ef2a35f28c8fd71a..04f110c861509f1fd2a0f8553305332f7dcd45e8 100644 (file)
@@ -2,15 +2,16 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf" {
+    deviation "/bar:my-leaf" {
         deviate replace {
             units "seconds";
         }
     }
-
-    leaf my-leaf {
-        type int32;
-    }
 }
\ No newline at end of file
index af866f4563d6f3b6a59b96bc5ab541bb7758aa19..5375af4d3bc917f523b471a877e580ad4eefc275 100644 (file)
@@ -2,9 +2,14 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-leaf" {
+    deviation "/bar:my-leaf" {
         deviate replace {
             type uint32;
             default 10;
@@ -12,7 +17,7 @@ module foo {
         }
     }
 
-    deviation "/my-leaf-list-test" {
+    deviation "/bar:my-leaf-list-test" {
         deviate replace {
             min-elements 3;
             max-elements 6;
@@ -20,85 +25,27 @@ module foo {
         }
     }
 
-    deviation "/my-choice" {
+    deviation "/bar:my-choice" {
         deviate replace {
             mandatory false;
-            foo:custom-property "new arg";
-        }
-    }
-
-    extension custom-property {
-        argument name;
-    }
-
-    leaf my-leaf {
-        type int32;
-        default 100;
-        units kilobytes;
-    }
-
-    leaf-list my-leaf-list-test {
-        type string;
-        min-elements 5;
-        max-elements 10;
-        config false;
-    }
-
-    choice my-choice {
-        mandatory true;
-        foo:custom-property "original arg";
-        case c1 {
-            leaf c1-leaf {
-                type string;
-            }
-        }
-
-        case c2 {
-            leaf c2-leaf {
-                type string;
-            }
-        }
-    }
-
-    container my-cont {
-        uses my-grouping {
-            refine my-used-leaf {
-                default "def-val-added-by-refine";
-                foo:custom-property "arg";
-            }
+            bar:custom-property "new arg";
         }
     }
 
-    augment "/my-cont" {
-        leaf my-aug-leaf {
-            type int32;
-            default "def-val";
-            units "minutes";
-            foo:custom-property "arg";
-        }
-    }
-
-    deviation "/my-cont/my-aug-leaf" {
+    deviation "/bar:my-cont/bar:my-aug-leaf" {
         deviate replace {
             type uint32;
             default "new-def-val";
             units "seconds";
-            foo:custom-property "new arg";
-        }
-    }
-
-    grouping my-grouping {
-        leaf my-used-leaf {
-            type int32;
-            units "days";
+            bar:custom-property "new arg";
         }
     }
 
-    deviation "/my-cont/my-used-leaf" {
+    deviation "/bar:my-cont/bar:my-used-leaf" {
         deviate replace {
             type uint32;
             default "new-def-val";
-            foo:custom-property "new arg";
+            bar:custom-property "new arg";
             units "weeks";
         }
     }
index c0684413da78ac5cf23ec83531ca695d205eaa31..21ef9590426253d38260bb353864fea2cb3e5fd7 100644 (file)
@@ -2,9 +2,14 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/invalid/path" {
+    deviation "/bar:invalid/bar:path" {
         deviate not-supported;
     }
 
index 2cbbab76f45b8f17bb214b4ebb61e799a147ca45..96180581a3f56af15aabc197a181ba13f10c0bf4 100644 (file)
@@ -2,15 +2,16 @@ module foo {
     namespace foo;
     prefix foo;
 
+    import bar {
+        prefix bar;
+        revision-date 2017-01-20;
+    }
+
     revision 2017-01-20;
 
-    deviation "/my-cont" {
+    deviation "/bar:my-cont" {
         deviate add {
             max-elements 5;
         }
     }
-
-    container my-cont {
-
-    }
 }
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-stmt-test/bar-imp.yang b/yang/yang-parser-impl/src/test/resources/deviation-stmt-test/bar-imp.yang
new file mode 100644 (file)
index 0000000..38652e0
--- /dev/null
@@ -0,0 +1,20 @@
+module bar-imp {
+    namespace "bimp-ns";
+    prefix "bimp";
+
+    revision 2016-09-22;
+
+    container bar-container-1 {
+        leaf bar-leaf-1 {
+            type string;
+        }
+    }
+
+    container bar-container-2 {
+        must "a = b";
+
+        leaf bar-leaf-2 {
+            type string;
+        }
+    }
+}
\ No newline at end of file
index 831895a78f705fc9caf8f6bb394c301ed01e0911..6b52bf33fef0d32d6932c7a8db47cf0c247e68f6 100644 (file)
@@ -2,68 +2,59 @@ module bar {
     namespace bar-namespace;
     prefix bar-prefix;
 
+    import bar-imp {
+        prefix bimp;
+        revision-date 2016-09-22;
+    }
+
     revision "2016-09-22";
 
-    deviation "/bar-container-1" {
+    deviation "/bimp:bar-container-1" {
         deviate add {
             must "a != b";
         }
         bar-prefix:bar-extension;
     }
 
-    deviation "/bar-container-2" {
+    deviation "/bimp:bar-container-2" {
         deviate delete {
             must "a = b";
         }
     }
 
-    deviation "/bar-container-2" {
+    deviation "/bimp:bar-container-2" {
         deviate add {
             config false;
         }
     }
 
-    deviation "/bar-container-1/bar-leaf-1" {
+    deviation "/bimp:bar-container-1/bimp:bar-leaf-1" {
         deviate add {
             default "def-val";
         }
         description "desc";
     }
 
-    deviation "/bar-container-1/bar-leaf-1" {
+    deviation "/bimp:bar-container-1/bimp:bar-leaf-1" {
         deviate add {
             config false;
         }
         description "another desc";
     }
 
-    deviation "/bar-container-2/bar-leaf-2" {
+    deviation "/bimp:bar-container-2/bimp:bar-leaf-2" {
         deviate add {
             default "def-val";
         }
         reference "ref";
     }
 
-    deviation "/bar-container-2/bar-leaf-2" {
+    deviation "/bimp:bar-container-2/bimp:bar-leaf-2" {
         deviate add {
             config false;
         }
         reference "another ref";
     }
 
-    container bar-container-1 {
-        leaf bar-leaf-1 {
-            type string;
-        }
-    }
-
-    container bar-container-2 {
-        must "a = b";
-
-        leaf bar-leaf-2 {
-            type string;
-        }
-    }
-
     extension bar-extension {}
 }
\ No newline at end of file
diff --git a/yang/yang-parser-impl/src/test/resources/deviation-stmt-test/foo-imp.yang b/yang/yang-parser-impl/src/test/resources/deviation-stmt-test/foo-imp.yang
new file mode 100644 (file)
index 0000000..0164671
--- /dev/null
@@ -0,0 +1,50 @@
+module foo-imp {
+    namespace "fimp-ns";
+    prefix "fimp";
+
+    revision 2016-06-23;
+
+    container test-container {
+        leaf test-leaf {
+            type string;
+        }
+
+        leaf test-leaf-2 {
+            type string;
+        }
+
+        leaf-list test-leaf-list {
+            type int32;
+            min-elements 3;
+            must "daytime or time";
+            must "time or daytime";
+            units minutes;
+        }
+
+        list test-list {
+            key key-leaf;
+            unique "list-leaf-1 list-leaf-2";
+            unique "list-leaf-3 list-leaf-4";
+
+            leaf key-leaf {
+                type string;
+            }
+
+            leaf list-leaf-1 {
+                type string;
+            }
+
+            leaf list-leaf-2 {
+                type string;
+            }
+
+            leaf list-leaf-3 {
+                type string;
+            }
+
+            leaf list-leaf-4 {
+                type string;
+            }
+        }
+    }
+}
\ No newline at end of file
index 2102b9e09ecbe3fd0e3440129743f89493b954a5..bb456735b4629691f202046748b971778bee4cae 100644 (file)
@@ -2,16 +2,21 @@ module foo {
     namespace "foo-namespace";
     prefix "foo-prefix";
 
+    import foo-imp {
+        prefix fimp;
+        revision-date 2016-06-23;
+    }
+
     revision "2016-06-23" {
         description "Initial revision";
     }
 
-    deviation "/test-container/test-leaf" {
+    deviation "/fimp:test-container/fimp:test-leaf" {
         description "test-leaf is not supported";
         deviate not-supported;
     }
 
-    deviation "/test-container/test-leaf-2" {
+    deviation "/fimp:test-container/fimp:test-leaf-2" {
         deviate add {
             default "added-def-val";
             config false;
@@ -19,7 +24,7 @@ module foo {
         }
     }
 
-    deviation "/test-container/test-leaf-list" {
+    deviation "/fimp:test-container/fimp:test-leaf-list" {
         deviate add {
             max-elements 12;
         }
@@ -36,54 +41,10 @@ module foo {
         }
     }
 
-    deviation "/test-container/test-list" {
+    deviation "/fimp:test-container/fimp:test-list" {
         deviate delete {
             unique "list-leaf-1 list-leaf-2";
             unique "list-leaf-3 list-leaf-4";
         }
     }
-
-    container test-container {
-        leaf test-leaf {
-            type string;
-        }
-
-        leaf test-leaf-2 {
-            type string;
-        }
-
-        leaf-list test-leaf-list {
-            type int32;
-            min-elements 3;
-            must "daytime or time";
-            must "time or daytime";
-            units minutes;
-        }
-
-        list test-list {
-            key key-leaf;
-            unique "list-leaf-1 list-leaf-2";
-            unique "list-leaf-3 list-leaf-4";
-
-            leaf key-leaf {
-                type string;
-            }
-
-            leaf list-leaf-1 {
-                type string;
-            }
-
-            leaf list-leaf-2 {
-                type string;
-            }
-
-            leaf list-leaf-3 {
-                type string;
-            }
-
-            leaf list-leaf-4 {
-                type string;
-            }
-        }
-    }
 }
\ No newline at end of file
index 51ce0c5e0f898e7b2b5df8a856ce24637b0796ee..63a76d280d7014d3b7aa02229ff8efe9d5f134e6 100644 (file)
@@ -36,7 +36,7 @@ module root {
     rpc rpc1 {
     }
 
-    deviation /cont {
+    deviation /imp-pref:cont {
         deviate add {
         }
         reference "deviate reference";
index a3d3d656041cddeafc28736306f30f1b42829a93..5b1e3b40388bfd871319dcce6a796693276d2b48 100644 (file)
@@ -70,11 +70,14 @@ class SystemTestUtils {
             final StatementStreamSource[] libSources, final Set<QName> supportedFeatures) throws ReactorException {
         Preconditions.checkArgument(testSources != null && testSources.length > 0, "No yang sources");
 
-        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
-                .newBuild(supportedFeatures);
+        final CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR.newBuild();
         reactor.addSources(testSources);
         reactor.addLibSources(libSources);
 
+        if (supportedFeatures != null) {
+            reactor.setSupportedFeatures(supportedFeatures);
+        }
+
         return reactor.buildEffective();
     }