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