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