Merge "Bug 2512: Initial design of YANG statement meta-model."
[yangtools.git] / yang / yang-model-util / src / test / java / org / opendaylight / yangtools / yang / model / util / SchemaContextProxyTest.java
1 /*
2  * Copyright (c) 2015 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.html
7  */
8
9 package org.opendaylight.yangtools.yang.model.util;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertTrue;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.mock;
15
16 import com.google.common.collect.Sets;
17 import java.net.URI;
18 import java.net.URISyntaxException;
19 import java.text.ParseException;
20 import java.util.Arrays;
21 import java.util.Date;
22 import java.util.HashSet;
23 import java.util.Set;
24 import org.junit.BeforeClass;
25 import org.junit.Test;
26 import org.opendaylight.yangtools.yang.common.QNameModule;
27 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
28 import org.opendaylight.yangtools.yang.model.api.Module;
29 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
30 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
31 import org.opendaylight.yangtools.yang.model.util.FilteringSchemaContextProxy.ModuleId;
32
33 public class SchemaContextProxyTest {
34
35     private static URI namespace;
36     private static Date revision;
37     private static Date revision2;
38
39     private static final String CONFIG_NAME = "config";
40     private static final String ROOT_NAME = "root";
41     private static final String MODULE2_NAME = "module2";
42     private static final String MODULE3_NAME = "module3";
43     private static final String MODULE4_NAME = "module4";
44     private static final String MODULE41_NAME = "module41";
45     private static final String MODULE5_NAME = "module5";
46     private static final String TEST_SOURCE = "test source";
47
48     @BeforeClass
49     public static void setUp() throws ParseException, URISyntaxException {
50
51         namespace = new URI("urn:opendaylight:params:xml:ns:yang:controller:config");
52
53         revision = SimpleDateFormatUtil.getRevisionFormat().parse("2015-01-01");
54         revision2 = SimpleDateFormatUtil.getRevisionFormat().parse("2015-01-15");
55     }
56
57     private SchemaContext mockSchema(Module... module) {
58
59         SchemaContext mock = mock(SchemaContext.class);
60         doReturn(Sets.newHashSet(module)).when(mock).getModules();
61         return mock;
62     }
63
64     /**
65      * <pre>
66      * CFG(R)
67      *  | \
68      *  |  \
69      * M2 <- M3
70      * </pre>
71      */
72     @Test
73     public void testBasic() {
74         Module moduleConfig = mockModule(CONFIG_NAME);
75         Module module2 = mockModule(MODULE2_NAME);
76         Module module3 = mockModule(MODULE3_NAME);
77
78         mockModuleImport(module2, moduleConfig);
79         mockModuleImport(module3, module2, moduleConfig);
80
81         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
82
83         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
84         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
85     }
86
87     /**
88      * <pre>
89      * No root or additional modules
90      *  | \
91      *  |  \
92      * M2 <- M3
93      * </pre>
94      */
95     @Test
96     public void testNull() {
97         Module moduleConfig = mockModule(CONFIG_NAME);
98         Module module2 = mockModule(MODULE2_NAME);
99         Module module3 = mockModule(MODULE3_NAME);
100
101         mockModuleImport(module2, moduleConfig);
102         mockModuleImport(module3, module2, moduleConfig);
103
104         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
105
106         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, null);
107         assertProxyContext(filteringSchemaContextProxy, null);
108     }
109
110     /**
111      * <pre>
112      *  Config
113      *  | \ (NR)
114      *  |  \
115      * M2 <- M3
116      * </pre>
117      */
118     @Test
119     public void testConfigDifferentRevisions() {
120         Module moduleConfigNullRevision = mockModule(CONFIG_NAME, null);
121         Module moduleConfig = mockModule(CONFIG_NAME, revision);
122         Module moduleConfig2 = mockModule(CONFIG_NAME, revision2);
123         Module module2 = mockModule(MODULE2_NAME);
124         Module module3 = mockModule(MODULE3_NAME);
125
126         mockModuleImport(module2, moduleConfig);
127         mockModuleImport(module3, module2, moduleConfigNullRevision);
128
129         SchemaContext schemaContext = mockSchema(moduleConfig, moduleConfig2, module2, module3);
130
131         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
132         assertProxyContext(filteringSchemaContextProxy, moduleConfig, moduleConfig2, module2, module3);
133     }
134
135     /**
136      * <pre>
137      *     CFG(R)
138      *    |      \
139      *   |         \
140      * M2<-(NullRev)M3
141      * </pre>
142      */
143     @Test
144     public void testBasicNullRevision() throws Exception {
145         Module moduleConfig = mockModule(CONFIG_NAME,SimpleDateFormatUtil.getRevisionFormat().parse("2013-04-05"));
146         Module module2 = mockModule(MODULE2_NAME, SimpleDateFormatUtil.getRevisionFormat().parse("2014-06-17"));
147         Module module20 = mockModule(MODULE2_NAME, null);
148         Module module3 = mockModule(MODULE3_NAME, SimpleDateFormatUtil.getRevisionFormat().parse("2014-06-12"));
149         Module module30 = mockModule(MODULE3_NAME, null);
150
151         mockModuleImport(module20, moduleConfig);
152         mockModuleImport(module2, moduleConfig);
153         mockModuleImport(module3, module20, moduleConfig);
154         mockModuleImport(module30, module20, moduleConfig);
155
156         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
157
158         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
159
160         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
161     }
162
163     /**
164      * <pre>
165      * CFG(R)   ROOT(R)
166      *  |         \
167      *  |          \
168      * M2          M3
169      * </pre>
170      */
171     @Test
172     public void testBasicMoreRootModules() {
173         Module moduleConfig = mockModule(CONFIG_NAME);
174         Module moduleRoot = mockModule(ROOT_NAME);
175         Module module2 = mockModule(MODULE2_NAME);
176         Module module3 = mockModule(MODULE3_NAME);
177
178         mockModuleImport(module2, moduleConfig);
179         mockModuleImport(module3, moduleRoot);
180
181         SchemaContext schemaContext = mockSchema(moduleConfig, moduleRoot, module2, module3);
182
183         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleRoot, moduleConfig);
184         assertProxyContext(filteringSchemaContextProxy, moduleRoot, module3, moduleConfig, module2);
185     }
186
187     /**
188      * <pre>
189      * CFG(R)
190      *  |
191      *  |
192      * M2 <- M3
193      * </pre>
194      */
195     @Test
196     public void testChainNotDepend() {
197         Module moduleConfig = mockModule(CONFIG_NAME);
198         Module module2 = mockModule(MODULE2_NAME);
199         Module module3 = mockModule(MODULE3_NAME);
200
201         mockModuleImport(module2, moduleConfig);
202         mockModuleImport(module3, module2);
203
204         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3);
205
206         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
207         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2);
208     }
209
210     /**
211      * <pre>
212      * CFG(R)
213      *  |
214      *  |
215      * M2 -> M3 -> M4 -> M5
216      * </pre>
217      */
218     @Test
219     public void testChainDependMulti() {
220         Module moduleConfig = mockModule(CONFIG_NAME);
221         Module module2 = mockModule(MODULE2_NAME);
222         Module module3 = mockModule(MODULE3_NAME);
223         Module module4 = mockModule(MODULE4_NAME);
224         Module module5 = mockModule(MODULE5_NAME);
225
226         mockModuleImport(module2, moduleConfig, module3);
227         mockModuleImport(module3, module4);
228         mockModuleImport(module4, module5);
229
230         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
231
232         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
233         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4, module5);
234     }
235
236     /**
237      * <pre>
238      * CFG(R)
239      *  |
240      *  |
241      * M2 -> M3 <- M4
242      * </pre>
243      */
244     @Test
245     public void testChainNotDependMulti() {
246         Module moduleConfig = mockModule(CONFIG_NAME);
247         Module module2 = mockModule(MODULE2_NAME);
248         Module module3 = mockModule(MODULE3_NAME);
249         Module module4 = mockModule(MODULE4_NAME);
250
251         mockModuleImport(module2, moduleConfig, module3);
252         mockModuleImport(module4, module3);
253
254         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4);
255
256         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
257         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
258     }
259
260     /**
261      * <pre>
262      *  CFG(R)
263      *  | \ \ \
264      *  |  \ \ \
265      * M2 M3 M4 M5
266      * </pre>
267      */
268     @Test
269     public void testChainNotMulti() {
270         Module moduleConfig = mockModule(CONFIG_NAME);
271         Module module2 = mockModule(MODULE2_NAME);
272         Module module3 = mockModule(MODULE3_NAME);
273         Module module4 = mockModule(MODULE4_NAME);
274         Module module5 = mockModule(MODULE5_NAME);
275
276         mockModuleImport(module2, moduleConfig);
277         mockModuleImport(module3, moduleConfig);
278         mockModuleImport(module4, moduleConfig);
279         mockModuleImport(module5, moduleConfig);
280
281         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
282
283         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
284         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4, module5);
285     }
286
287     /**
288      * <pre>
289      * CFG(R)
290      *  | \
291      *  |  \
292      * M2 <- M3 M4=M3(Different revision)
293      * </pre>
294      */
295     @Test
296     public void testBasicRevisionChange() throws Exception {
297         Module moduleConfig = mockModule(CONFIG_NAME);
298         Module module2 = mockModule(MODULE2_NAME);
299         Module module3 = mockModule(MODULE3_NAME);
300
301         Date dat = SimpleDateFormatUtil.getRevisionFormat().parse("2015-10-10");
302         Module module4 = mockModule(MODULE3_NAME, dat);
303
304         mockModuleImport(module2, moduleConfig);
305         mockModuleImport(module3, module2, moduleConfig);
306
307         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4);
308
309         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
310         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3);
311     }
312
313     /**
314      * <pre>
315      * CFG(R)
316      * |
317      * M2 -(no revision)-> M3(R2) ... M3(R1)
318      * </pre>
319      */
320     @Test
321     public void testImportNoRevision() throws Exception {
322         Module moduleConfig = mockModule(CONFIG_NAME, revision);
323         Module module2 = mockModule(MODULE2_NAME, revision);
324
325         Module module3  = mockModule(MODULE3_NAME, null);
326         Module module30 = mockModule(MODULE3_NAME, revision);
327         Module module31 = mockModule(MODULE3_NAME, revision2);
328         mockModuleImport(module2, moduleConfig, module3);
329
330         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module30, module31);
331
332         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
333
334         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module31);
335     }
336
337     /**
338      * <pre>
339      * CFG(R)
340      * |   \
341      * |    \
342      * |    M2 -> M3
343      * |
344      * M41(S) => M4
345      * </pre>
346      */
347     @Test
348     public void testBasicSubmodule() throws Exception {
349         Module moduleConfig = mockModule(CONFIG_NAME);
350         Module module2 = mockModule(MODULE2_NAME);
351         Module module3 = mockModule(MODULE3_NAME);
352         Module module4 = mockModule(MODULE4_NAME);
353         Module module41 = mockModule(MODULE41_NAME);
354
355         mockSubmodules(module4, module41);
356         mockModuleImport(module2, moduleConfig, module3);
357         mockModuleImport(module41, moduleConfig);
358
359         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4);
360
361         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, null, moduleConfig);
362         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4);
363     }
364
365     /**
366      * <pre>
367      *
368      * M2 -> M3 -> M4 -> M5
369      *
370      * </pre>
371      */
372     @Test
373     public void testChainAdditionalModules() {
374         Module module2 = mockModule(MODULE2_NAME);
375         Module module3 = mockModule(MODULE3_NAME);
376         Module module4 = mockModule(MODULE4_NAME);
377         Module module5 = mockModule(MODULE5_NAME);
378
379         mockModuleImport(module2, module3);
380         mockModuleImport(module3, module4);
381         mockModuleImport(module4, module5);
382
383         SchemaContext schemaContext = mockSchema(module2, module3, module4, module5);
384
385         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Sets.newHashSet(module2), null);
386         assertProxyContext(filteringSchemaContextProxy, module2, module3, module4, module5);
387     }
388
389     /**
390      * <pre>
391      *
392      * CFG(R)
393      *  |
394      *  |       M5
395      * M2
396      *
397      * M3 -> M4
398      *
399      * </pre>
400      */
401     @Test
402     public void testChainAdditionalModulesConfig() {
403         Module moduleConfig = mockModule(CONFIG_NAME);
404         Module module2 = mockModule(MODULE2_NAME);
405
406         Module module3 = mockModule(MODULE3_NAME);
407         Module module4 = mockModule(MODULE4_NAME);
408         Module module5 = mockModule(MODULE5_NAME);
409
410         mockModuleImport(module2, moduleConfig);
411         mockModuleImport(module3, module4);
412
413         SchemaContext schemaContext = mockSchema(moduleConfig, module2, module3, module4, module5);
414
415         FilteringSchemaContextProxy filteringSchemaContextProxy = createProxySchemaCtx(schemaContext, Sets.newHashSet(module3), moduleConfig);
416         assertProxyContext(filteringSchemaContextProxy, moduleConfig, module2, module3, module4);
417     }
418
419     private void assertProxyContext(FilteringSchemaContextProxy filteringSchemaContextProxy, Module... expected) {
420
421         Set<Module> modSet = Sets.newHashSet();
422
423         if(expected!=null) {
424
425             modSet = Sets.newHashSet(expected);
426         }
427
428         Set<Module> modSetFiltering = filteringSchemaContextProxy.getModules();
429
430         assertEquals(modSet, modSetFiltering);
431
432         //asserting collections
433         if(expected!=null) {
434             for (final Module module : expected) {
435                 assertEquals(module, filteringSchemaContextProxy.findModuleByName(module.getName(), module.getRevision()));
436
437                 Set<Module> mod = filteringSchemaContextProxy.findModuleByNamespace(module.getNamespace());
438                 assertTrue(mod.contains(module));
439
440                 assertEquals(module, filteringSchemaContextProxy.findModuleByNamespaceAndRevision(module.getNamespace(), module.getRevision()));
441
442                 assertEquals(module.getSource(), filteringSchemaContextProxy.getModuleSource(module).get());
443             }
444         }
445     }
446
447     private FilteringSchemaContextProxy createProxySchemaCtx(SchemaContext schemaContext, Set<Module> additionalModules, Module... modules) {
448
449         Set<Module> modulesSet = new HashSet();
450
451         if(modules!=null) {
452
453             modulesSet = Sets.newHashSet(modules);
454
455         }
456
457         return new FilteringSchemaContextProxy(schemaContext, createModuleIds(modulesSet) , createModuleIds(additionalModules));
458     }
459
460     private Set<ModuleId> createModuleIds(Set<Module> modules) {
461
462         Set<ModuleId> moduleIds = Sets.newHashSet();
463
464         if(modules!=null && modules.size()>0) {
465
466             for (Module module : modules) {
467
468                 moduleIds.add(new ModuleId(module.getName(), module.getRevision()));
469             }
470         }
471
472         return moduleIds;
473     }
474
475     private void mockSubmodules(Module mainModule, Module... submodules){
476
477         Set<Module> submodulesSet = new HashSet<>();
478         submodulesSet.addAll(Arrays.asList(submodules));
479
480         doReturn(submodulesSet).when(mainModule).getSubmodules();
481     }
482
483     private void mockModuleImport(Module importer, Module... imports) {
484         Set<ModuleImport> mockedImports = Sets.newHashSet();
485         for (final Module module : imports) {
486             mockedImports.add(new ModuleImport() {
487                 @Override
488                 public String getModuleName() {
489                     return module.getName();
490                 }
491
492                 @Override
493                 public Date getRevision() {
494                     return module.getRevision();
495                 }
496
497                 @Override
498                 public String getPrefix() {
499                     return module.getName();
500                 }
501
502                 @Override
503                 public String toString() {
504
505                     return String.format("Module: %s, revision:%s", module.getName(), module.getRevision());
506                 }
507             });
508         }
509         doReturn(mockedImports).when(importer).getImports();
510     }
511
512     //mock module with revision
513     private Module mockModule(String name, final Date rev){
514
515         final Module mod = mockModule(name);
516
517         doReturn(QNameModule.create(mod.getNamespace(), rev)).when(mod).getQNameModule();
518         doReturn(rev).when(mod).getRevision();
519         doReturn(mod.getQNameModule().toString()).when(mod).toString();
520
521         return mod;
522     }
523
524     //mock module with default revision
525     private Module mockModule(String mName) {
526
527         Module mockedModule = mock(Module.class);
528         doReturn(mName).when(mockedModule).getName();
529         doReturn(revision).when(mockedModule).getRevision();
530         final URI newNamespace = URI.create(namespace.toString() + ":" + mName);
531         doReturn(newNamespace).when(mockedModule).getNamespace();
532         doReturn(QNameModule.create(newNamespace, revision)).when(mockedModule).getQNameModule();
533         doReturn(TEST_SOURCE).when(mockedModule).getSource();
534         doReturn(Sets.newHashSet()).when(mockedModule).getSubmodules();
535         doReturn(mockedModule.getQNameModule().toString()).when(mockedModule).toString();
536         mockModuleImport(mockedModule);
537
538         return mockedModule;
539     }
540 }