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