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.assertNotNull;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.fail;
16 import java.io.FileNotFoundException;
17 import java.lang.reflect.Constructor;
18 import java.lang.reflect.Field;
19 import java.lang.reflect.InvocationTargetException;
20 import java.lang.reflect.Method;
21 import java.lang.reflect.ParameterizedType;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.List;
26 import javax.tools.JavaCompiler;
27 import javax.tools.JavaFileObject;
28 import javax.tools.StandardJavaFileManager;
29 import javax.tools.ToolProvider;
31 public class CompilationTestUtils {
32 public static final String FS = File.separator;
33 static final String BASE_PKG = "org.opendaylight.yang.gen.v1";
35 static final String TEST_PATH = "target" + FS + "test";
36 static final File TEST_DIR = new File(TEST_PATH);
38 static final String GENERATOR_OUTPUT_PATH = TEST_PATH + FS + "src";
39 static final File GENERATOR_OUTPUT_DIR = new File(GENERATOR_OUTPUT_PATH);
40 static final String COMPILER_OUTPUT_PATH = TEST_PATH + FS + "bin";
41 static final File COMPILER_OUTPUT_DIR = new File(COMPILER_OUTPUT_PATH);
43 static final String BASE_PATH = "org" + FS + "opendaylight" + FS + "yang" + FS + "gen" + FS + "v1";
44 static final String NS_TEST = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "test" + FS + "rev131008";
45 static final String NS_FOO = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "foo" + FS + "rev131008";
46 static final String NS_BAR = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "bar" + FS + "rev131008";
47 static final String NS_BAZ = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "baz" + FS + "rev131008";
50 * Method to clean resources. It is manually called at the end of each test
51 * instead of marking it with @After annotation to prevent removing
52 * generated code if test fails.
54 static void cleanUp(File... resourceDirs) {
55 for (File resourceDir : resourceDirs) {
56 if (resourceDir.exists()) {
57 deleteTestDir(resourceDir);
63 * Asserts that class contains field with fiven name and type.
71 * @return field with given name if present in class
73 static Field assertContainsField(Class<?> clazz, String name, Class<?> type) {
75 Field f = clazz.getDeclaredField(name);
76 assertEquals(type, f.getType());
78 } catch (NoSuchFieldException e) {
79 throw new AssertionError("Field " + name + " does not exists in class " + clazz.getSimpleName());
84 * Asserts that class contains field with given name and value. Method tries
85 * to create new instance of class and get value of field. If class
86 * constructor contains any arguments, class is instantiated with null
94 * return type of field
95 * @param expectedValue
96 * expected value of field
97 * @param constructorArgs
98 * constructor arguments of class to test
100 static void assertContainsFieldWithValue(Class<?> clazz, String name, Class<?> returnType, Object expectedValue,
101 Class<?>... constructorArgs) {
102 Object[] initargs = null;
103 if (constructorArgs != null && constructorArgs.length > 0) {
104 initargs = new Object[constructorArgs.length];
105 for (int i = 0; i < constructorArgs.length; i++) {
109 assertContainsFieldWithValue(clazz, name, returnType, expectedValue, constructorArgs, initargs);
113 * Asserts that class contains field with given name, return type and value.
120 * return type of field
121 * @param expectedValue
122 * expected value of field
123 * @param constructorArgs
124 * array of constructor arguments classes
126 * array of constructor values
128 static void assertContainsFieldWithValue(Class<?> clazz, String name, Class<?> returnType, Object expectedValue,
129 Class<?>[] constructorArgs, Object... initargs) {
130 Field f = assertContainsField(clazz, name, returnType);
131 f.setAccessible(true);
133 Constructor<?> c = clazz.getDeclaredConstructor(constructorArgs);
134 Object o = c.newInstance(initargs);
135 assertEquals(expectedValue, f.get(o));
136 } catch (Exception e) {
137 throw new AssertionError("Failed to perform " + name + " field test", e);
142 * Asserts that class contains constructor with parameter types.
147 * array of argument classes
149 static Constructor<?> assertContainsConstructor(Class<?> clazz, Class<?>... args) {
151 return clazz.getDeclaredConstructor(args);
152 } catch (NoSuchMethodException e) {
153 throw new AssertionError("Constructor with args " + Arrays.toString(args) + " does not exists in class "
154 + clazz.getSimpleName());
159 * Asserts that class contains method with given name, return type and
169 * array of parameter type classes
170 * @return method with given name, return type and parameter types
172 static Method assertContainsMethod(Class<?> clazz, Class<?> returnType, String name, Class<?>... args) {
174 Method m = clazz.getDeclaredMethod(name, args);
175 assertEquals(returnType, m.getReturnType());
177 } catch (NoSuchMethodException e) {
178 throw new AssertionError("Method " + name + " with args " + Arrays.toString(args)
179 + " does not exists in class " + clazz.getSimpleName());
184 * Asserts that class contains method with given name and return type.
188 * @param returnTypeStr
189 * name of method return type
193 * current class loader
195 static void assertContainsMethod(Class<?> clazz, String returnTypeStr, String name, ClassLoader loader) {
198 returnType = Class.forName(returnTypeStr, true, loader);
199 Method method = clazz.getMethod(name);
200 assertEquals(returnType, method.getReturnType());
201 } catch (ClassNotFoundException e) {
202 throw new AssertionError("Return type of method '" + name + "' not found");
203 } catch (NoSuchMethodException e) {
204 throw new AssertionError("Method " + name + " does not exists in class " + clazz.getSimpleName());
209 * Asserts that class contains hashCode, equals and toString methods.
214 static void assertContainsDefaultMethods(Class<?> clazz) {
215 assertContainsMethod(clazz, Integer.TYPE, "hashCode");
216 assertContainsMethod(clazz, Boolean.TYPE, "equals", Object.class);
217 assertContainsMethod(clazz, String.class, "toString");
221 * Asserts that constructor contains check for illegal argument.
224 * constructor to invoke
226 * expected error message
228 * constructor arguments
231 static void assertContainsRestrictionCheck(Constructor<?> constructor, String errorMsg, Object... args)
234 constructor.newInstance(args);
235 fail("constructor invocation should fail");
236 } catch (InvocationTargetException e) {
237 Throwable cause = e.getCause();
238 assertTrue(cause instanceof IllegalArgumentException);
239 assertEquals(errorMsg, cause.getMessage());
244 * Asserts that method contains check for illegal argument.
247 * object to test (can be null, if method is static)
251 * expected error message
253 * constructor arguments
256 static void assertContainsRestrictionCheck(Object obj, Method method, String errorMsg, Object... args)
259 method.invoke(obj, args);
260 fail("method invocation should fail");
261 } catch (InvocationTargetException e) {
262 Throwable cause = e.getCause();
263 assertTrue(cause instanceof IllegalArgumentException);
264 assertEquals(errorMsg, cause.getMessage());
269 * Asserts that class contains 'public static
270 * java.util.List<com.google.common.collect.Range<java.lang.Integer>>
271 * getLength()' method.
276 static void assertContainsGetLengthOrRange(Class<?> clazz, boolean isLength) {
278 Method m = clazz.getDeclaredMethod(isLength ? "length" : "range");
279 java.lang.reflect.Type returnType = m.getGenericReturnType();
280 assertTrue("Return type of getLength method must be ParameterizedType",
281 returnType instanceof ParameterizedType);
282 ParameterizedType listType = (ParameterizedType) returnType;
283 assertEquals("interface java.util.List", listType.getRawType().toString());
285 java.lang.reflect.Type[] args = listType.getActualTypeArguments();
286 assertEquals(1, args.length);
287 java.lang.reflect.Type range = args[0];
288 assertTrue(range instanceof ParameterizedType);
289 ParameterizedType pRange = (ParameterizedType) range;
290 assertEquals("class com.google.common.collect.Range", pRange.getRawType().toString());
292 args = pRange.getActualTypeArguments();
293 assertEquals(1, args.length);
294 } catch (NoSuchMethodException e) {
295 throw new AssertionError("Method length()/range() does not exists in class " + clazz.getSimpleName());
300 * Asserts that class implements given interface.
307 static void assertImplementsIfc(Class<?> clazz, Class<?> ifc) {
308 Class<?>[] interfaces = clazz.getInterfaces();
309 List<Class<?>> ifcsList = Arrays.asList(interfaces);
310 if (!ifcsList.contains(ifc)) {
311 throw new AssertionError(clazz + " should implement " + ifc);
316 * Test if interface generated from augment extends Augmentation interface
317 * with correct generic type.
320 * interface generated from augment
321 * @param genericTypeName
322 * fully qualified name of expected parameter type
324 static void testAugmentation(Class<?> clazz, String genericTypeName) {
325 final String ifcName = "interface org.opendaylight.yangtools.yang.binding.Augmentation";
326 assertImplementsParameterizedIfc(clazz, ifcName, genericTypeName);
330 * Asserts that class implements interface with given name and generic type
337 * @param genericTypeName
338 * name of generic type
340 static void assertImplementsParameterizedIfc(Class<?> clazz, String ifcName, String genericTypeName) {
341 ParameterizedType ifcType = null;
342 for (java.lang.reflect.Type ifc : clazz.getGenericInterfaces()) {
343 if (ifc instanceof ParameterizedType) {
344 ParameterizedType pt = (ParameterizedType) ifc;
345 if (ifcName.equals(pt.getRawType().toString())) {
350 assertNotNull(ifcType);
352 java.lang.reflect.Type[] typeArguments = ifcType.getActualTypeArguments();
353 assertEquals(1, typeArguments.length);
354 assertEquals("interface " + genericTypeName, typeArguments[0].toString());
358 * Test if source code is compilable.
360 * @param sourcesOutputDir
361 * directory containing source files
362 * @param compiledOutputDir
363 * compiler output directory
365 static void testCompilation(File sourcesOutputDir, File compiledOutputDir) {
366 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
367 StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
368 List<File> filesList = getJavaFiles(sourcesOutputDir);
369 Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
370 Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
371 boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
372 assertTrue(compiled);
376 * Asserts that directory contains exactly given count of files.
381 * expected count of files in directory
383 static void assertFilesCount(File dir, int count) {
384 File[] dirContent = dir.listFiles();
385 if (dirContent == null) {
386 throw new AssertionError("File " + dir + " doesn't exists or it's not a directory");
388 assertEquals("Unexpected count of generated files", count, dirContent.length);
393 * Search recursively given directory for *.java files.
396 * directory to search
397 * @return List of java files found
399 private static List<File> getJavaFiles(File directory) {
400 List<File> result = new ArrayList<>();
401 File[] filesToRead = directory.listFiles();
402 if (filesToRead != null) {
403 for (File file : filesToRead) {
404 if (file.isDirectory()) {
405 result.addAll(getJavaFiles(file));
407 String absPath = file.getAbsolutePath();
408 if (absPath.endsWith(".java")) {
417 static List<File> getSourceFiles(String path) throws Exception {
418 final URI resPath = BaseCompilationTest.class.getResource(path).toURI();
419 final File sourcesDir = new File(resPath);
420 if (sourcesDir.exists()) {
421 final List<File> sourceFiles = new ArrayList<>();
422 final File[] fileArray = sourcesDir.listFiles();
423 if (fileArray == null) {
424 throw new IllegalArgumentException("Unable to locate files in " + sourcesDir);
426 sourceFiles.addAll(Arrays.asList(fileArray));
429 throw new FileNotFoundException("Testing files were not found(" + sourcesDir.getName() + ")");
433 static void deleteTestDir(File file) {
434 if (file.isDirectory()) {
435 File[] filesToDelete = file.listFiles();
436 if (filesToDelete != null) {
437 for (File f : filesToDelete) {
442 if (!file.delete()) {
443 throw new RuntimeException("Failed to clean up after test");