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