Added support for parsing submodules & added dependency utility parser
[yangtools.git] / code-generator / binding-generator-impl / src / test / java / org / opendaylight / yangtools / sal / binding / generator / impl / RefineTest.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.yangtools.sal.binding.generator.impl;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
14
15 import java.io.*;
16 import java.lang.reflect.InvocationTargetException;
17 import java.lang.reflect.Method;
18 import java.net.URI;
19 import java.net.URISyntaxException;
20 import java.util.*;
21
22 import org.junit.Test;
23 import org.opendaylight.yangtools.yang.common.QName;
24 import org.opendaylight.yangtools.yang.model.api.MustDefinition;
25 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
26 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
27 import org.opendaylight.yangtools.yang.parser.builder.api.DataSchemaNodeBuilder;
28 import org.opendaylight.yangtools.yang.parser.builder.api.UsesNodeBuilder;
29 import org.opendaylight.yangtools.yang.parser.builder.impl.*;
30 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
31 import org.opendaylight.yangtools.yang.parser.util.RefineHolder;
32 import org.opendaylight.yangtools.yang.parser.util.RefineUtils;
33
34 import com.google.common.collect.Lists;
35 import com.google.common.collect.Maps;
36
37 //Test for class RefineUtils
38 public class RefineTest {
39
40     private static List<File> testModels = new ArrayList<>();
41
42     private void loadTestResources() {
43         final File listModelFile = new File(RefineTest.class.getResource("/refine.yang").getPath());
44         testModels.add(listModelFile);
45     }
46
47     private void findUnknownNode(DataSchemaNodeBuilder childNode, String unknownNodeValue, String unknownNodeName) {
48         List<UnknownSchemaNodeBuilder> unknownSchemaNodesBuilder = childNode.getUnknownNodes();
49         boolean refinedUnknownNodeLflstFound = false;
50
51         for (UnknownSchemaNodeBuilder unknownSchemaNodeBuilders : unknownSchemaNodesBuilder) {
52             if (unknownSchemaNodeBuilders.getNodeType().getLocalName().equals(unknownNodeName)
53                     && unknownSchemaNodeBuilders.getQName().getLocalName().equals(unknownNodeValue)) {
54                 refinedUnknownNodeLflstFound = true;
55             }
56         }
57         assertTrue("Unknown node " + unknownNodeName + " with value " + unknownNodeValue + " wasn't found.",
58                 refinedUnknownNodeLflstFound);
59     }
60
61     private void findMustConstraint(ConstraintsBuilder conDef, String mustValue) {
62         boolean mustLflstFound = false;
63         for (MustDefinition mustDef : conDef.getMustDefinitions()) {
64             if (mustDef.toString().equals(mustValue)) {
65                 mustLflstFound = true;
66                 break;
67             }
68         }
69         assertTrue("Must element in 'lflst' is missing.", mustLflstFound);
70     }
71
72     @Test
73     public void usesInGroupingDependenciesTest() {
74         loadTestResources();
75         assertEquals("Incorrect number of test files.", 1, testModels.size());
76
77         Set<UsesNodeBuilder> usesNodeBuilders = getModuleBuilder().getUsesNodeBuilders();
78         List<RefineHolder> refineHolders = null;
79         Set<DataSchemaNodeBuilder> dataSchemaNodeBuilders = null;
80         for (UsesNodeBuilder usesNodeBuilder : usesNodeBuilders) {
81             if (usesNodeBuilder.getGroupingPathAsString().equals("grp")) {
82                 refineHolders = usesNodeBuilder.getRefines();
83                 // FIXME
84                 //GroupingUtils.updateUsesParent(usesNodeBuilder);
85                 dataSchemaNodeBuilders = usesNodeBuilder.getParent().getChildNodeBuilders();
86                 break;
87             }
88         }
89
90         assertNotNull("List of refine holders wasn't initialized.", refineHolders);
91         assertEquals("Incorrect number of refine holders", 4, refineHolders.size());
92
93         checkLflstRefineHolderAndSchemaNodeBuilder("lflst", refineHolders, dataSchemaNodeBuilders);
94         checkChcRefineHolderAndSchemaNodeBuilder("chc", refineHolders, dataSchemaNodeBuilders);
95         checkChc2RefineHolderAndSchemaNodeBuilder("chc2", refineHolders, dataSchemaNodeBuilders);
96         checkAnyXmlRefineHolderAndSchemaNodeBuilder("data", refineHolders, dataSchemaNodeBuilders);
97     }
98
99     private ModuleBuilder getModuleBuilder() {
100         Class<YangParserImpl> cl = YangParserImpl.class;
101
102         YangParserImpl yangParserImpl = null;
103         yangParserImpl = new YangParserImpl();
104         assertNotNull("Instance of YangParserImpl isn't created", yangParserImpl);
105
106         Method methodResolveModuleBuilders = null;
107         try {
108             methodResolveModuleBuilders = cl.getDeclaredMethod("resolveModuleBuilders", List.class, Map.class, SchemaContext.class);
109         } catch (NoSuchMethodException | SecurityException e1) {
110         }
111         assertNotNull("The method resolveModuleBuilders cannot be found", methodResolveModuleBuilders);
112
113         final Map<InputStream, File> inputStreams = Maps.newHashMap();
114
115         for (final File yangFile : testModels) {
116             try {
117                 inputStreams.put(new FileInputStream(yangFile), yangFile);
118             } catch (FileNotFoundException e) {
119             }
120         }
121         assertEquals("Map with input streams contains incorrect number of files.", 1, inputStreams.size());
122
123         Map<ModuleBuilder, InputStream> builderToStreamMap = Maps.newHashMap();
124         Map<String, Map<Date, ModuleBuilder>> modules = null;
125         try {
126             methodResolveModuleBuilders.setAccessible(true);
127             modules = (Map<String, Map<Date, ModuleBuilder>>) methodResolveModuleBuilders.invoke(yangParserImpl,
128                     Lists.newArrayList(inputStreams.keySet()), builderToStreamMap, null);
129         } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
130             e.printStackTrace();
131         }
132         assertEquals("Map with modules contains incorrect number of modules", 1, modules.size());
133         Map<Date, ModuleBuilder> mapWithModuleBuilder = modules.get("module-refine");
134         assertEquals("Map with module builders contains incorrect number of modules", 1, mapWithModuleBuilder.size());
135         Date date = new GregorianCalendar(2013, GregorianCalendar.SEPTEMBER, 11).getTime();
136         ModuleBuilder moduleBuilder = mapWithModuleBuilder.get(date);
137         assertNotNull("Module builder wasn't find", moduleBuilder);
138         return moduleBuilder;
139     }
140
141     private void checkAnyXmlRefineHolderAndSchemaNodeBuilder(String string, List<RefineHolder> refineHolders,
142             Set<DataSchemaNodeBuilder> dataSchemaNodeBuilders) {
143         RefineHolder refHolderData = getRefineHolder("data", refineHolders);
144
145         QName qname = createQname();
146         DataSchemaNodeBuilder builderData = new AnyXmlBuilder("module", 4, qname, createSchemaPath(qname));
147
148         assertNotNull("Refine holder data wasn't initialized.", refHolderData);
149         RefineUtils.refineAnyxml((AnyXmlBuilder) builderData, refHolderData);
150
151         // data node
152         ConstraintsBuilder conDefData = builderData.getConstraints();
153         assertFalse("'data' has incorrect value for 'mandatory'", conDefData.isMandatory());
154
155         String unknownNodeDataValue = "some value from data";
156         String unknownNodeDataName = "new-subnode-data";
157         findUnknownNode(builderData, unknownNodeDataValue, unknownNodeDataName);
158         findMustConstraint(conDefData, "something-else = 9");
159
160     }
161
162     private void checkChc2RefineHolderAndSchemaNodeBuilder(String nodeName, List<RefineHolder> refineHolders,
163             Set<DataSchemaNodeBuilder> dataSchemaNodeBuilders) {
164         RefineHolder refHolderChc2 = getRefineHolder("chc2", refineHolders);
165
166         QName qname = createQname();
167         List<QName> path = Lists.newArrayList(qname);
168         DataSchemaNodeBuilder builderChc2 = new ChoiceBuilder("module", 4, qname, new SchemaPath(path, true));
169         assertNotNull("Refine holder chc2 wasn't initialized.", refHolderChc2);
170
171         RefineUtils.refineChoice((ChoiceBuilder) builderChc2, refHolderChc2);
172
173         // chc2 node
174         ConstraintsBuilder conDefChc2 = builderChc2.getConstraints();
175         assertFalse("'chc2' has incorrect value for 'mandatory'", conDefChc2.isMandatory());
176     }
177
178     private void checkChcRefineHolderAndSchemaNodeBuilder(String nodeName, List<RefineHolder> refineHolders,
179             Set<DataSchemaNodeBuilder> dataSchemaNodeBuilders) {
180         RefineHolder refHolderChc = getRefineHolder("chc", refineHolders);
181
182         QName qname = createQname();
183         List<QName> path = Lists.newArrayList(qname);
184         DataSchemaNodeBuilder builderChc = new ChoiceBuilder("module", 4, qname, new SchemaPath(path, true));
185
186         assertNotNull("Refine holder chc wasn't initialized.", refHolderChc);
187         assertNotNull("Data schema node builder chc wasn't initialized.", builderChc);
188         RefineUtils.refineChoice((ChoiceBuilder) builderChc, refHolderChc);
189
190         ChoiceBuilder choiceBuilder = null;
191         if (builderChc instanceof ChoiceBuilder) {
192             choiceBuilder = (ChoiceBuilder) builderChc;
193         }
194         assertNotNull("Choice node chc isn't of type ChoiceBuilder", choiceBuilder);
195         assertEquals("chc node has incorrect default node.", "first", choiceBuilder.getDefaultCase());
196         String unknownNodeChcValue = "some value from chc";
197         String unknownNodeChcName = "new-subnode-chc";
198         findUnknownNode(choiceBuilder, unknownNodeChcValue, unknownNodeChcName);
199     }
200
201     private void checkLflstRefineHolderAndSchemaNodeBuilder(String nodeName, List<RefineHolder> refineHolders,
202             Set<DataSchemaNodeBuilder> dataSchemaNodeBuilders) {
203         RefineHolder refHolderLflst = getRefineHolder(nodeName, refineHolders);
204
205         QName qname = createQname();
206         DataSchemaNodeBuilder builderLflst = new LeafListSchemaNodeBuilder("module", 4, qname, createSchemaPath(qname));
207
208         assertNotNull("Refine holder " + nodeName + " wasn't initialized.", refHolderLflst);
209         assertNotNull("Data schema node builder " + nodeName + " wasn't initialized.", builderLflst);
210         RefineUtils.refineLeafList((LeafListSchemaNodeBuilder) builderLflst, refHolderLflst);
211         // lflst node
212
213         ConstraintsBuilder conDefLflst = builderLflst.getConstraints();
214         assertEquals("Max elements number in " + nodeName + " is incorrect.", new Integer(64),
215                 conDefLflst.getMaxElements());
216         assertEquals("Max elements number in " + nodeName + " is incorrect.", new Integer(32),
217                 conDefLflst.getMinElements());
218
219         findMustConstraint(conDefLflst, "new = 57");
220
221         boolean mustLflstFound = false;
222         for (MustDefinition mustDef : conDefLflst.getMustDefinitions()) {
223             if (mustDef.toString().equals("new = 57")) {
224                 mustLflstFound = true;
225                 break;
226             }
227         }
228         assertTrue("Must element in " + nodeName + " is missing.", mustLflstFound);
229
230         findUnknownNode(builderLflst, "some value from " + nodeName, "new-subnode");
231
232     }
233
234     private RefineHolder getRefineHolder(String refHolderName, List<RefineHolder> refineHolders) {
235         for (RefineHolder refineHolder : refineHolders) {
236             if (refineHolder.getName().equals(refHolderName)) {
237                 return refineHolder;
238             }
239         }
240         return null;
241     }
242
243     private QName createQname() {
244         QName qname = null;
245         boolean uriCreated = false;
246         try {
247             qname = new QName(new URI("uri"), "q name");
248             uriCreated = true;
249         } catch (URISyntaxException e) {
250         }
251         assertTrue("Qname wasn't created sucessfully.", uriCreated);
252         return qname;
253     }
254
255     private SchemaPath createSchemaPath(QName qname) {
256         List<QName> qnames = new ArrayList<>();
257         qnames.add(createQname());
258         return new SchemaPath(qnames, true);
259     }
260
261 }