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