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.assertTrue;
14 import java.net.URLClassLoader;
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.HashSet;
18 import java.util.List;
21 import javax.tools.JavaCompiler;
22 import javax.tools.JavaFileObject;
23 import javax.tools.StandardJavaFileManager;
24 import javax.tools.ToolProvider;
26 import org.junit.Before;
27 import org.junit.BeforeClass;
28 import org.junit.Test;
29 import org.opendaylight.yangtools.sal.binding.generator.api.BindingGenerator;
30 import org.opendaylight.yangtools.sal.binding.generator.impl.BindingGeneratorImpl;
31 import org.opendaylight.yangtools.sal.binding.model.api.Type;
32 import org.opendaylight.yangtools.sal.java.api.generator.GeneratorJavaFile;
33 import org.opendaylight.yangtools.yang.model.api.Module;
34 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
35 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
38 * Test correct code generation.
41 public class CompilationTest {
42 private static final String FS = File.separator;
43 private static final String TEST_PATH = "target" + FS + "test";
44 private static final File TEST_DIR = new File(TEST_PATH);
46 private static final String GENERATOR_OUTPUT_PATH = TEST_PATH + FS + "src";
47 private static final File GENERATOR_OUTPUT_DIR = new File(GENERATOR_OUTPUT_PATH);
48 private static final String COMPILER_OUTPUT_PATH = TEST_PATH + FS + "bin";
49 private static final File COMPILER_OUTPUT_DIR = new File(COMPILER_OUTPUT_PATH);
51 private YangParserImpl parser;
52 private BindingGenerator bindingGenerator;
55 public static void createTestDirs() {
56 if (TEST_DIR.exists()) {
57 deleteTestDir(TEST_DIR);
59 assertTrue(GENERATOR_OUTPUT_DIR.mkdirs());
60 assertTrue(COMPILER_OUTPUT_DIR.mkdirs());
65 parser = new YangParserImpl();
66 bindingGenerator = new BindingGeneratorImpl();
70 * Method to clean resources. It is manually called at the end of each test
71 * instead of marking it with @After annotation to prevent removing
72 * generated code if test fails.
74 public void cleanUp(File... resourceDirs) {
75 for (File resourceDir : resourceDirs) {
76 if (resourceDir.exists()) {
77 deleteTestDir(resourceDir);
83 public void testListGeneration() throws Exception {
84 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "list-gen");
85 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
86 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "list-gen");
87 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
89 final List<File> sourceFiles = getSourceFiles("/compilation/list-gen");
90 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
91 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
92 final List<Type> types = bindingGenerator.generateTypes(context);
93 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
94 generator.generateToFile(sourcesOutputDir);
96 File parent = new File(sourcesOutputDir, "org" + FS + "opendaylight" + FS + "yang" + FS + "gen" + FS + "v1"
97 + FS + "urn" + FS + "opendaylight" + FS + "test" + FS + "rev131008");
98 File linksKeyFile = new File(parent, "LinksKey.java");
99 assertTrue(new File(parent, "KeyArgs.java").exists());
100 assertTrue(new File(parent, "Links.java").exists());
101 assertTrue(new File(parent, "LinksBuilder.java").exists());
102 assertTrue(linksKeyFile.exists());
103 assertTrue(new File(parent, "TestData.java").exists());
104 assertTrue(new File(parent, "links" + FS + "Level.java").exists());
105 assertTrue(new File(parent, "links" + FS + "LinkGroup.java").exists());
106 assertTrue(new File(parent, "links" + FS + "Node.java").exists());
107 assertTrue(new File(parent, "links" + FS + "NodeBuilder.java").exists());
108 assertTrue(new File(parent, "links" + FS + "NodeList.java").exists());
109 assertTrue(new File(parent, "links" + FS + "NodeListBuilder.java").exists());
110 assertTrue(linksKeyFile.exists());
112 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
113 StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
115 List<File> filesList = getJavaFiles(sourcesOutputDir);
116 Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
117 Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
118 boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
119 assertTrue(compiled);
121 ClassLoader loader = new URLClassLoader(new URL[] { compiledOutputDir.toURI().toURL() });
122 Class<?> linksKeyClass = Class.forName("org.opendaylight.yang.gen.v1.urn.opendaylight.test.rev131008.LinksKey",
125 // test list key constructor arguments ordering
127 linksKeyClass.getConstructor(Byte.class, String.class, Integer.class);
128 } catch (NoSuchMethodException e) {
129 throw new AssertionError("Parameters of list key constructor are not properly ordered");
132 cleanUp(sourcesOutputDir, compiledOutputDir);
136 public void testAugmentUnderUsesGeneration() throws Exception {
137 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "augment-under-uses");
138 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
139 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "augment-under-uses");
140 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
142 final List<File> sourceFiles = getSourceFiles("/compilation/augment-under-uses");
143 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
144 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
145 final List<Type> types = bindingGenerator.generateTypes(context);
146 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
147 generator.generateToFile(sourcesOutputDir);
149 File parent = new File(sourcesOutputDir + FS + "org" + FS + "opendaylight" + FS + "yang" + FS + "gen" + FS
150 + "v1" + FS + "urn" + FS + "opendaylight" + FS + "test" + FS + "rev131008");
151 assertTrue(new File(parent, "Object.java").exists());
152 assertTrue(new File(parent, "OpenObject.java").exists());
153 assertTrue(new File(parent, "object" + FS + "Nodes.java").exists());
154 assertTrue(new File(parent, "object" + FS + "NodesBuilder.java").exists());
155 assertTrue(new File(parent, "open" + FS + "object" + FS + "Nodes1.java").exists());
156 assertTrue(new File(parent, "open" + FS + "object" + FS + "Nodes1Builder.java").exists());
157 assertTrue(new File(parent, "open" + FS + "object" + FS + "nodes" + FS + "Links.java").exists());
158 assertTrue(new File(parent, "open" + FS + "object" + FS + "nodes" + FS + "LinksBuilder.java").exists());
160 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
161 StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
163 List<File> filesList = getJavaFiles(sourcesOutputDir);
164 Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
165 Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
166 boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
167 assertTrue(compiled);
169 cleanUp(sourcesOutputDir, compiledOutputDir);
173 public void compilationTest() throws Exception {
174 final File sourcesOutputDir = new File(GENERATOR_OUTPUT_PATH + FS + "yang");
175 assertTrue("Failed to create test file '" + sourcesOutputDir + "'", sourcesOutputDir.mkdir());
176 final File compiledOutputDir = new File(COMPILER_OUTPUT_PATH + FS + "yang");
177 assertTrue("Failed to create test file '" + compiledOutputDir + "'", compiledOutputDir.mkdir());
179 final List<File> sourceFiles = getSourceFiles("/yang");
180 final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
181 final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
182 final List<Type> types = bindingGenerator.generateTypes(context);
183 final GeneratorJavaFile generator = new GeneratorJavaFile(new HashSet<>(types));
184 generator.generateToFile(sourcesOutputDir);
186 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
187 StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
189 List<File> filesList = getJavaFiles(sourcesOutputDir);
190 Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
191 Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
192 boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
193 assertTrue(compiled);
196 private List<File> getSourceFiles(String path) {
197 final String resPath = getClass().getResource(path).getPath();
198 final File sourcesDir = new File(resPath);
199 final List<File> sourceFiles = new ArrayList<>();
200 final File[] fileArray = sourcesDir.listFiles();
201 sourceFiles.addAll(Arrays.asList(fileArray));
205 private static void deleteTestDir(File file) {
206 if (file.isDirectory()) {
207 for (File f : file.listFiles()) {
211 if (!file.delete()) {
212 throw new RuntimeException("Failed to clean up after test");
217 * Search recursively given directory for *.java files.
220 * directory to search
221 * @return List of java files found
223 private List<File> getJavaFiles(File directory) {
224 List<File> result = new ArrayList<File>();
225 for (File file : directory.listFiles()) {
226 if (file.isDirectory()) {
227 result.addAll(getJavaFiles(file));
229 String absPath = file.getAbsolutePath();
230 if (absPath.endsWith(".java")) {