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