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>
--- /dev/null
+/*
+ * 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
+ }
+}
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;
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;
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;
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) {
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());
}
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;
*/
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;
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;
}
/**
- * 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}.
*/
}
/**
- * 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) {
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));
}
/**
}
}
+ /**
+ * 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
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;
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;
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);
});
}
+ 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()) {
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;
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 {
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;
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;
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
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;
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());
}
@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());
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());
--- /dev/null
+/*
+ * 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"));
+ }
+ }
+}
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;
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);
@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());
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());
@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);
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());
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());
@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());
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());
@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();
@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();
@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."));
}
}
@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."));
}
}
@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."));
}
}
@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."));
}
}
@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."));
}
}
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);
}
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);
}
@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();
@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();
@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();
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);
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());
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;
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);
@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);
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();
}
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();
}
--- /dev/null
+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
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;
}
}
--- /dev/null
+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
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;
}
}
--- /dev/null
+module bar {
+ namespace bar-ns;
+ prefix bar;
+
+ revision 2016-12-23;
+
+ leaf test-leaf {
+ type int32;
+ }
+}
\ No newline at end of file
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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+module baz {
+ namespace baz-ns;
+ prefix baz;
+
+ revision 2017-05-16;
+
+ container my-baz-cont {}
+}
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+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
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ container my-cont {
+
+ }
+}
\ No newline at end of file
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ leaf my-leaf {
+ type int32;
+ default 100;
+ }
+}
\ No newline at end of file
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ leaf my-leaf {
+ type int32;
+ }
+}
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ leaf my-leaf {
+ type int32;
+ config false;
+ }
+}
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ leaf-list my-leaf-list {
+ type int32;
+ }
+}
\ No newline at end of file
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
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
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
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
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;
}
}
- 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";
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
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
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ leaf my-leaf {
+ type int32;
+ config false;
+ }
+}
\ No newline at end of file
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ leaf my-leaf {
+ type int32;
+ }
+}
\ No newline at end of file
--- /dev/null
+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
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ leaf-list my-leaf-list {
+ type int32;
+ }
+}
\ No newline at end of file
namespace foo;
prefix foo;
+ import bar {
+ prefix bar;
+ revision-date 2017-01-20;
+ }
+
revision 2017-01-20;
deviation "/my-leaf" {
config false;
}
}
-
- leaf my-leaf {
- type int32;
- config false;
- }
}
\ No newline at end of file
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
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";
}
}
- 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";
}
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
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;
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
--- /dev/null
+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
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ leaf my-leaf {
+ type int32;
+ must "a != b";
+ }
+}
\ No newline at end of file
--- /dev/null
+module bar {
+ namespace bar;
+ prefix bar;
+
+ revision 2017-01-20;
+
+ leaf my-leaf {
+ type int32;
+ }
+}
\ No newline at end of file
--- /dev/null
+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
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
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
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
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;
}
}
- deviation "/my-leaf-list-test" {
+ deviation "/bar:my-leaf-list-test" {
deviate replace {
min-elements 3;
max-elements 6;
}
}
- 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";
}
}
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;
}
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
--- /dev/null
+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
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
--- /dev/null
+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
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;
}
}
- deviation "/test-container/test-leaf-list" {
+ deviation "/fimp:test-container/fimp:test-leaf-list" {
deviate add {
max-elements 12;
}
}
}
- 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
prefix imported;
revision "2000-01-01";
+
+ container cont {}
}
rpc rpc1 {
}
- deviation /cont {
+ deviation /imp-pref:cont {
deviate add {
}
reference "deviate reference";
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();
}