Bug 4540: Yang parser exceptions should follow consistent path
[yangtools.git] / yang / yang-parser-impl / src / test / java / org / opendaylight / yangtools / yang / stmt / test / MoreRevisionsTest.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
7  */
8
9 package org.opendaylight.yangtools.yang.stmt.test;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14 import java.io.FileNotFoundException;
15 import java.net.URI;
16 import java.net.URISyntaxException;
17 import java.text.ParseException;
18 import java.util.Date;
19 import java.util.Set;
20 import org.junit.Test;
21 import org.opendaylight.yangtools.yang.common.QName;
22 import org.opendaylight.yangtools.yang.common.QNameModule;
23 import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
24 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
25 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
26 import org.opendaylight.yangtools.yang.model.api.Module;
27 import org.opendaylight.yangtools.yang.model.api.ModuleImport;
28 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
29 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
30 import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
31 import org.opendaylight.yangtools.yang.parser.spi.source.SourceException;
32 import org.opendaylight.yangtools.yang.parser.stmt.reactor.CrossSourceStatementReactor;
33 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangInferencePipeline;
34 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.YangStatementSourceImpl;
35 import org.opendaylight.yangtools.yang.parser.stmt.rfc6020.effective.EffectiveSchemaContext;
36
37 public class MoreRevisionsTest {
38
39     private static final YangStatementSourceImpl REVFILE = new YangStatementSourceImpl(
40             "/semantic-statement-parser/revisions/more-revisions-test.yang",
41             false);
42
43     private static final YangStatementSourceImpl TED_20130712 = new YangStatementSourceImpl(
44             "/semantic-statement-parser/two-revisions/ted@2013-07-12.yang",
45             false);
46
47     private static final YangStatementSourceImpl TED_20131021 = new YangStatementSourceImpl(
48             "/semantic-statement-parser/two-revisions/ted@2013-10-21.yang",
49             false);
50
51     private static final YangStatementSourceImpl IETF_TYPES = new YangStatementSourceImpl(
52             "/ietf/ietf-inet-types@2010-09-24.yang", false);
53
54     private static final YangStatementSourceImpl NETWORK_TOPOLOGY_20130712 = new YangStatementSourceImpl(
55             "/ietf/network-topology@2013-07-12.yang", false);
56
57     private static final YangStatementSourceImpl NETWORK_TOPOLOGY_20131021 = new YangStatementSourceImpl(
58             "/ietf/network-topology@2013-10-21.yang", false);
59
60     private static final YangStatementSourceImpl ISIS_20130712 = new YangStatementSourceImpl(
61             "/semantic-statement-parser/two-revisions/isis-topology@2013-07-12.yang",
62             false);
63
64     private static final YangStatementSourceImpl ISIS_20131021 = new YangStatementSourceImpl(
65             "/semantic-statement-parser/two-revisions/isis-topology@2013-10-21.yang",
66             false);
67
68     private static final YangStatementSourceImpl L3_20130712 = new YangStatementSourceImpl(
69             "/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-07-12.yang",
70             false);
71
72     private static final YangStatementSourceImpl L3_20131021 = new YangStatementSourceImpl(
73             "/semantic-statement-parser/two-revisions/l3-unicast-igp-topology@2013-10-21.yang",
74             false);
75
76     @Test
77     public void readAndParseYangFileTest() throws SourceException,
78             ReactorException {
79         CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
80                 .newBuild();
81         reactor.addSource(REVFILE);
82         EffectiveSchemaContext result = reactor.buildEffective();
83         assertNotNull(result);
84         final Module moduleByName = result.getModules().iterator().next();
85         final QNameModule qNameModule = moduleByName.getQNameModule();
86         final String formattedRevision = qNameModule.getFormattedRevision();
87         assertEquals(formattedRevision, "2015-06-07");
88     }
89
90     @Test
91     public void twoRevisionsTest() throws SourceException, ReactorException {
92         CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
93                 .newBuild();
94
95         reactor.addSources(TED_20130712, TED_20131021, IETF_TYPES);
96
97         EffectiveSchemaContext result = reactor.buildEffective();
98         assertNotNull(result);
99
100     }
101
102     @Test
103     public void twoRevisionsTest2() throws SourceException, ReactorException {
104         CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
105                 .newBuild();
106
107         reactor.addSources(NETWORK_TOPOLOGY_20130712,
108                 NETWORK_TOPOLOGY_20131021, IETF_TYPES);
109
110         EffectiveSchemaContext result = reactor.buildEffective();
111         assertNotNull(result);
112         Set<Module> modules = result.getModules();
113
114         assertEquals(3, modules.size());
115         assertEquals(2, StmtTestUtils.findModules(modules, "network-topology")
116                 .size());
117     }
118
119     @Test
120     public void moreRevisionsListKeyTest() throws SourceException,
121             ReactorException {
122         CrossSourceStatementReactor.BuildAction reactor = YangInferencePipeline.RFC6020_REACTOR
123                 .newBuild();
124
125         reactor.addSources(TED_20130712, TED_20131021, ISIS_20130712,
126                 ISIS_20131021, L3_20130712, L3_20131021, IETF_TYPES,
127                 NETWORK_TOPOLOGY_20130712, NETWORK_TOPOLOGY_20131021);
128
129         EffectiveSchemaContext result = reactor.buildEffective();
130         assertNotNull(result);
131     }
132
133     @Test
134     public void multipleRevisionsTest() throws SourceException,
135             ReactorException, FileNotFoundException, URISyntaxException {
136         for (int i = 0; i < 100; i++) {
137             SchemaContext context = StmtTestUtils
138                     .parseYangSources("/semantic-statement-parser/multiple-revisions");
139             assertNotNull(context);
140         }
141     }
142
143     @Test
144     public void multipleRevisionsFullTest() throws SourceException,
145             ReactorException, FileNotFoundException, URISyntaxException,
146             ParseException {
147         for (int i = 0; i < 100; i++) {
148             SchemaContext context = StmtTestUtils
149                     .parseYangSources("/semantic-statement-parser/multiple-revisions/full");
150             assertNotNull(context);
151             assertEquals(6, context.getModules().size());
152             checkContentFullTest(context);
153         }
154     }
155
156     private static void checkContentFullTest(final SchemaContext context) throws ParseException,
157             URISyntaxException {
158
159         String yangTypesNSStr = "urn:ietf:params:xml:ns:yang:ietf-yang-types";
160         URI yangTypesNS = new URI(yangTypesNSStr);
161
162         Date rev20100924 = SimpleDateFormatUtil.getRevisionFormat().parse(
163                 "2010-09-24");
164         Date rev20130516 = SimpleDateFormatUtil.getRevisionFormat().parse(
165                 "2013-05-16");
166         Date rev20130715 = SimpleDateFormatUtil.getRevisionFormat().parse(
167                 "2013-07-15");
168
169         final QNameModule yangTypes_20100924 = QNameModule.create(yangTypesNS,
170                 rev20100924);
171         final QNameModule yangTypes_20130516 = QNameModule.create(yangTypesNS,
172                 rev20130516);
173         final QNameModule yangTypes_20130715 = QNameModule.create(yangTypesNS,
174                 rev20130715);
175
176         final QName dateTimeTypeDef_20100924 = QName.create(yangTypes_20100924,
177                 "date-and-time");
178         final QName dateTimeTypeDef_20130516 = QName.create(yangTypes_20130516,
179                 "date-and-time");
180         final QName dateTimeTypeDef_20130715 = QName.create(yangTypes_20130715,
181                 "date-and-time");
182
183         Module yangTypesModule_20100924 = context.findModuleByName(
184                 "ietf-yang-types", rev20100924);
185         Module yangTypesModule_20130516 = context.findModuleByName(
186                 "ietf-yang-types", rev20130516);
187         Module yangTypesModule_20130715 = context.findModuleByName(
188                 "ietf-yang-types", rev20130715);
189
190         assertNotNull(yangTypesModule_20100924);
191         assertNotNull(yangTypesModule_20130516);
192         assertNotNull(yangTypesModule_20130715);
193
194         assertTrue(findTypeDef(yangTypesModule_20100924,
195                 dateTimeTypeDef_20100924));
196         assertTrue(findTypeDef(yangTypesModule_20130516,
197                 dateTimeTypeDef_20130516));
198         assertTrue(findTypeDef(yangTypesModule_20130715,
199                 dateTimeTypeDef_20130715));
200
201         checkNetconfMonitoringModuleFullTest(context, rev20130715,
202                 dateTimeTypeDef_20130715);
203
204         checkInterfacesModuleFullTest(context, rev20100924, dateTimeTypeDef_20100924);
205
206     }
207
208     private static void checkInterfacesModuleFullTest(final SchemaContext context, final Date rev20100924,
209             final QName dateTimeTypeDef_20100924) throws URISyntaxException,
210             ParseException {
211         Date rev20121115 = SimpleDateFormatUtil.getRevisionFormat().parse(
212                 "2012-11-15");
213
214         Module interfacesModule_20121115 = context.findModuleByName(
215                 "ietf-interfaces", rev20121115);
216         assertNotNull(interfacesModule_20121115);
217
218         Set<ModuleImport> imports = interfacesModule_20121115.getImports();
219         assertEquals(1, imports.size());
220         ModuleImport interfacesImport = imports.iterator().next();
221         assertEquals("ietf-yang-types", interfacesImport.getModuleName());
222         assertEquals(rev20100924, interfacesImport.getRevision());
223     }
224
225     private static void checkNetconfMonitoringModuleFullTest(final SchemaContext context,
226             final Date rev20130715, final QName dateTimeTypeDef_20130715)
227             throws ParseException, URISyntaxException {
228         Date rev20101004 = SimpleDateFormatUtil.getRevisionFormat().parse(
229                 "2010-10-04");
230
231         Module monitoringModule_20101004 = context.findModuleByName(
232                 "ietf-netconf-monitoring", rev20101004);
233         assertNotNull(monitoringModule_20101004);
234
235         Set<ModuleImport> imports = monitoringModule_20101004.getImports();
236         assertEquals(2, imports.size());
237         for (ModuleImport monitoringImport : imports) {
238             if (monitoringImport.getModuleName().equals("ietf-yang-types")) {
239                 assertEquals(rev20130715, monitoringImport.getRevision());
240             }
241         }
242     }
243
244     @Test
245     public void multipleRevisionsSimpleTest() throws SourceException,
246             ReactorException, FileNotFoundException, URISyntaxException,
247             ParseException {
248         for (int i = 0; i < 1000; i++) {
249             SchemaContext context = StmtTestUtils
250                     .parseYangSources("/semantic-statement-parser/multiple-revisions/simple");
251             assertNotNull(context);
252             assertEquals(5, context.getModules().size());
253             checkContentSimpleTest(context);
254         }
255     }
256
257     private static void checkContentSimpleTest(final SchemaContext context)
258             throws ParseException, URISyntaxException {
259
260         String yangTypesNSStr = "urn:ietf:params:xml:ns:yang:ietf-yang-types";
261         URI yangTypesNS = new URI(yangTypesNSStr);
262
263         Date rev20100924 = SimpleDateFormatUtil.getRevisionFormat().parse(
264                 "2010-09-24");
265         Date rev20130516 = SimpleDateFormatUtil.getRevisionFormat().parse(
266                 "2013-05-16");
267         Date rev20130715 = SimpleDateFormatUtil.getRevisionFormat().parse(
268                 "2013-07-15");
269
270         final QNameModule yangTypes_20100924 = QNameModule.create(yangTypesNS,
271                 rev20100924);
272         final QNameModule yangTypes_20130516 = QNameModule.create(yangTypesNS,
273                 rev20130516);
274         final QNameModule yangTypes_20130715 = QNameModule.create(yangTypesNS,
275                 rev20130715);
276
277         final QName dateTimeTypeDef_20100924 = QName.create(yangTypes_20100924,
278                 "date-and-time");
279         final QName dateTimeTypeDef_20130516 = QName.create(yangTypes_20130516,
280                 "date-and-time");
281         final QName dateTimeTypeDef_20130715 = QName.create(yangTypes_20130715,
282                 "date-and-time");
283
284         Module yangTypesModule_20100924 = context.findModuleByName(
285                 "ietf-yang-types", rev20100924);
286         Module yangTypesModule_20130516 = context.findModuleByName(
287                 "ietf-yang-types", rev20130516);
288         Module yangTypesModule_20130715 = context.findModuleByName(
289                 "ietf-yang-types", rev20130715);
290
291         assertNotNull(yangTypesModule_20100924);
292         assertNotNull(yangTypesModule_20130516);
293         assertNotNull(yangTypesModule_20130715);
294
295         assertTrue(findTypeDef(yangTypesModule_20100924,
296                 dateTimeTypeDef_20100924));
297         assertTrue(findTypeDef(yangTypesModule_20130516,
298                 dateTimeTypeDef_20130516));
299         assertTrue(findTypeDef(yangTypesModule_20130715,
300                 dateTimeTypeDef_20130715));
301
302         checkNetconfMonitoringModuleSimpleTest(context, rev20130715,
303                 dateTimeTypeDef_20130715);
304
305         checkInterfacesModuleSimpleTest(context, rev20100924,
306                 dateTimeTypeDef_20100924);
307
308     }
309
310     private static void checkInterfacesModuleSimpleTest(final SchemaContext context,
311             final Date rev20100924, final QName dateTimeTypeDef_20100924)
312             throws URISyntaxException, ParseException {
313         String interfacesNSStr = "urn:ietf:params:xml:ns:yang:ietf-interfaces";
314         URI interfacesNS = new URI(interfacesNSStr);
315         Date rev20121115 = SimpleDateFormatUtil.getRevisionFormat().parse(
316                 "2012-11-15");
317         final QNameModule interfacesNS_20121115 = QNameModule.create(
318                 interfacesNS, rev20121115);
319         QName lastChange = QName.create(interfacesNS_20121115, "last-change");
320
321         Module interfacesModule_20121115 = context.findModuleByName(
322                 "ietf-interfaces", rev20121115);
323         assertNotNull(interfacesModule_20121115);
324
325         DataSchemaNode leafLastChange = interfacesModule_20121115
326                 .getDataChildByName(lastChange);
327         assertNotNull(leafLastChange);
328
329         assertTrue(leafLastChange instanceof LeafSchemaNode);
330         QName lastChangeTypeQName = ((LeafSchemaNode) leafLastChange).getType()
331                 .getQName();
332         assertEquals(dateTimeTypeDef_20100924, lastChangeTypeQName);
333
334         Set<ModuleImport> imports = interfacesModule_20121115.getImports();
335         assertEquals(1, imports.size());
336         ModuleImport interfacesImport = imports.iterator().next();
337         assertEquals("ietf-yang-types", interfacesImport.getModuleName());
338         assertEquals(rev20100924, interfacesImport.getRevision());
339     }
340
341     private static void checkNetconfMonitoringModuleSimpleTest(final SchemaContext context,
342             final Date rev20130715, final QName dateTimeTypeDef_20130715)
343             throws ParseException, URISyntaxException {
344         String monitoringNSStr = "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring";
345         URI monitoringNS = new URI(monitoringNSStr);
346
347         Date rev19700101 = SimpleDateFormatUtil.getRevisionFormat().parse(
348                 "1970-01-01");
349         final QNameModule monitoring_19700101 = QNameModule.create(
350                 monitoringNS, rev19700101);
351         QName lockedTime = QName.create(monitoring_19700101, "locked-time");
352
353         Module monitoringModule_19700101 = context.findModuleByName(
354                 "ietf-netconf-monitoring", rev19700101);
355         assertNotNull(monitoringModule_19700101);
356
357         DataSchemaNode leafLockedTime = monitoringModule_19700101
358                 .getDataChildByName(lockedTime);
359         assertNotNull(leafLockedTime);
360
361         assertTrue(leafLockedTime instanceof LeafSchemaNode);
362         QName lockedTimeTypeQName = ((LeafSchemaNode) leafLockedTime).getType()
363                 .getQName();
364         assertEquals(dateTimeTypeDef_20130715, lockedTimeTypeQName);
365
366         Set<ModuleImport> imports = monitoringModule_19700101.getImports();
367         assertEquals(1, imports.size());
368         ModuleImport monitoringImport = imports.iterator().next();
369         assertEquals("ietf-yang-types", monitoringImport.getModuleName());
370         assertEquals(rev20130715, monitoringImport.getRevision());
371     }
372
373     private static boolean findTypeDef(final Module module, final QName typedef) {
374         Set<TypeDefinition<?>> typeDefinitions = module.getTypeDefinitions();
375         for (TypeDefinition<?> typeDefinition : typeDefinitions) {
376             if (typeDefinition.getQName().equals(typedef)) {
377                 return true;
378             }
379         }
380         return false;
381     }
382 }