Fixed YANG union type resolving in yang model parser.
[controller.git] / opendaylight / sal / yang-prototype / code-generator / yang-model-parser-impl / src / test / java / org / opendaylight / controller / yang / model / parser / impl / YangModelParserListenerTest.java
1 /*
2  * Copyright (c) 2013 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.controller.yang.model.parser.impl;
9
10 import static org.junit.Assert.*;
11
12 import java.io.IOException;
13 import java.io.InputStream;
14 import java.net.URI;
15 import java.text.DateFormat;
16 import java.text.SimpleDateFormat;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.Date;
20 import java.util.List;
21 import java.util.Set;
22
23 import org.antlr.v4.runtime.ANTLRInputStream;
24 import org.antlr.v4.runtime.CommonTokenStream;
25 import org.antlr.v4.runtime.tree.ParseTree;
26 import org.antlr.v4.runtime.tree.ParseTreeWalker;
27 import org.junit.Test;
28 import org.opendaylight.controller.antlrv4.code.gen.YangLexer;
29 import org.opendaylight.controller.antlrv4.code.gen.YangParser;
30 import org.opendaylight.controller.model.util.Leafref;
31 import org.opendaylight.controller.model.util.UnknownType;
32 import org.opendaylight.controller.yang.common.QName;
33 import org.opendaylight.controller.yang.model.api.ContainerSchemaNode;
34 import org.opendaylight.controller.yang.model.api.DataNodeContainer;
35 import org.opendaylight.controller.yang.model.api.DataSchemaNode;
36 import org.opendaylight.controller.yang.model.api.LeafSchemaNode;
37 import org.opendaylight.controller.yang.model.api.ListSchemaNode;
38 import org.opendaylight.controller.yang.model.api.Module;
39 import org.opendaylight.controller.yang.model.api.ModuleImport;
40 import org.opendaylight.controller.yang.model.api.SchemaNode;
41 import org.opendaylight.controller.yang.model.api.SchemaPath;
42 import org.opendaylight.controller.yang.model.api.Status;
43 import org.opendaylight.controller.yang.model.api.TypeDefinition;
44 import org.opendaylight.controller.yang.model.parser.builder.impl.ModuleBuilder;
45
46 public class YangModelParserListenerTest {
47
48     @Test
49     public void testParseImport() throws Exception {
50         Module module = getModule("/abstract-topology.yang");
51
52         Set<ModuleImport> imports = module.getImports();
53         assertEquals(1, imports.size());
54         ModuleImport moduleImport = imports.iterator().next();
55
56         assertEquals("inet", moduleImport.getPrefix());
57
58         DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd");
59         Date expectedDate = simpleDateFormat.parse("2010-09-24");
60         assertEquals(expectedDate, moduleImport.getRevision());
61     }
62
63     @Test
64     public void testParseHeaders() throws Exception {
65         Module module = getModule("/abstract-topology.yang");
66
67         URI namespace = module.getNamespace();
68         URI expectedNS = URI.create("");
69         assertEquals(expectedNS, namespace);
70
71         DateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd");
72         Date expectedDate = simpleDateFormat.parse("2013-02-08");
73         assertEquals(expectedDate, module.getRevision());
74
75         String prefix = module.getPrefix();
76         String expectedPrefix = "tp";
77         assertEquals(expectedPrefix, prefix);
78
79         String expectedDescription = "This module contains the definitions of elements that creates network";
80         assertTrue(module.getDescription().contains(expectedDescription));
81
82         String expectedReference = "~~~ WILL BE DEFINED LATER";
83         assertEquals(expectedReference, module.getReference());
84
85         assertEquals("1", module.getYangVersion());
86     }
87
88     @Test
89     public void testParseLeafref() throws Exception {
90         Module module = getModule("/abstract-topology.yang");
91
92         Set<TypeDefinition<?>> typedefs = module.getTypeDefinitions();
93         assertEquals(2, typedefs.size());
94         for(TypeDefinition<?> td : typedefs) {
95             Leafref baseType = (Leafref)td.getBaseType();
96             if(td.getQName().getLocalName().equals("network-node-id-ref")) {
97                 assertEquals("/tp:topology/tp:network-nodes/tp:network-node/tp:node-id", baseType.getPathStatement().toString());
98             } else {
99                 assertEquals("/tp:topology/tp:network-links/tp:network-link/tp:link-id", baseType.getPathStatement().toString());
100             }
101         }
102     }
103
104     @Test
105     public void testParseModule() throws IOException {
106         Module module = getModule("/test-model.yang");
107
108         URI namespace = module.getNamespace();
109         Date revision = module.getRevision();
110         String prefix = module.getPrefix();
111
112         String expectedDescription = "module description";
113         assertEquals(expectedDescription, module.getDescription());
114
115         String expectedReference = "module reference";
116         assertEquals(expectedReference, module.getReference());
117
118         Set<TypeDefinition<?>> typedefs = module.getTypeDefinitions();
119         assertEquals(10, typedefs.size());
120
121         Set<DataSchemaNode> childNodes = module.getChildNodes();
122         assertEquals(1, childNodes.size());
123
124         final String containerName = "network";
125         final QName containerQName = new QName(namespace, revision, prefix, containerName);
126         ContainerSchemaNode tested = (ContainerSchemaNode) module.getChildNodes().iterator().next();
127         DataSchemaNode container1 = module.getDataChildByName(containerName);
128         DataSchemaNode container2 = module.getDataChildByName(containerQName);
129
130         assertEquals(tested, container1);
131         assertEquals(container1, container2);
132     }
133
134     @Test
135     public void testParseContainer() throws IOException {
136         Module module = getModule("/test-model.yang");
137
138         URI namespace = module.getNamespace();
139         Date revision = module.getRevision();
140         String prefix = module.getPrefix();
141         final QName containerQName = new QName(namespace, revision, prefix, "network");
142
143         ContainerSchemaNode tested = (ContainerSchemaNode)module.getDataChildByName(containerQName);
144
145         Set<DataSchemaNode> containerChildNodes = tested.getChildNodes();
146         assertEquals(3, containerChildNodes.size());
147
148         String expectedDescription = "network-description";
149         String expectedReference = "network-reference";
150         Status expectedStatus = Status.OBSOLETE;
151         testDesc_Ref_Status(tested, expectedDescription, expectedReference, expectedStatus);
152
153         List<QName> path = new ArrayList<QName>();
154         path.add(new QName(namespace, revision, prefix, "test-model"));
155         path.add(containerQName);
156         SchemaPath expectedSchemaPath = new SchemaPath(path, true);
157         assertEquals(expectedSchemaPath, tested.getPath());
158
159         assertTrue(tested.isConfiguration());
160         assertTrue(tested.isPresenceContainer());
161     }
162
163     @Test
164     public void testParseList() throws IOException {
165         Module module = getModule("/test-model.yang");
166
167         URI namespace = module.getNamespace();
168         Date revision = module.getRevision();
169         String prefix = module.getPrefix();
170         final QName listQName = new QName(namespace, revision, prefix, "topology");
171
172         DataNodeContainer networkContainer = (DataNodeContainer)module.getDataChildByName("network");
173         DataNodeContainer topologiesContainer = (DataNodeContainer)networkContainer.getDataChildByName("topologies");
174         ListSchemaNode tested = (ListSchemaNode)topologiesContainer.getDataChildByName(listQName);
175         assertEquals(listQName, tested.getQName());
176
177         String expectedDescription = "Test description of list 'topology'.";
178         String expectedReference = null;
179         Status expectedStatus = Status.CURRENT;
180         testDesc_Ref_Status(tested, expectedDescription, expectedReference, expectedStatus);
181
182         List<QName> path = new ArrayList<QName>();
183         path.add(new QName(namespace, revision, prefix, "test-model"));
184         path.add(new QName(namespace, revision, prefix, "network"));
185         path.add(new QName(namespace, revision, prefix, "topologies"));
186         path.add(listQName);
187         SchemaPath expectedSchemaPath = new SchemaPath(path, true);
188         assertEquals(expectedSchemaPath, tested.getPath());
189
190         List<QName> expectedKey = new ArrayList<QName>();
191         expectedKey.add(new QName(namespace, revision, prefix, "topology-id"));
192         assertEquals(expectedKey, tested.getKeyDefinition());
193
194         assertEquals(Collections.EMPTY_SET, tested.getTypeDefinitions());
195         assertEquals(Collections.EMPTY_SET, tested.getUses());
196         assertEquals(Collections.EMPTY_SET, tested.getGroupings());
197
198         assertTrue(tested.getDataChildByName("topology-id") instanceof LeafSchemaNode);
199     }
200
201     @Test
202     public void testParseLeaf() throws IOException {
203         Module module = getModule("/test-model.yang");
204
205         URI namespace = module.getNamespace();
206         Date revision = module.getRevision();
207         String prefix = module.getPrefix();
208         final QName leafQName = new QName(namespace, revision, prefix, "topology-id");
209
210         DataNodeContainer networkContainer = (DataNodeContainer)module.getDataChildByName("network");
211         DataNodeContainer topologiesContainer = (DataNodeContainer)networkContainer.getDataChildByName("topologies");
212         DataNodeContainer topologyList = (DataNodeContainer)topologiesContainer.getDataChildByName("topology");
213         LeafSchemaNode tested = (LeafSchemaNode)topologyList.getDataChildByName(leafQName);
214         assertEquals(leafQName, tested.getQName());
215
216         String expectedDescription = "Test description of leaf 'topology-id'";
217         String expectedReference = null;
218         Status expectedStatus = Status.CURRENT;
219         testDesc_Ref_Status(tested, expectedDescription, expectedReference, expectedStatus);
220
221         List<QName> path = new ArrayList<QName>();
222         path.add(new QName(namespace, revision, prefix, "test-model"));
223         path.add(new QName(namespace, revision, prefix, "network"));
224         path.add(new QName(namespace, revision, prefix, "topologies"));
225         path.add(new QName(namespace, revision, prefix, "topology"));
226         path.add(leafQName);
227         SchemaPath expectedSchemaPath = new SchemaPath(path, true);
228         assertEquals(expectedSchemaPath, tested.getPath());
229
230         UnknownType.Builder typeBuilder = new UnknownType.Builder(new QName(namespace, revision, prefix, "topology-id"), null, null);
231         TypeDefinition<?> expectedType = typeBuilder.build();
232         assertEquals(expectedType, tested.getType());
233     }
234
235
236     private void testDesc_Ref_Status(SchemaNode tested, String expectedDescription, String expectedReference, Status expectedStatus) {
237         assertEquals(expectedDescription, tested.getDescription());
238         assertEquals(expectedReference, tested.getReference());
239         assertEquals(expectedStatus, tested.getStatus());
240     }
241
242     private Module getModule(String testFile) throws IOException {
243         ModuleBuilder builder = getBuilder(testFile);
244         return builder.build();
245     }
246
247     private ModuleBuilder getBuilder(String fileName) throws IOException {
248         final InputStream inStream = getClass().getResourceAsStream(fileName);
249         ANTLRInputStream input = new ANTLRInputStream(inStream);
250         final YangLexer lexer = new YangLexer(input);
251         final CommonTokenStream tokens = new CommonTokenStream(lexer);
252         final YangParser parser = new YangParser(tokens);
253
254         final ParseTree tree = parser.yang();
255         final ParseTreeWalker walker = new ParseTreeWalker();
256
257         final YangModelParserListenerImpl modelParser = new YangModelParserListenerImpl();
258         walker.walk(modelParser, tree);
259         return modelParser.getModuleBuilder();
260     }
261
262 }