Merge branch 'master' of ../controller
[yangtools.git] / yang / yang-parser-impl / src / test / java / org / opendaylight / yangtools / yang / parser / repo / SchemaContextFactoryDeviationsTest.java
1 /*
2  * Copyright (c) 2017 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.yangtools.yang.parser.repo;
9
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;
14
15 import com.google.common.collect.ImmutableSetMultimap;
16 import com.google.common.collect.SetMultimap;
17 import com.google.common.util.concurrent.ListenableFuture;
18 import java.net.URI;
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;
36
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);
56
57     @Test
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)
64                 .build();
65
66         final ListenableFuture<EffectiveModelContext> lf = createSchemaContext(modulesWithSupportedDeviations, FOO, BAR,
67             BAZ, FOOBAR);
68         assertTrue(lf.isDone());
69         final SchemaContext schemaContext = lf.get();
70         assertNotNull(schemaContext);
71
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)));
77     }
78
79     @Test
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);
85
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)));
91     }
92
93     @Test
94     public void testDeviationsSupportedInNoModule() throws Exception {
95         final ListenableFuture<EffectiveModelContext> lf = createSchemaContext(ImmutableSetMultimap.of(), FOO, BAR, BAZ,
96             FOOBAR);
97         assertTrue(lf.isDone());
98         final SchemaContext schemaContext = lf.get();
99         assertNotNull(schemaContext);
100
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)));
106     }
107
108     @Test
109     public void shouldFailOnAttemptToDeviateTheSameModule2() throws Exception {
110         final ListenableFuture<EffectiveModelContext> lf = createSchemaContext(null, BAR_INVALID, BAZ_INVALID);
111         assertTrue(lf.isDone());
112         try {
113             lf.get();
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"));
120         }
121     }
122
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);
128     }
129
130     private static ListenableFuture<EffectiveModelContext> createSchemaContext(
131             final SetMultimap<QNameModule, QNameModule> modulesWithSupportedDeviations, final String... resources)
132             throws Exception {
133         final SharedSchemaRepository sharedSchemaRepository = new SharedSchemaRepository(
134                 "shared-schema-repo-with-deviations-test");
135
136         final Collection<SourceIdentifier> requiredSources = new ArrayList<>();
137         for (final String resource : resources) {
138             final SettableSchemaProvider<ASTSchemaSource> yangSource = getImmediateYangSourceProviderFromResource(
139                     resource);
140             yangSource.register(sharedSchemaRepository);
141             yangSource.setResult();
142             requiredSources.add(yangSource.getId());
143         }
144
145         final SchemaContextFactoryConfiguration config = SchemaContextFactoryConfiguration.builder()
146                 .setModulesDeviatedByModules(modulesWithSupportedDeviations).build();
147         return sharedSchemaRepository.createEffectiveModelContextFactory(config).createEffectiveModelContext(
148             requiredSources);
149     }
150 }