2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.yangtools.sal.java.api.generator.test;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
14 import java.io.FileNotFoundException;
15 import java.lang.annotation.Annotation;
16 import java.lang.reflect.Method;
17 import java.lang.reflect.ParameterizedType;
18 import java.lang.reflect.WildcardType;
20 import java.net.URLClassLoader;
21 import java.util.ArrayList;
22 import java.util.Arrays;
23 import java.util.HashSet;
24 import java.util.List;
27 import javax.tools.JavaCompiler;
28 import javax.tools.JavaFileObject;
29 import javax.tools.StandardJavaFileManager;
30 import javax.tools.ToolProvider;
32 import org.junit.Before;
33 import org.junit.BeforeClass;
34 import org.junit.Test;
35 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
36 import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl;
37 import org.opendaylight.yangtools.sal.binding.model.api.Type;
38 import org.opendaylight.yangtools.sal.java.api.generator.GeneratorJavaFile;
39 import org.opendaylight.yangtools.yang.binding.annotations.RoutingContext;
40 import org.opendaylight.yangtools.yang.model.api.Module;
41 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
42 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
45 * Test correct code generation.
48 public class CompilationTest {
49 private static final String FS = File.separator;
50 private static final String BASE_PATH = "org" + FS + "opendaylight" + FS + "yang" + FS + "gen" + FS + "v1";
51 private static final String NS_TEST = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "test" + FS + "rev131008";
52 private static final String NS_FOO = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "foo" + FS + "rev131008";
53 private static final String NS_BAR = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "bar" + FS + "rev131008";
54 private static final String NS_BAZ = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "baz" + FS + "rev131008";
56 private static final String BASE_PKG = "org.opendaylight.yang.gen.v1";
58 private static final String TEST_PATH = "target" + FS + "test";
59 private static final File TEST_DIR = new File(TEST_PATH);
61 private static final String GENERATOR_OUTPUT_PATH = TEST_PATH + FS + "src";
62 private static final File GENERATOR_OUTPUT_DIR = new File(GENERATOR_OUTPUT_PATH);
63 private static final String COMPILER_OUTPUT_PATH = TEST_PATH + FS + "bin";
64 private static final File COMPILER_OUTPUT_DIR = new File(COMPILER_OUTPUT_PATH);
66 private YangParserImpl parser;
67 private BindingGenerator bindingGenerator;
68 private JavaCompiler compiler;
69 private StandardJavaFileManager fileManager;
72 public static void createTestDirs() {
73 if (TEST_DIR.exists()) {
74 deleteTestDir(TEST_DIR);
76 assertTrue(GENERATOR_OUTPUT_DIR.mkdirs());
77 assertTrue(COMPILER_OUTPUT_DIR.mkdirs());
82 parser = new YangParserImpl();
83 bindingGenerator = new BindingGeneratorImpl();
84 compiler = ToolProvider.getSystemJavaCompiler();
85 fileManager = compiler.getStandardFileManager(null, null, null);
89 * Method to clean resources. It is manually called at the end of each test
90 * instead of marking it with @After annotation to prevent removing
91 * generated code if test fails.
93 public void cleanUp(File... resourceDirs) {
94 for (File resourceDir : resourceDirs) {
95 if (resourceDir.exists()) {
96 deleteTestDir(resourceDir);
102 public void testListGeneration() throws Exception {
103 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "list-gen");
104 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
105 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "list-gen");
106 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
108 final List<File> sourceFiles = getSourceFiles("/compilation/list-gen");
109 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
110 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
111 final List<Type> types = bindingGenerator.generateTypes(context);
112 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
113 generator.generateToFile(sourcesOutputDir);
115 // Test if all sources are generated
116 File parent = new File(sourcesOutputDir, NS_TEST);
117 assertEquals(6, parent.listFiles().length);
118 File keyArgs = new File(parent, "KeyArgs.java");
119 File links = new File(parent, "Links.java");
120 File linksBuilder = new File(parent, "LinksBuilder.java");
121 File linksKey = new File(parent, "LinksKey.java");
122 File testData = new File(parent, "TestData.java");
123 assertTrue(keyArgs.exists());
124 assertTrue(links.exists());
125 assertTrue(linksBuilder.exists());
126 assertTrue(linksKey.exists());
127 assertTrue(testData.exists());
129 parent = new File(sourcesOutputDir, NS_TEST + FS + "links");
130 assertEquals(7, parent.listFiles().length);
131 File level = new File(parent, "Level.java");
132 File linkGroup = new File(parent, "LinkGroup.java");
133 File node = new File(parent, "Node.java");
134 File nodeBuilder = new File(parent, "NodeBuilder.java");
135 File nodeList = new File(parent, "NodeList.java");
136 File nodeListBuilder = new File(parent, "NodeListBuilder.java");
137 File nodesType = new File(parent, "NodesType.java");
138 assertTrue(level.exists());
139 assertTrue(linkGroup.exists());
140 assertTrue(node.exists());
141 assertTrue(nodeBuilder.exists());
142 assertTrue(nodeList.exists());
143 assertTrue(nodeListBuilder.exists());
144 assertTrue(nodesType.exists());
146 // Test if sources are compilable
147 testCompilation(sourcesOutputDir, compiledOutputDir);
149 ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
150 Class<?> keyArgsClass = Class.forName(BASE_PKG + ".urn.opendaylight.test.rev131008.KeyArgs", true, loader);
151 Class<?> linksClass = Class.forName(BASE_PKG + ".urn.opendaylight.test.rev131008.Links", true, loader);
152 Class<?> linksKeyClass = Class.forName(BASE_PKG + ".urn.opendaylight.test.rev131008.LinksKey", true, loader);
154 // Test generated 'grouping key-args'
156 assertTrue(keyArgsClass.isInterface());
157 assertEquals(3, keyArgsClass.getDeclaredMethods().length);
159 Method getId = keyArgsClass.getMethod("getId");
160 assertEquals(Byte.class, getId.getReturnType());
161 Method getName = keyArgsClass.getMethod("getName");
162 assertEquals(String.class, getName.getReturnType());
163 Method getSize = keyArgsClass.getMethod("getSize");
164 assertEquals(Integer.class, getSize.getReturnType());
165 } catch (NoSuchMethodException e) {
166 throw new AssertionError("Required method not found in " + keyArgsClass, e);
169 // test generated 'list links'
170 assertTrue(linksClass.isInterface());
172 assertEquals(5, linksClass.getDeclaredMethods().length);
173 testImplementIfc(linksClass, keyArgsClass);
175 // Test list key constructor arguments ordering
177 linksKeyClass.getConstructor(Byte.class, String.class, Integer.class);
178 } catch (NoSuchMethodException e) {
179 throw new AssertionError("Parameters of list key constructor are not properly ordered");
182 cleanUp(sourcesOutputDir, compiledOutputDir);
186 public void testAugmentUnderUsesGeneration() throws Exception {
187 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "augment-under-uses");
188 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
189 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "augment-under-uses");
190 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
192 final List<File> sourceFiles = getSourceFiles("/compilation/augment-under-uses");
193 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
194 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
195 final List<Type> types = bindingGenerator.generateTypes(context);
196 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
197 generator.generateToFile(sourcesOutputDir);
199 // Test if all sources were generated from 'module foo'
200 File parent = new File(sourcesOutputDir, NS_FOO);
201 assertEquals(7, parent.listFiles().length);
202 assertTrue(new File(parent, "Object.java").exists());
203 assertTrue(new File(parent, "OpenObject.java").exists());
204 assertTrue(new File(parent, "ExplicitRouteObject.java").exists());
205 assertTrue(new File(parent, "PathKeySubobject.java").exists());
207 parent = new File(parent, "object");
208 assertEquals(2, parent.listFiles().length);
209 assertTrue(new File(parent, "Nodes.java").exists());
210 assertTrue(new File(parent, "NodesBuilder.java").exists());
212 parent = new File(sourcesOutputDir, NS_FOO + FS + "open");
213 assertEquals(1, parent.listFiles().length);
215 parent = new File(parent, "object");
216 assertEquals(3, parent.listFiles().length);
217 assertTrue(new File(parent, "Nodes1.java").exists());
218 assertTrue(new File(parent, "Nodes1Builder.java").exists());
220 parent = new File(parent, "nodes");
221 assertEquals(2, parent.listFiles().length);
222 assertTrue(new File(parent, "Links.java").exists());
223 assertTrue(new File(parent, "LinksBuilder.java").exists());
225 parent = new File(sourcesOutputDir, NS_FOO + FS + "explicit");
226 assertEquals(1, parent.listFiles().length);
227 parent = new File(parent, "route");
228 assertEquals(1, parent.listFiles().length);
229 parent = new File(parent, "object");
230 assertEquals(3, parent.listFiles().length);
231 assertTrue(new File(parent, "Subobjects.java").exists());
232 assertTrue(new File(parent, "SubobjectsBuilder.java").exists());
234 parent = new File(parent, "subobjects");
235 assertEquals(1, parent.listFiles().length);
236 parent = new File(parent, "subobject");
237 assertEquals(1, parent.listFiles().length);
238 parent = new File(parent, "type");
239 assertEquals(3, parent.listFiles().length);
240 assertTrue(new File(parent, "PathKey.java").exists());
241 assertTrue(new File(parent, "PathKeyBuilder.java").exists());
243 parent = new File(parent, "path");
244 assertEquals(1, parent.listFiles().length);
245 parent = new File(parent, "key");
246 assertEquals(2, parent.listFiles().length);
247 assertTrue(new File(parent, "PathKey.java").exists());
248 assertTrue(new File(parent, "PathKeyBuilder.java").exists());
250 // Test if all sources were generated from 'module bar'
251 parent = new File(sourcesOutputDir, NS_BAR);
252 assertEquals(3, parent.listFiles().length);
253 assertTrue(new File(parent, "BasicExplicitRouteSubobjects.java").exists());
254 assertTrue(new File(parent, "ExplicitRouteSubobjects.java").exists());
256 parent = new File(parent, "basic");
257 assertEquals(1, parent.listFiles().length);
258 parent = new File(parent, "explicit");
259 assertEquals(1, parent.listFiles().length);
260 parent = new File(parent, "route");
261 assertEquals(1, parent.listFiles().length);
263 parent = new File(parent, "subobjects");
264 assertEquals(2, parent.listFiles().length);
265 assertTrue(new File(parent, "SubobjectType.java").exists());
267 parent = new File(parent, "subobject");
268 assertEquals(1, parent.listFiles().length);
270 parent = new File(parent, "type");
271 assertEquals(4, parent.listFiles().length);
272 assertTrue(new File(parent, "IpPrefix.java").exists());
273 assertTrue(new File(parent, "IpPrefixBuilder.java").exists());
274 assertTrue(new File(parent, "Label.java").exists());
275 assertTrue(new File(parent, "LabelBuilder.java").exists());
277 // Test if sources are compilable
278 testCompilation(sourcesOutputDir, compiledOutputDir);
280 cleanUp(sourcesOutputDir, compiledOutputDir);
284 public void testAugmentOfAugmentGeneration() throws Exception {
285 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "aug-of-aug");
286 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
287 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "aug-of-aug");
288 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
290 final List<File> sourceFiles = getSourceFiles("/compilation/augment-of-augment");
291 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
292 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
293 final List<Type> types = bindingGenerator.generateTypes(context);
294 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
295 generator.generateToFile(sourcesOutputDir);
297 // Test if all sources were generated from 'module foo'
298 File parent = new File(sourcesOutputDir, NS_FOO);
299 assertEquals(6, parent.listFiles().length);
300 File fooListener = new File(parent, "FooListener.java");
301 File pathAttributes = new File(parent, "PathAttributes.java");
302 File update = new File(parent, "Update.java");
303 File updateBuilder = new File(parent, "UpdateBuilder.java");
304 assertTrue(fooListener.exists());
305 assertTrue(pathAttributes.exists());
306 assertTrue(update.exists());
307 assertTrue(updateBuilder.exists());
309 parent = new File(sourcesOutputDir, NS_FOO + FS + "path");
310 assertEquals(1, parent.listFiles().length);
311 parent = new File(parent, "attributes");
312 assertEquals(2, parent.listFiles().length);
313 File origin = new File(parent, "Origin.java");
314 File originBuilder = new File(parent, "OriginBuilder.java");
315 assertTrue(origin.exists());
316 assertTrue(originBuilder.exists());
318 parent = new File(sourcesOutputDir, NS_FOO + FS + "update");
319 assertEquals(2, parent.listFiles().length);
320 pathAttributes = new File(parent, "PathAttributes.java");
321 File pathAttributesBuilder = new File(parent, "PathAttributesBuilder.java");
322 assertTrue(pathAttributes.exists());
323 assertTrue(pathAttributesBuilder.exists());
325 // Test if all sources were generated from 'module bar'
326 parent = new File(sourcesOutputDir, NS_BAR);
327 assertEquals(5, parent.listFiles().length);
328 File destination = new File(parent, "Destination.java");
329 File pathAttributes1 = new File(parent, "PathAttributes1.java");
330 File pathAttributes1Builder = new File(parent, "PathAttributes1Builder.java");
331 assertTrue(destination.exists());
332 assertTrue(pathAttributes1.exists());
333 assertTrue(pathAttributes1Builder.exists());
335 parent = new File(sourcesOutputDir, NS_BAR + FS + "destination");
336 assertEquals(2, parent.listFiles().length);
337 File destinationType = new File(parent, "DestinationType.java");
338 assertTrue(destinationType.exists());
340 parent = new File(parent, "destination");
341 assertEquals(1, parent.listFiles().length);
342 parent = new File(parent, "type");
343 assertEquals(2, parent.listFiles().length);
344 File destinationIpv4 = new File(parent, "DestinationIp.java");
345 File destinationIpv4Builder = new File(parent, "DestinationIpBuilder.java");
346 assertTrue(destinationIpv4.exists());
347 assertTrue(destinationIpv4Builder.exists());
349 parent = new File(sourcesOutputDir, NS_BAR + FS + "update");
350 assertEquals(1, parent.listFiles().length);
351 parent = new File(parent, "path");
352 assertEquals(1, parent.listFiles().length);
353 parent = new File(parent, "attributes");
354 assertEquals(3, parent.listFiles().length);
355 File mpUnreachNlri = new File(parent, "MpUnreachNlri.java");
356 File mpUnreachNlriBuilder = new File(parent, "MpUnreachNlriBuilder.java");
357 assertTrue(mpUnreachNlri.exists());
358 assertTrue(mpUnreachNlriBuilder.exists());
360 parent = new File(parent, "mp");
361 assertEquals(1, parent.listFiles().length);
362 parent = new File(parent, "unreach");
363 assertEquals(1, parent.listFiles().length);
364 parent = new File(parent, "nlri");
365 assertEquals(3, parent.listFiles().length);
366 File withdrawnRoutes = new File(parent, "WithdrawnRoutes.java");
367 File withdrawnRoutesBuilder = new File(parent, "WithdrawnRoutesBuilder.java");
368 assertTrue(withdrawnRoutes.exists());
369 assertTrue(withdrawnRoutesBuilder.exists());
371 parent = new File(parent, "withdrawn");
372 assertEquals(1, parent.listFiles().length);
373 parent = new File(parent, "routes");
374 assertEquals(1, parent.listFiles().length);
375 destinationType = new File(parent, "DestinationType.java");
376 assertTrue(destinationType.exists());
378 // Test if all sources were generated from 'module baz'
379 parent = new File(sourcesOutputDir, NS_BAZ);
380 assertEquals(2, parent.listFiles().length);
381 File linkstateDestination = new File(parent, "LinkstateDestination.java");
382 assertTrue(linkstateDestination.exists());
384 parent = new File(sourcesOutputDir, NS_BAZ + FS + "update");
385 assertEquals(1, parent.listFiles().length);
386 parent = new File(parent, "path");
387 assertEquals(1, parent.listFiles().length);
388 parent = new File(parent, "attributes");
389 assertEquals(1, parent.listFiles().length);
390 parent = new File(parent, "mp");
391 assertEquals(1, parent.listFiles().length);
392 parent = new File(parent, "unreach");
393 assertEquals(1, parent.listFiles().length);
394 parent = new File(parent, "nlri");
395 assertEquals(1, parent.listFiles().length);
396 parent = new File(parent, "withdrawn");
397 assertEquals(1, parent.listFiles().length);
398 parent = new File(parent, "routes");
399 assertEquals(1, parent.listFiles().length);
400 parent = new File(parent, "destination");
401 assertEquals(1, parent.listFiles().length);
402 parent = new File(parent, "type");
403 assertEquals(2, parent.listFiles().length);
404 File destinationLinkstate = new File(parent, "DestinationLinkstate.java");
405 File destinationLinkstateBuilder = new File(parent, "DestinationLinkstateBuilder.java");
406 assertTrue(destinationLinkstate.exists());
407 assertTrue(destinationLinkstateBuilder.exists());
409 // Test if sources are compilable
410 testCompilation(sourcesOutputDir, compiledOutputDir);
412 cleanUp(sourcesOutputDir, compiledOutputDir);
416 public void testLeafReturnTypes() throws Exception {
417 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "leaf-return-types");
418 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
419 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "leaf-return-types");
420 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
422 final List<File> sourceFiles = getSourceFiles("/compilation/leaf-return-types");
423 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
424 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
425 final List<Type> types = bindingGenerator.generateTypes(context);
426 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
427 generator.generateToFile(sourcesOutputDir);
429 File parent = new File(sourcesOutputDir, NS_TEST);
430 assertTrue(new File(parent, "TestData.java").exists());
431 assertTrue(new File(parent, "Nodes.java").exists());
432 assertTrue(new File(parent, "NodesBuilder.java").exists());
433 assertTrue(new File(parent, "Alg.java").exists());
435 // Test if sources are compilable
436 testCompilation(sourcesOutputDir, compiledOutputDir);
438 String pkg = BASE_PKG + ".urn.opendaylight.test.rev131008";
439 ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
440 Class<?> nodesClass = Class.forName(pkg + ".Nodes", true, loader);
442 // Test methods return type
443 byte[] b = new byte[] {};
444 testReturnType(nodesClass, "getIdBinary", b.getClass());
445 testReturnType(nodesClass, "getIdBits", pkg + ".Nodes$IdBits", loader);
446 testReturnType(nodesClass, "isIdBoolean", "java.lang.Boolean", loader);
447 testReturnType(nodesClass, "getIdDecimal64", "java.math.BigDecimal", loader);
448 testReturnType(nodesClass, "isIdEmpty", "java.lang.Boolean", loader);
449 testReturnType(nodesClass, "getIdEnumeration", pkg + ".Nodes$IdEnumeration", loader);
450 testReturnTypeIdentityref(nodesClass, "getIdIdentityref", pkg + ".Alg");
451 testReturnTypeInstanceIdentitifer(loader, nodesClass, "getIdInstanceIdentifier");
452 testReturnType(nodesClass, "getId8", "java.lang.Byte", loader);
453 testReturnType(nodesClass, "getId16", "java.lang.Short", loader);
454 testReturnType(nodesClass, "getId32", "java.lang.Integer", loader);
455 testReturnType(nodesClass, "getId64", "java.lang.Long", loader);
456 testReturnType(nodesClass, "getIdLeafref", "java.lang.Long", loader);
457 testReturnType(nodesClass, "getIdString", "java.lang.String", loader);
458 testReturnType(nodesClass, "getIdU8", "java.lang.Short", loader);
459 testReturnType(nodesClass, "getIdU16", "java.lang.Integer", loader);
460 testReturnType(nodesClass, "getIdU32", "java.lang.Long", loader);
461 testReturnType(nodesClass, "getIdU64", "java.math.BigInteger", loader);
462 testReturnType(nodesClass, "getIdUnion", pkg + ".Nodes$IdUnion", loader);
464 cleanUp(sourcesOutputDir, compiledOutputDir);
468 public void testGenerationContextReferenceExtension() throws Exception {
469 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "context-reference");
470 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
471 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "context-reference");
472 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
474 final List<File> sourceFiles = getSourceFiles("/compilation/context-reference");
475 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
476 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
477 final List<Type> types = bindingGenerator.generateTypes(context);
478 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
479 generator.generateToFile(sourcesOutputDir);
481 // Test if all sources are generated
482 File fooParent = new File(sourcesOutputDir, NS_FOO);
483 assertEquals(3, fooParent.listFiles().length);
484 assertTrue(new File(fooParent, "FooData.java").exists());
485 assertTrue(new File(fooParent, "Nodes.java").exists());
486 assertTrue(new File(fooParent, "NodesBuilder.java").exists());
488 File barParent = new File(sourcesOutputDir, NS_BAR);
489 assertEquals(1, barParent.listFiles().length);
490 assertTrue(new File(barParent, "IdentityClass.java").exists());
492 // Test if sources are compilable
493 testCompilation(sourcesOutputDir, compiledOutputDir);
495 ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
496 Class<?> nodesClass = Class.forName(BASE_PKG + ".urn.opendaylight.foo.rev131008.Nodes", true, loader);
497 Class<?> identityClass = Class
498 .forName(BASE_PKG + ".urn.opendaylight.bar.rev131008.IdentityClass", true, loader);
502 identityClass.getConstructor();
503 Class<?> baseIdentity = Class.forName("org.opendaylight.yangtools.yang.binding.BaseIdentity", true, loader);
504 assertEquals(baseIdentity, identityClass.getSuperclass());
505 } catch (NoSuchMethodException e) {
506 throw new AssertionError("IdentityClass must have no-arg constructor");
511 Method getId = nodesClass.getMethod("getId");
512 Annotation[] annotations = getId.getAnnotations();
513 assertEquals(1, annotations.length);
514 Annotation routingContext = annotations[0];
515 assertEquals(RoutingContext.class, routingContext.annotationType());
516 } catch (NoSuchMethodException e) {
517 throw new AssertionError("Method getId() not found");
520 cleanUp(sourcesOutputDir, compiledOutputDir);
524 public void testAugmentToUsesInAugment() throws Exception {
525 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "augment-uses-to-augment");
526 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
527 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "augment-uses-to-augment");
528 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
530 final List<File> sourceFiles = getSourceFiles("/compilation/augment-uses-to-augment");
531 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
532 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
533 final List<Type> types = bindingGenerator.generateTypes(context);
534 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
535 generator.generateToFile(sourcesOutputDir);
537 // Test if all sources are generated
538 File fooParent = new File(sourcesOutputDir, NS_FOO);
539 assertEquals(4, fooParent.listFiles().length);
540 assertTrue(new File(fooParent, "IgpLinkAttributes.java").exists());
541 assertTrue(new File(fooParent, "Link1.java").exists());
542 assertTrue(new File(fooParent, "Link1Builder.java").exists());
544 File bazParent = new File(sourcesOutputDir, NS_BAZ);
545 assertEquals(4, bazParent.listFiles().length);
546 assertTrue(new File(bazParent, "IgpLinkAttributes1.java").exists());
547 assertTrue(new File(bazParent, "IgpLinkAttributes1Builder.java").exists());
548 assertTrue(new File(bazParent, "LinkAttributes.java").exists());
550 // Test if sources are compilable
551 testCompilation(sourcesOutputDir, compiledOutputDir);
555 public void compilationTest() throws Exception {
556 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "yang");
557 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
558 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "yang");
559 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
561 final List<File> sourceFiles = getSourceFiles("/yang");
562 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
563 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
564 final List<Type> types = bindingGenerator.generateTypes(context);
565 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
566 generator.generateToFile(sourcesOutputDir);
568 // Test if sources are compilable
569 testCompilation(sourcesOutputDir, compiledOutputDir);
571 cleanUp(sourcesOutputDir, compiledOutputDir);
575 * Test if source code is compilable.
577 * @param sourcesOutputDir
578 * directory containing source files
579 * @param compiledOutputDir
580 * compiler output directory
582 private void testCompilation(File sourcesOutputDir, File compiledOutputDir) {
583 List<File> filesList = getJavaFiles(sourcesOutputDir);
584 Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
585 Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
586 boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
587 assertTrue(compiled);
590 private void testImplementIfc(Class<?> classToTest, String ifc, ClassLoader loader) throws ClassNotFoundException {
591 Class<?>[] interfaces = classToTest.getInterfaces();
592 List<Class<?>> ifcsList = Arrays.asList(interfaces);
593 Class<?> ifcClass = Class.forName(ifc, true, loader);
594 testImplementIfc(classToTest, ifcClass);
597 private void testImplementIfc(Class<?> classToTest, Class<?> ifcClass) throws ClassNotFoundException {
598 Class<?>[] interfaces = classToTest.getInterfaces();
599 List<Class<?>> ifcsList = Arrays.asList(interfaces);
600 if (!ifcsList.contains(ifcClass)) {
601 throw new AssertionError(classToTest + " should implement " + ifcClass);
605 private void testReturnType(Class<?> clazz, String methodName, Class<?> returnType) throws Exception {
608 method = clazz.getMethod(methodName);
609 assertEquals(returnType, method.getReturnType());
610 } catch (NoSuchMethodException e) {
611 throw new AssertionError("Method '" + methodName + "' not found");
615 private void testReturnType(Class<?> clazz, String methodName, String returnTypeStr, ClassLoader loader)
619 returnType = Class.forName(returnTypeStr, true, loader);
620 testReturnType(clazz, methodName, returnType);
621 } catch (ClassNotFoundException e) {
622 throw new AssertionError("Return type of method '" + methodName + "' not found");
626 private void testReturnTypeIdentityref(Class<?> clazz, String methodName, String returnTypeStr) throws Exception {
628 java.lang.reflect.Type returnType;
630 method = clazz.getMethod(methodName);
631 assertEquals(java.lang.Class.class, method.getReturnType());
632 returnType = method.getGenericReturnType();
633 assertTrue(returnType instanceof ParameterizedType);
634 ParameterizedType pt = (ParameterizedType) returnType;
635 java.lang.reflect.Type[] parameters = pt.getActualTypeArguments();
636 assertEquals(1, parameters.length);
637 java.lang.reflect.Type parameter = parameters[0];
638 assertTrue(parameter instanceof WildcardType);
639 WildcardType wildcardType = (WildcardType) parameter;
640 assertEquals("? extends " + returnTypeStr, wildcardType.toString());
641 } catch (NoSuchMethodException e) {
642 throw new AssertionError("Method '" + methodName + "' not found");
646 private void testReturnTypeInstanceIdentitifer(ClassLoader loader, Class<?> clazz, String methodName)
649 Class<?> rawReturnType;
650 java.lang.reflect.Type returnType;
652 method = clazz.getMethod(methodName);
653 rawReturnType = Class.forName("org.opendaylight.yangtools.yang.binding.InstanceIdentifier", true, loader);
654 assertEquals(rawReturnType, method.getReturnType());
655 returnType = method.getGenericReturnType();
656 assertTrue(returnType instanceof ParameterizedType);
657 ParameterizedType pt = (ParameterizedType) returnType;
658 java.lang.reflect.Type[] parameters = pt.getActualTypeArguments();
659 assertEquals(1, parameters.length);
660 java.lang.reflect.Type parameter = parameters[0];
661 assertTrue(parameter instanceof WildcardType);
662 WildcardType wildcardType = (WildcardType) parameter;
663 assertEquals("?", wildcardType.toString());
664 } catch (NoSuchMethodException e) {
665 throw new AssertionError("Method '" + methodName + "' not found");
669 private List<File> getSourceFiles(String path) throws FileNotFoundException {
670 final String resPath = getClass().getResource(path).getPath();
671 final File sourcesDir = new File(resPath);
672 if (sourcesDir.exists()) {
673 final List<File> sourceFiles = new ArrayList<>();
674 final File[] fileArray = sourcesDir.listFiles();
675 if (fileArray == null) {
676 throw new IllegalArgumentException("Unable to locate files in " + sourcesDir);
678 sourceFiles.addAll(Arrays.asList(fileArray));
681 throw new FileNotFoundException("Testing files were not found(" + sourcesDir.getName() + ")");
685 private static void deleteTestDir(File file) {
686 if (file.isDirectory()) {
687 File[] filesToDelete = file.listFiles();
688 if (filesToDelete != null) {
689 for (File f : filesToDelete) {
694 if (!file.delete()) {
695 throw new RuntimeException("Failed to clean up after test");
700 * Search recursively given directory for *.java files.
703 * directory to search
704 * @return List of java files found
706 private List<File> getJavaFiles(File directory) {
707 List<File> result = new ArrayList<>();
708 File[] filesToRead = directory.listFiles();
709 if (filesToRead != null) {
710 for (File file : filesToRead) {
711 if (file.isDirectory()) {
712 result.addAll(getJavaFiles(file));
714 String absPath = file.getAbsolutePath();
715 if (absPath.endsWith(".java")) {