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