2 * Copyright (c) 2015 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.model.util;
10 import static org.junit.jupiter.api.Assertions.assertEquals;
11 import static org.junit.jupiter.api.Assertions.assertTrue;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.mock;
16 import com.google.common.collect.ImmutableSet;
17 import java.util.Arrays;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Optional;
22 import org.junit.jupiter.api.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.common.UnresolvedQName.Unqualified;
27 import org.opendaylight.yangtools.yang.common.XMLNamespace;
28 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
29 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
30 import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition;
31 import org.opendaylight.yangtools.yang.model.api.GroupingDefinition;
32 import org.opendaylight.yangtools.yang.model.api.Module;
33 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
34 import org.opendaylight.yangtools.yang.model.api.ModuleLike;
35 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
36 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
37 import org.opendaylight.yangtools.yang.model.api.Submodule;
38 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
39 import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
40 import org.opendaylight.yangtools.yang.model.api.stmt.ImportEffectiveStatement;
41 import org.opendaylight.yangtools.yang.model.spi.AbstractSchemaContext;
42 import org.opendaylight.yangtools.yang.model.util.FilteringSchemaContextProxy.ModuleId;
44 class SchemaContextProxyTest {
46 private static final String NAMESPACE = "urn:opendaylight:params:xml:ns:yang:controller:config";
47 private static final Revision REVISION = Revision.of("2015-01-01");
48 private static final Revision REVISION2 = Revision.of("2015-01-15");
50 private static final String CONFIG_NAME = "config";
51 private static final String ROOT_NAME = "root";
52 private static final String MODULE2_NAME = "module2";
53 private static final String MODULE3_NAME = "module3";
54 private static final String MODULE4_NAME = "module4";
55 private static final String MODULE41_NAME = "module41";
56 private static final String MODULE5_NAME = "module5";
58 private static EffectiveModelContext mockSchema(final Module... modules) {
59 Arrays.sort(modules, AbstractSchemaContext.NAME_REVISION_COMPARATOR);
60 var mock = mock(EffectiveModelContext.class);
61 doReturn(ImmutableSet.copyOf(modules)).when(mock).getModules();
73 var moduleConfig = mockModule(CONFIG_NAME);
74 var module2 = mockModule(MODULE2_NAME);
75 var module3 = mockModule(MODULE3_NAME);
77 mockModuleImport(module2, moduleConfig);
78 mockModuleImport(module3, module2, moduleConfig);
80 var schemaContext = mockSchema(moduleConfig, module2, module3);
82 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
83 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
87 * No root or additional modules
94 var moduleConfig = mockModule(CONFIG_NAME);
95 var module2 = mockModule(MODULE2_NAME);
96 var module3 = mockModule(MODULE3_NAME);
98 mockModuleImport(module2, moduleConfig);
99 mockModuleImport(module3, module2, moduleConfig);
101 var schemaContext = mockSchema(moduleConfig, module2, module3);
103 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, null);
104 assertProxyContext(filteringSchemaContextProxy, null);
114 void testConfigDifferentRevisions() {
115 var moduleConfigNullRevision = mockModule(CONFIG_NAME, null);
116 var moduleConfig = mockModule(CONFIG_NAME, REVISION);
117 var moduleConfig2 = mockModule(CONFIG_NAME, REVISION2);
118 var module2 = mockModule(MODULE2_NAME);
119 var module3 = mockModule(MODULE3_NAME);
121 mockModuleImport(module2, moduleConfig);
122 mockModuleImport(module3, module2, moduleConfigNullRevision);
124 var schemaContext = mockSchema(moduleConfig, moduleConfig2, module2, module3);
126 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
127 assertProxyContext(filteringSchemaContextProxy, moduleConfig, moduleConfig2, module2, module3);
137 void testBasicNullRevision() throws Exception {
138 final var moduleConfig = mockModule(CONFIG_NAME, Revision.of("2013-04-05"));
139 final var module2 = mockModule(MODULE2_NAME, Revision.of("2014-06-17"));
140 final var module20 = mockModule(MODULE2_NAME, null);
141 final var module3 = mockModule(MODULE3_NAME, Revision.of("2014-06-12"));
142 final var module30 = mockModule(MODULE3_NAME, null);
144 mockModuleImport(module20, moduleConfig);
145 mockModuleImport(module2, moduleConfig);
146 mockModuleImport(module3, module20, moduleConfig);
147 mockModuleImport(module30, module20, moduleConfig);
149 var schemaContext = mockSchema(moduleConfig, module2, module3);
151 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
152 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
162 void testBasicMoreRootModules() {
163 final var moduleConfig = mockModule(CONFIG_NAME);
164 final var moduleRoot = mockModule(ROOT_NAME);
165 final var module2 = mockModule(MODULE2_NAME);
166 final var module3 = mockModule(MODULE3_NAME);
168 mockModuleImport(module2, moduleConfig);
169 mockModuleImport(module3, moduleRoot);
171 var schemaContext = mockSchema(moduleConfig, moduleRoot, module2, module3);
173 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleRoot, moduleConfig);
174 assertProxyContext(filteringSchemaContextProxy, moduleRoot, module3, moduleConfig, module2);
184 void testChainNotDepend() {
185 var moduleConfig = mockModule(CONFIG_NAME);
186 var module2 = mockModule(MODULE2_NAME);
187 var module3 = mockModule(MODULE3_NAME);
189 mockModuleImport(module2, moduleConfig);
190 mockModuleImport(module3, module2);
192 var schemaContext = mockSchema(moduleConfig, module2, module3);
194 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
195 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2);
202 * M2 -> M3 -> M4 -> M5
205 void testChainDependMulti() {
206 var moduleConfig = mockModule(CONFIG_NAME);
207 var module2 = mockModule(MODULE2_NAME);
208 var module3 = mockModule(MODULE3_NAME);
209 var module4 = mockModule(MODULE4_NAME);
210 var module5 = mockModule(MODULE5_NAME);
212 mockModuleImport(module2, moduleConfig, module3);
213 mockModuleImport(module3, module4);
214 mockModuleImport(module4, module5);
216 var schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
218 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
219 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4, module5);
229 void testChainNotDependMulti() {
230 var moduleConfig = mockModule(CONFIG_NAME);
231 var module2 = mockModule(MODULE2_NAME);
232 var module3 = mockModule(MODULE3_NAME);
233 var module4 = mockModule(MODULE4_NAME);
235 mockModuleImport(module2, moduleConfig, module3);
236 mockModuleImport(module4, module3);
238 var schemaContext = mockSchema(moduleConfig, module2, module3, module4);
240 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
241 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
251 void testChainNotMulti() {
252 final var moduleConfig = mockModule(CONFIG_NAME);
253 final var module2 = mockModule(MODULE2_NAME);
254 final var module3 = mockModule(MODULE3_NAME);
255 final var module4 = mockModule(MODULE4_NAME);
256 final var module5 = mockModule(MODULE5_NAME);
258 mockModuleImport(module2, moduleConfig);
259 mockModuleImport(module3, moduleConfig);
260 mockModuleImport(module4, moduleConfig);
261 mockModuleImport(module5, moduleConfig);
263 var schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
265 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
266 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4, module5);
273 * M2 <- M3 M4=M3(Different revision)
276 void testBasicRevisionChange() throws Exception {
277 var moduleConfig = mockModule(CONFIG_NAME);
278 var module2 = mockModule(MODULE2_NAME);
279 var module3 = mockModule(MODULE3_NAME);
280 var module4 = mockModule(MODULE3_NAME, Revision.of("2015-10-10"));
282 mockModuleImport(module2, moduleConfig);
283 mockModuleImport(module3, module2, moduleConfig);
285 var schemaContext = mockSchema(moduleConfig, module2, module3, module4);
287 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
288 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
294 * M2 -(no revision)-> M3(R2) ... M3(R1)
297 void testImportNoRevision() {
298 var moduleConfig = mockModule(CONFIG_NAME, REVISION);
299 var module2 = mockModule(MODULE2_NAME, REVISION);
301 var module3 = mockModule(MODULE3_NAME, null);
302 var module30 = mockModule(MODULE3_NAME, REVISION);
303 var module31 = mockModule(MODULE3_NAME, REVISION2);
304 mockModuleImport(module2, moduleConfig, module3);
306 var schemaContext = mockSchema(moduleConfig, module2, module30, module31);
308 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
309 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module31);
321 void testBasicSubmodule() {
322 var moduleConfig = mockModule(CONFIG_NAME);
323 var module2 = mockModule(MODULE2_NAME);
324 var module3 = mockModule(MODULE3_NAME);
325 var module4 = mockModule(MODULE4_NAME);
326 var module41 = mockSubmodule(MODULE41_NAME);
328 mockSubmodules(module4, module41);
329 mockModuleImport(module2, moduleConfig, module3);
330 mockModuleImport(module41, moduleConfig);
332 var schemaContext = mockSchema(moduleConfig, module2, module3, module4);
334 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
335 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4);
339 * M2 -> M3 -> M4 -> M5
342 void testChainAdditionalModules() {
343 var module2 = mockModule(MODULE2_NAME);
344 var module3 = mockModule(MODULE3_NAME);
345 var module4 = mockModule(MODULE4_NAME);
346 var module5 = mockModule(MODULE5_NAME);
348 mockModuleImport(module2, module3);
349 mockModuleImport(module3, module4);
350 mockModuleImport(module4, module5);
352 var schemaContext = mockSchema(module2, module3, module4, module5);
354 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(module2), null);
355 assertProxyContext(filteringSchemaContextProxy, module2, module3, module4, module5);
368 void testChainAdditionalModulesConfig() {
369 var moduleConfig = mockModule(CONFIG_NAME);
370 var module2 = mockModule(MODULE2_NAME);
372 var module3 = mockModule(MODULE3_NAME);
373 var module4 = mockModule(MODULE4_NAME);
374 var module5 = mockModule(MODULE5_NAME);
376 mockModuleImport(module2, moduleConfig);
377 mockModuleImport(module3, module4);
379 var schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
381 var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(module3), moduleConfig);
382 assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4);
386 void testGetDataDefinitions() {
387 final var moduleConfig = mockModule(CONFIG_NAME);
388 final var schemaContext = mockSchema(moduleConfig);
389 final var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(), moduleConfig);
391 final var mockedContainer = mock(ContainerSchemaNode.class);
392 doReturn(Set.of(mockedContainer)).when(moduleConfig).getChildNodes();
394 final var dataDefinitions = filteringSchemaContextProxy.getDataDefinitions();
395 assertTrue(dataDefinitions.contains(mockedContainer));
399 void testGetNotifications() {
400 final var moduleConfig = mockModule(CONFIG_NAME);
401 final var schemaContext = mockSchema(moduleConfig);
402 final var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(), moduleConfig);
404 final var mockedNotification = mock(NotificationDefinition.class);
405 doReturn(Set.of(mockedNotification)).when(moduleConfig).getNotifications();
407 final var schemaContextProxyNotifications = filteringSchemaContextProxy.getNotifications();
408 assertTrue(schemaContextProxyNotifications.contains(mockedNotification));
412 void testGetOperations() {
413 final var moduleConfig = mockModule(CONFIG_NAME);
414 final var schemaContext = mockSchema(moduleConfig);
415 final var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(), moduleConfig);
417 final var mockedRpc = mock(RpcDefinition.class);
418 doReturn(Set.of(mockedRpc)).when(moduleConfig).getRpcs();
420 final var operations = filteringSchemaContextProxy.getOperations();
421 assertTrue(operations.contains(mockedRpc));
425 void testGetExtensions() {
426 final var moduleConfig = mockModule(CONFIG_NAME);
427 final var schemaContext = mockSchema(moduleConfig);
428 final var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(), moduleConfig);
430 final var mockedExtension = mock(ExtensionDefinition.class);
431 doReturn(List.of(mockedExtension)).when(moduleConfig).getExtensionSchemaNodes();
433 final var schemaContextProxyExtensions = filteringSchemaContextProxy.getExtensions();
434 assertTrue(schemaContextProxyExtensions.contains(mockedExtension));
438 void testGetUnknownSchemaNodes() {
439 final var moduleConfig = mockModule(CONFIG_NAME);
440 final var schemaContext = mockSchema(moduleConfig);
441 final var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(), moduleConfig);
443 final var mockedUnknownSchemaNode = mock(UnknownSchemaNode.class);
444 doReturn(List.of(mockedUnknownSchemaNode)).when(moduleConfig).getUnknownSchemaNodes();
446 final var schemaContextProxyUnknownSchemaNodes = filteringSchemaContextProxy.getUnknownSchemaNodes();
447 assertTrue(schemaContextProxyUnknownSchemaNodes.contains(mockedUnknownSchemaNode));
451 void testGetTypeDefinitions() {
452 final var moduleConfig = mockModule(CONFIG_NAME);
453 final var schemaContext = mockSchema(moduleConfig);
454 final var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(), moduleConfig);
456 final var mockedTypeDefinition = mock(TypeDefinition.class);
457 doReturn(Set.of(mockedTypeDefinition)).when(moduleConfig).getTypeDefinitions();
459 final var schemaContextProxyTypeDefinitions = filteringSchemaContextProxy.getTypeDefinitions();
460 assertTrue(schemaContextProxyTypeDefinitions.contains(mockedTypeDefinition));
464 void testGetChildNodes() {
465 final var moduleConfig = mockModule(CONFIG_NAME);
466 final var schemaContext = mockSchema(moduleConfig);
467 final var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(), moduleConfig);
469 final var mockedContainer = mock(ContainerSchemaNode.class);
470 doReturn(Set.of(mockedContainer)).when(moduleConfig).getChildNodes();
472 final var schemaContextProxyChildNodes = filteringSchemaContextProxy.getChildNodes();
473 assertTrue(schemaContextProxyChildNodes.contains(mockedContainer));
477 void testGetGroupings() {
478 final var moduleConfig = mockModule(CONFIG_NAME);
479 final var schemaContext = mockSchema(moduleConfig);
480 final var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(), moduleConfig);
482 final var mockedGrouping = mock(GroupingDefinition.class);
483 doReturn(Set.of(mockedGrouping)).when(moduleConfig).getGroupings();
485 final var schemaContextProxyGroupings = filteringSchemaContextProxy.getGroupings();
486 assertTrue(schemaContextProxyGroupings.contains(mockedGrouping));
490 void testGetDataChildByName() {
491 final var moduleConfig = mockModule(CONFIG_NAME);
492 final var schemaContext = mockSchema(moduleConfig);
493 final var filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Set.of(), moduleConfig);
495 final var qname = QName.create("config-namespace", "2016-08-11", "cont");
496 final var mockedContainer = mock(ContainerSchemaNode.class);
497 doReturn(mockedContainer).when(moduleConfig).dataChildByName(any(QName.class));
499 final var dataSchemaNode = filteringSchemaContextProxy.getDataChildByName(qname);
500 assertTrue(dataSchemaNode instanceof ContainerSchemaNode);
503 private static void assertProxyContext(final FilteringSchemaContextProxy filteringSchemaContextProxy,
504 final Module... expected) {
506 final var modSet = expected != null ? ImmutableSet.copyOf(expected) : Set.of();
507 var modSetFiltering = filteringSchemaContextProxy.getModules();
509 assertEquals(modSet, modSetFiltering);
511 //asserting collections
512 if (expected != null) {
513 for (var module : expected) {
514 assertEquals(Optional.of(module),
515 filteringSchemaContextProxy.findModule(module.getName(), module.getRevision()));
517 final var mod = filteringSchemaContextProxy.findModules(module.getNamespace());
518 assertTrue(mod.contains(module));
519 assertEquals(Optional.of(module),
520 filteringSchemaContextProxy.findModule(module.getNamespace(), module.getRevision().orElse(null)));
525 private static FilteringSchemaContextProxy createProxySchemaCtx(final EffectiveModelContext schemaContext,
526 final Set<Module> additionalModules, final Module... modules) {
527 final var modulesSet = modules != null ? ImmutableSet.copyOf(modules) : Set.<Module>of();
528 return new FilteringSchemaContextProxy(schemaContext, createModuleIds(modulesSet),
529 createModuleIds(additionalModules));
532 private static Set<ModuleId> createModuleIds(final Set<Module> modules) {
533 final var moduleIds = new HashSet<ModuleId>();
534 if (modules != null) {
535 for (var module : modules) {
536 moduleIds.add(new ModuleId(module.getName(), module.getRevision()));
543 private static void mockSubmodules(final Module mainModule, final Submodule... submodules) {
544 doReturn(Set.of(submodules)).when(mainModule).getSubmodules();
547 private static void mockModuleImport(final ModuleLike importer, final Module... imports) {
548 final var mockedImports = new HashSet<ModuleImport>();
549 for (var module : imports) {
550 mockedImports.add(new ModuleImport() {
552 public Unqualified getModuleName() {
553 return Unqualified.of(module.getName());
557 public Optional<Revision> getRevision() {
558 return module.getRevision();
562 public String getPrefix() {
563 return module.getName();
567 public Optional<String> getDescription() {
568 return module.getDescription();
572 public Optional<String> getReference() {
573 return module.getReference();
577 public String toString() {
578 return String.format("Module: %s, revision:%s", module.getName(), module.getRevision());
582 public ImportEffectiveStatement asEffectiveStatement() {
583 throw new UnsupportedOperationException();
587 doReturn(mockedImports).when(importer).getImports();
590 //mock module with revision
591 private static Module mockModule(final String name, final Revision rev) {
592 final var mod = mockModule(name);
594 doReturn(QNameModule.ofRevision(mod.getNamespace(), rev)).when(mod).getQNameModule();
595 doReturn(Optional.ofNullable(rev)).when(mod).getRevision();
596 doReturn(mod.getQNameModule().toString()).when(mod).toString();
601 //mock module with default revision
602 private static Module mockModule(final String name) {
603 final var mockedModule = mock(Module.class);
604 mockModuleLike(mockedModule, name);
608 private static Submodule mockSubmodule(final String name) {
609 final var mockedModule = mock(Submodule.class);
610 mockModuleLike(mockedModule, name);
614 private static void mockModuleLike(final ModuleLike mockedModule, final String name) {
615 doReturn(name).when(mockedModule).getName();
616 doReturn(Optional.of(REVISION)).when(mockedModule).getRevision();
617 final var newNamespace = XMLNamespace.of(NAMESPACE + ":" + name);
618 doReturn(newNamespace).when(mockedModule).getNamespace();
619 doReturn(QNameModule.of(newNamespace, REVISION)).when(mockedModule).getQNameModule();
620 doReturn(Set.of()).when(mockedModule).getSubmodules();
621 doReturn(mockedModule.getQNameModule().toString()).when(mockedModule).toString();
622 mockModuleImport(mockedModule);