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