2 * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.yangtools.yang.parser.repo;
10 import static org.junit.Assert.assertNotNull;
11 import static org.junit.Assert.assertNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
15 import com.google.common.collect.ImmutableSetMultimap;
16 import com.google.common.collect.SetMultimap;
17 import com.google.common.util.concurrent.ListenableFuture;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.concurrent.ExecutionException;
22 import org.junit.Test;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.common.QNameModule;
25 import org.opendaylight.yangtools.yang.common.Revision;
26 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
27 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
28 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
29 import org.opendaylight.yangtools.yang.model.repo.api.SchemaContextFactoryConfiguration;
30 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
31 import org.opendaylight.yangtools.yang.model.repo.api.YangTextSchemaSource;
32 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
33 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.ASTSchemaSource;
34 import org.opendaylight.yangtools.yang.parser.rfc7950.repo.TextToASTTransformer;
35 import org.opendaylight.yangtools.yang.parser.spi.meta.InferenceException;
37 public class SchemaContextFactoryDeviationsTest {
38 private static final String FOO = "/bug9195/foo.yang";
39 private static final String BAR = "/bug9195/bar.yang";
40 private static final String BAZ = "/bug9195/baz.yang";
41 private static final String FOOBAR = "/bug9195/foobar.yang";
42 private static final String BAR_INVALID = "/bug9195/bar-invalid.yang";
43 private static final String BAZ_INVALID = "/bug9195/baz-invalid.yang";
44 private static final URI FOO_NS = URI.create("foo-ns");
45 private static final URI BAR_NS = URI.create("bar-ns");
46 private static final URI BAZ_NS = URI.create("baz-ns");
47 private static final Revision REVISION = Revision.of("2017-05-16");
48 private static final QNameModule FOO_MODULE = QNameModule.create(FOO_NS, REVISION);
49 private static final QName MY_FOO_CONT_A = QName.create(FOO_MODULE, "my-foo-cont-a");
50 private static final QName MY_FOO_CONT_B = QName.create(FOO_MODULE, "my-foo-cont-b");
51 private static final QName MY_FOO_CONT_C = QName.create(FOO_MODULE, "my-foo-cont-c");
52 private static final QNameModule BAR_MODULE = QNameModule.create(BAR_NS, REVISION);
53 private static final QName MY_BAR_CONT_A = QName.create(BAR_MODULE, "my-bar-cont-a");
54 private static final QName MY_BAR_CONT_B = QName.create(BAR_MODULE, "my-bar-cont-b");
55 private static final QNameModule BAZ_MODULE = QNameModule.create(BAZ_NS, REVISION);
58 public void testDeviationsSupportedInSomeModules() throws Exception {
59 final SetMultimap<QNameModule, QNameModule> modulesWithSupportedDeviations =
60 ImmutableSetMultimap.<QNameModule, QNameModule>builder()
61 .put(FOO_MODULE, BAR_MODULE)
62 .put(FOO_MODULE, BAZ_MODULE)
63 .put(BAR_MODULE, BAZ_MODULE)
66 final ListenableFuture<EffectiveModelContext> lf = createSchemaContext(modulesWithSupportedDeviations, FOO, BAR,
68 assertTrue(lf.isDone());
69 final SchemaContext schemaContext = lf.get();
70 assertNotNull(schemaContext);
72 assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_FOO_CONT_A)));
73 assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_FOO_CONT_B)));
74 assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_FOO_CONT_C)));
75 assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_BAR_CONT_A)));
76 assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_BAR_CONT_B)));
80 public void testDeviationsSupportedInAllModules() throws Exception {
81 final ListenableFuture<EffectiveModelContext> lf = createSchemaContext(null, FOO, BAR, BAZ, FOOBAR);
82 assertTrue(lf.isDone());
83 final SchemaContext schemaContext = lf.get();
84 assertNotNull(schemaContext);
86 assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_FOO_CONT_A)));
87 assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_FOO_CONT_B)));
88 assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_FOO_CONT_C)));
89 assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_BAR_CONT_A)));
90 assertNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_BAR_CONT_B)));
94 public void testDeviationsSupportedInNoModule() throws Exception {
95 final ListenableFuture<EffectiveModelContext> lf = createSchemaContext(ImmutableSetMultimap.of(), FOO, BAR, BAZ,
97 assertTrue(lf.isDone());
98 final SchemaContext schemaContext = lf.get();
99 assertNotNull(schemaContext);
101 assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_FOO_CONT_A)));
102 assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_FOO_CONT_B)));
103 assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_FOO_CONT_C)));
104 assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_BAR_CONT_A)));
105 assertNotNull(SchemaContextUtil.findDataSchemaNode(schemaContext, SchemaPath.create(true, MY_BAR_CONT_B)));
109 public void shouldFailOnAttemptToDeviateTheSameModule2() throws Exception {
110 final ListenableFuture<EffectiveModelContext> lf = createSchemaContext(null, BAR_INVALID, BAZ_INVALID);
111 assertTrue(lf.isDone());
114 fail("Deviation that targets the same module as the one it is defined is forbidden.");
115 } catch (final ExecutionException ex) {
116 final Throwable cause = ex.getCause().getCause().getCause();
117 assertTrue(cause instanceof InferenceException);
118 assertTrue(cause.getMessage()
119 .startsWith("Deviation must not target the same module as the one it is defined in"));
123 private static SettableSchemaProvider<ASTSchemaSource> getImmediateYangSourceProviderFromResource(
124 final String resourceName) throws Exception {
125 final YangTextSchemaSource yangSource = YangTextSchemaSource.forResource(resourceName);
126 return SettableSchemaProvider.createImmediate(TextToASTTransformer.transformText(yangSource),
127 ASTSchemaSource.class);
130 private static ListenableFuture<EffectiveModelContext> createSchemaContext(
131 final SetMultimap<QNameModule, QNameModule> modulesWithSupportedDeviations, final String... resources)
133 final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository(
134 "shared-schema-repo-with-deviations-test");
136 final Collection<SourceIdentifier> requiredSources = new ArrayList<>();
137 for (final String resource : resources) {
138 final SettableSchemaProvider<ASTSchemaSource> yangSource = getImmediateYangSourceProviderFromResource(
140 yangSource.register(sharedSchemaRepository);
141 yangSource.setResult();
142 requiredSources.add(yangSource.getId());
145 final SchemaContextFactoryConfiguration config = SchemaContextFactoryConfiguration.builder()
146 .setModulesDeviatedByModules(modulesWithSupportedDeviations).build();
147 return sharedSchemaRepository.createEffectiveModelContextFactory(config).createEffectiveModelContext(