Adjust to yangtools-2.0.0 changes
[mdsal.git] / binding / mdsal-binding-java-api-generator / src / test / java / org / opendaylight / mdsal / binding / java / api / generator / test / CompilationTest.java
1 /*
2  * Copyright (c) 2016 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.mdsal.binding.java.api.generator.test;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
13
14 import com.google.common.collect.Collections2;
15 import com.google.common.collect.ImmutableSet;
16 import com.google.common.collect.Range;
17 import java.io.File;
18 import java.io.IOException;
19 import java.lang.annotation.Annotation;
20 import java.lang.reflect.Field;
21 import java.lang.reflect.Method;
22 import java.lang.reflect.Modifier;
23 import java.lang.reflect.ParameterizedType;
24 import java.lang.reflect.WildcardType;
25 import java.math.BigDecimal;
26 import java.math.BigInteger;
27 import java.net.URISyntaxException;
28 import java.net.URL;
29 import java.net.URLClassLoader;
30 import java.util.ArrayList;
31 import java.util.Arrays;
32 import java.util.Collection;
33 import java.util.Collections;
34 import java.util.List;
35 import org.junit.Test;
36 import org.opendaylight.mdsal.binding.java.api.generator.GeneratorJavaFile;
37 import org.opendaylight.mdsal.binding.model.api.Type;
38 import org.opendaylight.yangtools.yang.binding.ChildOf;
39 import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext;
40 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
41 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
42
43 /**
44  * Test correct code generation.
45  *
46  */
47 public class CompilationTest extends BaseCompilationTest {
48
49     /*
50      * Java 8 allows JaCoCo to hook onto interfaces, as well as
51      * generating a default implementation. We only want to check
52      * abstract methods.
53      */
54     private static Collection<Method> abstractMethods(final Class<?> clazz) {
55         // Filter out
56         return Collections2.filter(Arrays.asList(clazz.getDeclaredMethods()), input -> Modifier.isAbstract(input.getModifiers()));
57     }
58
59     @Test
60     public void testListGeneration() throws Exception {
61         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "list-gen");
62         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
63         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "list-gen");
64         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
65
66         generateTestSources("/compilation/list-gen", sourcesOutputDir);
67
68         // Test if all sources are generated
69         File parent = new File(sourcesOutputDir, CompilationTestUtils.NS_TEST);
70         final File keyArgs = new File(parent, "KeyArgs.java");
71         final File links = new File(parent, "Links.java");
72         final File linksBuilder = new File(parent, "LinksBuilder.java");
73         final File linksKey = new File(parent, "LinksKey.java");
74         final File testData = new File(parent, "TestData.java");
75         assertTrue(keyArgs.exists());
76         assertTrue(links.exists());
77         assertTrue(linksBuilder.exists());
78         assertTrue(linksKey.exists());
79         assertTrue(testData.exists());
80         CompilationTestUtils.assertFilesCount(parent, 6);
81
82         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_TEST + CompilationTestUtils.FS + "links");
83         final File level = new File(parent, "Level.java");
84         final File linkGroup = new File(parent, "LinkGroup.java");
85         final File node = new File(parent, "Node.java");
86         final File nodeBuilder = new File(parent, "NodeBuilder.java");
87         final File nodeList = new File(parent, "NodeList.java");
88         final File nodeListBuilder = new File(parent, "NodeListBuilder.java");
89         final File nodesType = new File(parent, "NodesType.java");
90         assertTrue(level.exists());
91         assertTrue(linkGroup.exists());
92         assertTrue(node.exists());
93         assertTrue(nodeBuilder.exists());
94         assertTrue(nodeList.exists());
95         assertTrue(nodeListBuilder.exists());
96         assertTrue(nodesType.exists());
97         CompilationTestUtils.assertFilesCount(parent, 7);
98
99         // Test if sources are compilable
100         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
101
102         final ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
103         final Class<?> keyArgsClass = Class.forName(CompilationTestUtils.BASE_PKG + ".urn.opendaylight.test.rev131008.KeyArgs", true, loader);
104         final Class<?> linksClass = Class.forName(CompilationTestUtils.BASE_PKG + ".urn.opendaylight.test.rev131008.Links", true, loader);
105         final Class<?> linksKeyClass = Class.forName(CompilationTestUtils.BASE_PKG + ".urn.opendaylight.test.rev131008.LinksKey", true, loader);
106
107         // Test generated 'grouping key-args'
108         assertTrue(keyArgsClass.isInterface());
109         CompilationTestUtils.assertContainsMethod(keyArgsClass, String.class, "getName");
110         CompilationTestUtils.assertContainsMethod(keyArgsClass, Integer.class, "getSize");
111         assertEquals(2, abstractMethods(keyArgsClass).size());
112
113         // Test generated 'list links'
114         assertTrue(linksClass.isInterface());
115         CompilationTestUtils.assertImplementsIfc(linksClass, keyArgsClass);
116         // TODO: anyxml
117         assertEquals(6, abstractMethods(linksClass).size());
118
119         // Test list key constructor arguments ordering
120         CompilationTestUtils.assertContainsConstructor(linksKeyClass, Byte.class, String.class, Integer.class);
121         // Test serialVersionUID generation
122         final Field suid = CompilationTestUtils.assertContainsField(linksKeyClass, "serialVersionUID", Long.TYPE);
123         suid.setAccessible(true);
124         assertEquals(-8829501012356283881L, suid.getLong(null));
125
126         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
127     }
128
129     @Test
130     public void testAugmentUnderUsesGeneration() throws Exception {
131         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "augment-under-uses");
132         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
133         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "augment-under-uses");
134         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
135
136         generateTestSources("/compilation/augment-under-uses", sourcesOutputDir);
137
138         // Test if all sources were generated from 'module foo'
139         File parent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO);
140         assertTrue(new File(parent, "Object.java").exists());
141         assertTrue(new File(parent, "ClosedObject.java").exists());
142         assertTrue(new File(parent, "OpenObject.java").exists());
143         assertTrue(new File(parent, "ExplicitRouteObject.java").exists());
144         assertTrue(new File(parent, "PathKeySubobject.java").exists());
145         CompilationTestUtils.assertFilesCount(parent, 9);
146
147         parent = new File(parent, "object");
148         assertTrue(new File(parent, "Nodes.java").exists());
149         assertTrue(new File(parent, "NodesBuilder.java").exists());
150         CompilationTestUtils.assertFilesCount(parent, 2);
151
152         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO + CompilationTestUtils.FS + "closed");
153         CompilationTestUtils.assertFilesCount(parent, 1);
154
155         parent = new File(parent, "object");
156         assertTrue(new File(parent, "Link1.java").exists());
157         assertTrue(new File(parent, "Link1Builder.java").exists());
158         CompilationTestUtils.assertFilesCount(parent, 2);
159
160         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO + CompilationTestUtils.FS + "open");
161         CompilationTestUtils.assertFilesCount(parent, 1);
162
163         parent = new File(parent, "object");
164         assertTrue(new File(parent, "Nodes1.java").exists());
165         assertTrue(new File(parent, "Nodes1Builder.java").exists());
166         CompilationTestUtils.assertFilesCount(parent, 3);
167
168         parent = new File(parent, "nodes");
169         assertTrue(new File(parent, "Links.java").exists());
170         assertTrue(new File(parent, "LinksBuilder.java").exists());
171         CompilationTestUtils.assertFilesCount(parent, 2);
172
173         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO + CompilationTestUtils.FS + "explicit");
174         CompilationTestUtils.assertFilesCount(parent, 1);
175         parent = new File(parent, "route");
176         CompilationTestUtils.assertFilesCount(parent, 1);
177         parent = new File(parent, "object");
178         assertTrue(new File(parent, "Subobjects.java").exists());
179         assertTrue(new File(parent, "SubobjectsBuilder.java").exists());
180         CompilationTestUtils.assertFilesCount(parent, 3);
181
182         parent = new File(parent, "subobjects");
183         CompilationTestUtils.assertFilesCount(parent, 1);
184         parent = new File(parent, "subobject");
185         CompilationTestUtils.assertFilesCount(parent, 1);
186         parent = new File(parent, "type");
187         assertTrue(new File(parent, "PathKey.java").exists());
188         assertTrue(new File(parent, "PathKeyBuilder.java").exists());
189         CompilationTestUtils.assertFilesCount(parent, 3);
190
191         parent = new File(parent, "path");
192         CompilationTestUtils.assertFilesCount(parent, 1);
193         parent = new File(parent, "key");
194         assertTrue(new File(parent, "PathKey.java").exists());
195         assertTrue(new File(parent, "PathKeyBuilder.java").exists());
196         CompilationTestUtils.assertFilesCount(parent, 2);
197
198         // Test if all sources were generated from 'module bar'
199         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_BAR);
200         assertTrue(new File(parent, "BasicExplicitRouteSubobjects.java").exists());
201         assertTrue(new File(parent, "ExplicitRouteSubobjects.java").exists());
202         assertTrue(new File(parent, "RouteSubobjects.java").exists());
203         CompilationTestUtils.assertFilesCount(parent, 5);
204
205         parent = new File(parent, "route");
206         CompilationTestUtils.assertFilesCount(parent, 1);
207         parent = new File(new File(sourcesOutputDir, CompilationTestUtils.NS_BAR), "basic");
208         CompilationTestUtils.assertFilesCount(parent, 1);
209         parent = new File(parent, "explicit");
210         CompilationTestUtils.assertFilesCount(parent, 1);
211         parent = new File(parent, "route");
212         CompilationTestUtils.assertFilesCount(parent, 1);
213
214         parent = new File(parent, "subobjects");
215         CompilationTestUtils.assertFilesCount(parent, 2);
216         assertTrue(new File(parent, "SubobjectType.java").exists());
217
218         parent = new File(parent, "subobject");
219         CompilationTestUtils.assertFilesCount(parent, 1);
220
221         parent = new File(parent, "type");
222         assertTrue(new File(parent, "IpPrefix.java").exists());
223         assertTrue(new File(parent, "IpPrefixBuilder.java").exists());
224         assertTrue(new File(parent, "Label.java").exists());
225         assertTrue(new File(parent, "LabelBuilder.java").exists());
226         CompilationTestUtils.assertFilesCount(parent, 4);
227
228         // Test if sources are compilable
229         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
230
231         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
232     }
233
234     @Test
235     public void testAugmentOfAugmentGeneration() throws Exception {
236         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "aug-of-aug");
237         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
238         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "aug-of-aug");
239         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
240
241         generateTestSources("/compilation/augment-of-augment", sourcesOutputDir);
242
243         // Test if all sources were generated from 'module foo'
244         File parent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO);
245         final File fooListener = new File(parent, "FooListener.java");
246         File pathAttributes = new File(parent, "PathAttributes.java");
247         final File update = new File(parent, "Update.java");
248         final File updateBuilder = new File(parent, "UpdateBuilder.java");
249         assertTrue(fooListener.exists());
250         assertTrue(pathAttributes.exists());
251         assertTrue(update.exists());
252         assertTrue(updateBuilder.exists());
253         CompilationTestUtils.assertFilesCount(parent, 6);
254
255         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO + CompilationTestUtils.FS + "path");
256         CompilationTestUtils.assertFilesCount(parent, 1);
257         parent = new File(parent, "attributes");
258         CompilationTestUtils.assertFilesCount(parent, 2);
259         final File origin = new File(parent, "Origin.java");
260         final File originBuilder = new File(parent, "OriginBuilder.java");
261         assertTrue(origin.exists());
262         assertTrue(originBuilder.exists());
263
264         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO + CompilationTestUtils.FS + "update");
265         CompilationTestUtils.assertFilesCount(parent, 2);
266         pathAttributes = new File(parent, "PathAttributes.java");
267         final File pathAttributesBuilder = new File(parent, "PathAttributesBuilder.java");
268         assertTrue(pathAttributes.exists());
269         assertTrue(pathAttributesBuilder.exists());
270
271         // Test if all sources were generated from 'module bar'
272         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_BAR);
273         final File destination = new File(parent, "Destination.java");
274         final File pathAttributes1 = new File(parent, "PathAttributes1.java");
275         final File pathAttributes1Builder = new File(parent, "PathAttributes1Builder.java");
276         assertTrue(destination.exists());
277         assertTrue(pathAttributes1.exists());
278         assertTrue(pathAttributes1Builder.exists());
279         CompilationTestUtils.assertFilesCount(parent, 5);
280
281         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_BAR + CompilationTestUtils.FS + "destination");
282         CompilationTestUtils.assertFilesCount(parent, 2);
283         final File destinationType = new File(parent, "DestinationType.java");
284         assertTrue(destinationType.exists());
285
286         parent = new File(parent, "destination");
287         CompilationTestUtils.assertFilesCount(parent, 1);
288         parent = new File(parent, "type");
289         CompilationTestUtils.assertFilesCount(parent, 2);
290         final File destinationIpv4 = new File(parent, "DestinationIp.java");
291         final File destinationIpv4Builder = new File(parent, "DestinationIpBuilder.java");
292         assertTrue(destinationIpv4.exists());
293         assertTrue(destinationIpv4Builder.exists());
294
295         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_BAR + CompilationTestUtils.FS + "update");
296         CompilationTestUtils.assertFilesCount(parent, 1);
297         parent = new File(parent, "path");
298         CompilationTestUtils.assertFilesCount(parent, 1);
299         parent = new File(parent, "attributes");
300         final File mpUnreachNlri = new File(parent, "MpUnreachNlri.java");
301         final File mpUnreachNlriBuilder = new File(parent, "MpUnreachNlriBuilder.java");
302         assertTrue(mpUnreachNlri.exists());
303         assertTrue(mpUnreachNlriBuilder.exists());
304         CompilationTestUtils.assertFilesCount(parent, 3);
305
306         parent = new File(parent, "mp");
307         CompilationTestUtils.assertFilesCount(parent, 1);
308         parent = new File(parent, "unreach");
309         CompilationTestUtils.assertFilesCount(parent, 1);
310         parent = new File(parent, "nlri");
311         final File withdrawnRoutes = new File(parent, "WithdrawnRoutes.java");
312         final File withdrawnRoutesBuilder = new File(parent, "WithdrawnRoutesBuilder.java");
313         assertTrue(withdrawnRoutes.exists());
314         assertTrue(withdrawnRoutesBuilder.exists());
315         CompilationTestUtils.assertFilesCount(parent, 2);
316
317         // Test if all sources were generated from 'module baz'
318         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_BAZ);
319         CompilationTestUtils.assertFilesCount(parent, 2);
320         final File linkstateDestination = new File(parent, "LinkstateDestination.java");
321         assertTrue(linkstateDestination.exists());
322
323         parent = new File(sourcesOutputDir, CompilationTestUtils.NS_BAZ + CompilationTestUtils.FS + "update");
324         CompilationTestUtils.assertFilesCount(parent, 1);
325         parent = new File(parent, "path");
326         CompilationTestUtils.assertFilesCount(parent, 1);
327         parent = new File(parent, "attributes");
328         CompilationTestUtils.assertFilesCount(parent, 1);
329         parent = new File(parent, "mp");
330         CompilationTestUtils.assertFilesCount(parent, 1);
331         parent = new File(parent, "unreach");
332         CompilationTestUtils.assertFilesCount(parent, 1);
333         parent = new File(parent, "nlri");
334         CompilationTestUtils.assertFilesCount(parent, 1);
335         parent = new File(parent, "withdrawn");
336         CompilationTestUtils.assertFilesCount(parent, 1);
337         parent = new File(parent, "routes");
338         CompilationTestUtils.assertFilesCount(parent, 1);
339         parent = new File(parent, "destination");
340         CompilationTestUtils.assertFilesCount(parent, 1);
341         parent = new File(parent, "type");
342         final File destinationLinkstate = new File(parent, "DestinationLinkstate.java");
343         final File destinationLinkstateBuilder = new File(parent, "DestinationLinkstateBuilder.java");
344         assertTrue(destinationLinkstate.exists());
345         assertTrue(destinationLinkstateBuilder.exists());
346         CompilationTestUtils.assertFilesCount(parent, 3);
347         parent = new File(parent, "destination");
348         CompilationTestUtils.assertFilesCount(parent, 1);
349         parent = new File(parent, "linkstate");
350         final File links = new File(parent, "Links.java");
351         final File linksBuilder = new File(parent, "LinksBuilder.java");
352         assertTrue(links.exists());
353         assertTrue(linksBuilder.exists());
354         CompilationTestUtils.assertFilesCount(parent, 3);
355         parent = new File(parent, "links");
356         final File source = new File(parent, "Source.java");
357         final File sourceBuilder = new File(parent, "SourceBuilder.java");
358         assertTrue(source.exists());
359         assertTrue(sourceBuilder.exists());
360         CompilationTestUtils.assertFilesCount(parent, 3);
361         parent = new File(parent, "source");
362         final File address = new File(parent, "Address.java");
363         final File addressBuilder = new File(parent, "AddressBuilder.java");
364         assertTrue(address.exists());
365         assertTrue(addressBuilder.exists());
366         CompilationTestUtils.assertFilesCount(parent, 2);
367
368         // Test if sources are compilable
369         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
370
371         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
372     }
373
374     @Test
375     public void testLeafReturnTypes() throws Exception {
376         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "leaf-return-types");
377         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
378         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "leaf-return-types");
379         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
380
381         generateTestSources("/compilation/leaf-return-types", sourcesOutputDir);
382
383         final File parent = new File(sourcesOutputDir, CompilationTestUtils.NS_TEST);
384         assertTrue(new File(parent, "TestData.java").exists());
385         assertTrue(new File(parent, "Nodes.java").exists());
386         assertTrue(new File(parent, "NodesBuilder.java").exists());
387         assertTrue(new File(parent, "Alg.java").exists());
388         assertTrue(new File(parent, "NodesIdUnionBuilder.java").exists());
389         CompilationTestUtils.assertFilesCount(parent, 5);
390
391         // Test if sources are compilable
392         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
393
394         final String pkg = CompilationTestUtils.BASE_PKG + ".urn.opendaylight.test.rev131008";
395         final ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
396         final Class<?> nodesClass = Class.forName(pkg + ".Nodes", true, loader);
397         final Class<?> builderClass = Class.forName(pkg + ".NodesBuilder", true, loader);
398
399         // Test methods return type
400         final byte[] b = new byte[] {};
401         CompilationTestUtils.assertContainsMethod(nodesClass, b.getClass(), "getIdBinary");
402         CompilationTestUtils.assertContainsMethod(nodesClass, pkg + ".Nodes$IdBits", "getIdBits", loader);
403         CompilationTestUtils.assertContainsMethod(nodesClass, Boolean.class, "isIdBoolean");
404         CompilationTestUtils.assertContainsMethod(nodesClass, BigDecimal.class, "getIdDecimal64");
405         CompilationTestUtils.assertContainsMethod(nodesClass, Boolean.class, "isIdEmpty");
406         CompilationTestUtils.assertContainsMethod(nodesClass, pkg + ".Nodes$IdEnumeration", "getIdEnumeration", loader);
407         testReturnTypeIdentityref(nodesClass, "getIdIdentityref", pkg + ".Alg");
408         testReturnTypeInstanceIdentitifer(loader, nodesClass, "getIdInstanceIdentifier");
409         CompilationTestUtils.assertContainsMethod(nodesClass, Byte.class, "getId8");
410         CompilationTestUtils.assertContainsMethod(nodesClass, Short.class, "getId16");
411         CompilationTestUtils.assertContainsMethod(nodesClass, Integer.class, "getId32");
412         CompilationTestUtils.assertContainsMethod(nodesClass, Long.class, "getId64");
413         CompilationTestUtils.assertContainsMethod(nodesClass, Long.class, "getIdLeafref");
414         CompilationTestUtils.assertContainsMethod(nodesClass, String.class, "getIdString");
415         CompilationTestUtils.assertContainsMethod(nodesClass, Short.class, "getIdU8");
416         CompilationTestUtils.assertContainsMethod(nodesClass, Integer.class, "getIdU16");
417         CompilationTestUtils.assertContainsMethod(nodesClass, Long.class, "getIdU32");
418         CompilationTestUtils.assertContainsMethod(nodesClass, BigInteger.class, "getIdU64");
419         CompilationTestUtils.assertContainsMethod(nodesClass, pkg + ".Nodes$IdUnion", "getIdUnion", loader);
420
421         final Object builderObj = builderClass.newInstance();
422
423         Method m = CompilationTestUtils.assertContainsMethod(builderClass, builderClass, "setIdBinary", b.getClass());
424         final List<Range<Integer>> lengthConstraints = new ArrayList<>();
425         lengthConstraints.add(Range.closed(1, 10));
426         byte[] arg = new byte[] {};
427         String expectedMsg = String.format("Invalid length: %s, expected: %s.", Arrays.toString(arg), lengthConstraints);
428         CompilationTestUtils.assertContainsRestrictionCheck(builderObj, m, expectedMsg, arg);
429
430         m = CompilationTestUtils.assertContainsMethod(builderClass, builderClass, "setIdDecimal64", BigDecimal.class);
431         final List<Range<BigDecimal>> rangeConstraints = new ArrayList<>();
432         rangeConstraints.add(Range.closed(new BigDecimal("1.5"), new BigDecimal("5.5")));
433         Object arg1 = new BigDecimal("1.4");
434         expectedMsg = String.format("Invalid range: %s, expected: %s.", arg1, rangeConstraints);
435         CompilationTestUtils.assertContainsRestrictionCheck(builderObj, m, expectedMsg, arg1);
436
437         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
438     }
439
440     @Test
441     public void testGenerationContextReferenceExtension() throws Exception {
442         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "context-reference");
443         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
444         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "context-reference");
445         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
446
447         generateTestSources("/compilation/context-reference", sourcesOutputDir);
448
449         // Test if all sources are generated
450         final File fooParent = new File(sourcesOutputDir, CompilationTestUtils.NS_FOO);
451         CompilationTestUtils.assertFilesCount(fooParent, 3);
452         assertTrue(new File(fooParent, "FooData.java").exists());
453         assertTrue(new File(fooParent, "Nodes.java").exists());
454         assertTrue(new File(fooParent, "NodesBuilder.java").exists());
455
456         final File barParent = new File(sourcesOutputDir, CompilationTestUtils.NS_BAR);
457         CompilationTestUtils.assertFilesCount(barParent, 1);
458         assertTrue(new File(barParent, "IdentityClass.java").exists());
459
460         // Test if sources are compilable
461         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
462
463         final ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
464         final Class<?> nodesClass = Class.forName(CompilationTestUtils.BASE_PKG + ".urn.opendaylight.foo.rev131008.Nodes", true, loader);
465         final Class<?> identityClass = Class
466                 .forName(CompilationTestUtils.BASE_PKG + ".urn.opendaylight.bar.rev131008.IdentityClass", true, loader);
467
468         // test identity
469         try {
470             identityClass.getConstructor();
471             final Class<?> baseIdentity = Class.forName("org.opendaylight.yangtools.yang.binding.BaseIdentity", true, loader);
472             assertEquals(baseIdentity, identityClass.getSuperclass());
473         } catch (final NoSuchMethodException e) {
474             throw new AssertionError("IdentityClass must have no-arg constructor");
475         }
476
477         // Test annotation
478         try {
479             final Method getId = nodesClass.getMethod("getId");
480             final Annotation[] annotations = getId.getAnnotations();
481             assertEquals(1, annotations.length);
482             final Annotation routingContext = annotations[0];
483             assertEquals(RoutingContext.class, routingContext.annotationType());
484         } catch (final NoSuchMethodException e) {
485             throw new AssertionError("Method getId() not found");
486         }
487
488         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
489     }
490
491     @Test
492     public void compilationTest() throws Exception {
493         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "yang");
494         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
495         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "yang");
496         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
497
498         generateTestSources("/yang", sourcesOutputDir);
499
500         // Test if sources are compilable
501         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
502
503         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
504     }
505
506     @Test
507     public void testBug586() throws Exception {
508         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "bug586");
509         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
510         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "bug586");
511         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
512
513         generateTestSources("/compilation/bug586", sourcesOutputDir);
514
515         // Test if sources are compilable
516         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
517
518         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
519     }
520
521     @Test
522     public void testBug4760() throws Exception {
523         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "bug4760");
524         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
525         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "bug4760");
526         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
527
528         generateTestSources("/compilation/bug4760", sourcesOutputDir);
529
530         // Test if sources are compilable
531         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
532
533         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
534     }
535
536     /**
537      * Test handling nested uses-augmentations.
538      *
539      * @throws Exception
540      */
541     @Test
542     public void testBug1172() throws Exception {
543         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "bug1172");
544         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
545         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "bug1172");
546         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
547
548         generateTestSources("/compilation/bug1172", sourcesOutputDir);
549
550         // Test if sources are compilable
551         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
552
553         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
554     }
555
556     @Test
557     public void testBug5461() throws Exception {
558         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "bug5461");
559         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
560         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "bug5461");
561         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
562
563         generateTestSources("/compilation/bug5461", sourcesOutputDir);
564
565         // Test if sources are compilable
566         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
567
568         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
569     }
570
571     @Test
572     public void testBug5882() throws Exception {
573         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "bug5882");
574         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
575         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "bug5882");
576         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
577         generateTestSources("/compilation/bug5882", sourcesOutputDir);
578
579         // Test if sources are compilable
580         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
581
582         final File parent = new File(sourcesOutputDir, CompilationTestUtils.NS_BUG5882);
583         assertTrue(new File(parent, "FooData.java").exists());
584         assertTrue(new File(parent, "TypedefCurrent.java").exists());
585         assertTrue(new File(parent, "TypedefDeprecated.java").exists());
586
587         final String pkg = CompilationTestUtils.BASE_PKG + ".urn.yang.foo.rev160102";
588         final ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
589         final Class<?> cls = loader.loadClass(pkg + ".FooData");
590         final Class<?> clsContainer = loader.loadClass(pkg + ".ContainerMain");
591         final Class<?> clsTypedefDepr = loader.loadClass(pkg + ".TypedefDeprecated");
592         final Class<?> clsTypedefCur = loader.loadClass(pkg + ".TypedefCurrent");
593         final Class<?> clsGroupingDepr = loader.loadClass(pkg + ".GroupingDeprecated");
594         final Class<?> clsGroupingCur = loader.loadClass(pkg + ".GroupingCurrent");
595         final Class<?> clsTypeDef1 = loader.loadClass(pkg + ".Typedef1");
596         final Class<?> clsTypeDef2 = loader.loadClass(pkg + ".Typedef2");
597         final Class<?> clsTypeDef3 = loader.loadClass(pkg + ".Typedef3");
598         assertTrue(clsTypedefDepr.getAnnotations()[0].toString().contains("Deprecated"));
599         assertTrue(clsTypedefCur.getAnnotations().length == 0);
600         assertTrue(clsGroupingDepr.getAnnotations()[0].toString().contains("Deprecated"));
601         assertTrue(clsGroupingCur.getAnnotations().length == 0);
602         assertTrue(clsTypeDef1.getAnnotations().length == 0);
603         assertTrue(clsTypeDef3.getAnnotations().length == 0);
604         assertTrue(clsTypeDef2.getAnnotations()[0].toString().contains("Deprecated"));
605
606         /*methods inside container*/
607         assertTrue(clsContainer.getMethod("getContainerMainLeafDepr").isAnnotationPresent(Deprecated.class));
608         assertTrue(clsContainer.getMethod("getContainerMainListDepr").isAnnotationPresent(Deprecated.class));
609         assertTrue(clsContainer.getMethod("getContainerMainChoiceDepr").isAnnotationPresent(Deprecated.class));
610         assertFalse(clsContainer.getMethod("getContainerMainLeafCurrent").isAnnotationPresent(Deprecated.class));
611         assertFalse(clsContainer.getMethod("getContainerMainListCurrent").isAnnotationPresent(Deprecated.class));
612         assertFalse(clsContainer.getMethod("getContainerMainChoiceCur").isAnnotationPresent(Deprecated.class));
613
614         /*methods inside module*/
615         assertTrue(cls.getMethod("getContainerMainLeafDepr").isAnnotationPresent(Deprecated.class));
616         assertTrue(cls.getMethod("getContainerMainListDepr").isAnnotationPresent(Deprecated.class));
617         assertTrue(cls.getMethod("getContainerMainChoiceDepr").isAnnotationPresent(Deprecated.class));
618         assertFalse(cls.getMethod("getContainerMainLeafCurrent").isAnnotationPresent(Deprecated.class));
619         assertFalse(cls.getMethod("getContainerMainListCurrent").isAnnotationPresent(Deprecated.class));
620         assertFalse(cls.getMethod("getContainerMainChoiceCur").isAnnotationPresent(Deprecated.class));
621         assertTrue(cls.getMethod("getLeafDeprecated").isAnnotationPresent(Deprecated.class));
622
623         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
624     }
625
626     /**
627      * Test if class generated for node from grouping implements ChildOf.
628      *
629      * @throws Exception
630      */
631     @Test
632     public void testBug1377() throws Exception {
633         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "bug1377");
634         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
635         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "bug1377");
636         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
637
638         generateTestSources("/compilation/bug1377", sourcesOutputDir);
639
640         // Test if sources are compilable
641         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
642
643         final ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
644         final Class<?> outputActionClass = Class.forName(CompilationTestUtils.BASE_PKG
645                 + ".urn.test.foo.rev140717.action.action.output.action._case.OutputAction", true, loader);
646         final Class<?> actionClass = Class.forName(CompilationTestUtils.BASE_PKG + ".urn.test.foo.rev140717.Action", true, loader);
647
648         // Test generated 'container output-action'
649         assertTrue(outputActionClass.isInterface());
650         CompilationTestUtils.assertImplementsParameterizedIfc(outputActionClass, ChildOf.class.toString(), actionClass.getCanonicalName());
651
652         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
653     }
654
655     @Test
656     public void classNamesColisionTest() throws Exception {
657         final File sourcesOutputDir = new File(CompilationTestUtils.GENERATOR_OUTPUT_PATH + CompilationTestUtils.FS + "class-name-collision");
658         assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
659         final File compiledOutputDir = new File(CompilationTestUtils.COMPILER_OUTPUT_PATH + CompilationTestUtils.FS + "class-name-collision");
660         assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
661
662         generateTestSources("/compilation/class-name-collision", sourcesOutputDir);
663         CompilationTestUtils.testCompilation(sourcesOutputDir, compiledOutputDir);
664         CompilationTestUtils.cleanUp(sourcesOutputDir, compiledOutputDir);
665     }
666
667     private void generateTestSources(final String resourceDirPath, final File sourcesOutputDir)
668             throws IOException, URISyntaxException {
669         final List<File> sourceFiles = CompilationTestUtils.getSourceFiles(resourceDirPath);
670         final SchemaContext context = YangParserTestUtils.parseYangFiles(sourceFiles);
671         final List<Type> types = bindingGenerator.generateTypes(context);
672         Collections.sort(types, (o1, o2) -> o2.getName().compareTo(o1.getName()));
673         final GeneratorJavaFile generator = new GeneratorJavaFile(ImmutableSet.copyOf(types));
674         generator.generateToFile(sourcesOutputDir);
675     }
676
677     private static void testReturnTypeIdentityref(final Class<?> clazz, final String methodName, final String returnTypeStr) throws Exception {
678         Method method;
679         java.lang.reflect.Type returnType;
680         try {
681             method = clazz.getMethod(methodName);
682             assertEquals(java.lang.Class.class, method.getReturnType());
683             returnType = method.getGenericReturnType();
684             assertTrue(returnType instanceof ParameterizedType);
685             final ParameterizedType pt = (ParameterizedType) returnType;
686             final java.lang.reflect.Type[] parameters = pt.getActualTypeArguments();
687             assertEquals(1, parameters.length);
688             final java.lang.reflect.Type parameter = parameters[0];
689             assertTrue(parameter instanceof WildcardType);
690             final WildcardType wildcardType = (WildcardType) parameter;
691             assertEquals("? extends " + returnTypeStr, wildcardType.toString());
692         } catch (final NoSuchMethodException e) {
693             throw new AssertionError("Method '" + methodName + "' not found");
694         }
695     }
696
697     private static void testReturnTypeInstanceIdentitifer(final ClassLoader loader, final Class<?> clazz, final String methodName)
698             throws Exception {
699         Method method;
700         Class<?> rawReturnType;
701         java.lang.reflect.Type returnType;
702         try {
703             method = clazz.getMethod(methodName);
704             rawReturnType = Class.forName("org.opendaylight.yangtools.yang.binding.InstanceIdentifier", true, loader);
705             assertEquals(rawReturnType, method.getReturnType());
706             returnType = method.getGenericReturnType();
707             assertTrue(returnType instanceof ParameterizedType);
708             final ParameterizedType pt = (ParameterizedType) returnType;
709             final java.lang.reflect.Type[] parameters = pt.getActualTypeArguments();
710             assertEquals(1, parameters.length);
711             final java.lang.reflect.Type parameter = parameters[0];
712             assertTrue(parameter instanceof WildcardType);
713             final WildcardType wildcardType = (WildcardType) parameter;
714             assertEquals("?", wildcardType.toString());
715         } catch (final NoSuchMethodException e) {
716             throw new AssertionError("Method '" + methodName + "' not found");
717         }
718     }
719
720 }