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.*;
13 import java.io.FileNotFoundException;
14 import java.lang.reflect.Constructor;
15 import java.lang.reflect.Field;
16 import java.lang.reflect.InvocationTargetException;
17 import java.lang.reflect.Method;
18 import java.lang.reflect.ParameterizedType;
20 import java.util.ArrayList;
21 import java.util.Arrays;
22 import java.util.List;
24 import javax.tools.JavaCompiler;
25 import javax.tools.JavaFileObject;
26 import javax.tools.StandardJavaFileManager;
27 import javax.tools.ToolProvider;
29 public class CompilationTestUtils {
30 public static final String FS = File.separator;
31 static final String BASE_PKG = "org.opendaylight.yang.gen.v1";
33 static final String TEST_PATH = "target" + FS + "test";
34 static final File TEST_DIR = new File(TEST_PATH);
36 static final String GENERATOR_OUTPUT_PATH = TEST_PATH + FS + "src";
37 static final File GENERATOR_OUTPUT_DIR = new File(GENERATOR_OUTPUT_PATH);
38 static final String COMPILER_OUTPUT_PATH = TEST_PATH + FS + "bin";
39 static final File COMPILER_OUTPUT_DIR = new File(COMPILER_OUTPUT_PATH);
41 static final String BASE_PATH = "org" + FS + "opendaylight" + FS + "yang" + FS + "gen" + FS + "v1";
42 static final String NS_TEST = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "test" + FS + "rev131008";
43 static final String NS_FOO = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "foo" + FS + "rev131008";
44 static final String NS_BAR = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "bar" + FS + "rev131008";
45 static final String NS_BAZ = BASE_PATH + FS + "urn" + FS + "opendaylight" + FS + "baz" + FS + "rev131008";
48 * Method to clean resources. It is manually called at the end of each test
49 * instead of marking it with @After annotation to prevent removing
50 * generated code if test fails.
52 static void cleanUp(File... resourceDirs) {
53 for (File resourceDir : resourceDirs) {
54 if (resourceDir.exists()) {
55 deleteTestDir(resourceDir);
61 * Asserts that class contains field with fiven name and type.
69 * @return field with given name if present in class
71 static Field assertContainsField(Class<?> clazz, String name, Class<?> type) {
73 Field f = clazz.getDeclaredField(name);
74 assertEquals(type, f.getType());
76 } catch (NoSuchFieldException e) {
77 throw new AssertionError("Field " + name + " does not exists in class " + clazz.getSimpleName());
82 * Asserts that class contains field with given name and value. Method tries
83 * to create new instance of class and get value of field. If class
84 * constructor contains any arguments, class is instantiated with null
92 * return type of field
93 * @param expectedValue
94 * expected value of field
95 * @param constructorArgs
96 * constructor arguments of class to test
98 static void assertContainsFieldWithValue(Class<?> clazz, String name, Class<?> returnType, Object expectedValue,
99 Class<?>... constructorArgs) {
100 Object[] initargs = null;
101 if (constructorArgs != null && constructorArgs.length > 0) {
102 initargs = new Object[constructorArgs.length];
103 for (int i = 0; i < constructorArgs.length; i++) {
107 assertContainsFieldWithValue(clazz, name, returnType, expectedValue, constructorArgs, initargs);
111 * Asserts that class contains field with given name, return type and value.
118 * return type of field
119 * @param expectedValue
120 * expected value of field
121 * @param constructorArgs
122 * array of constructor arguments classes
124 * array of constructor values
126 static void assertContainsFieldWithValue(Class<?> clazz, String name, Class<?> returnType, Object expectedValue,
127 Class<?>[] constructorArgs, Object... initargs) {
128 Field f = assertContainsField(clazz, name, returnType);
130 Constructor<?> c = clazz.getDeclaredConstructor(constructorArgs);
131 Object o = c.newInstance(initargs);
132 assertEquals(expectedValue, f.get(o));
133 } catch (Exception e) {
134 throw new AssertionError("Failed to perform " + name + " field test", e);
139 * Asserts that class contains constructor with parameter types.
144 * array of argument classes
146 static Constructor<?> assertContainsConstructor(Class<?> clazz, Class<?>... args) {
148 return clazz.getDeclaredConstructor(args);
149 } catch (NoSuchMethodException e) {
150 throw new AssertionError("Constructor with args " + Arrays.toString(args) + " does not exists in class "
151 + clazz.getSimpleName());
156 * Asserts that class contains method with given name, return type and
166 * array of parameter type classes
167 * @return method with given name, return type and parameter types
169 static Method assertContainsMethod(Class<?> clazz, Class<?> returnType, String name, Class<?>... args) {
171 Method m = clazz.getDeclaredMethod(name, args);
172 assertEquals(returnType, m.getReturnType());
174 } catch (NoSuchMethodException e) {
175 throw new AssertionError("Method " + name + " with args " + Arrays.toString(args)
176 + " does not exists in class " + clazz.getSimpleName());
181 * Asserts that class contains method with given name and return type.
185 * @param returnTypeStr
186 * name of method return type
190 * current class loader
192 static void assertContainsMethod(Class<?> clazz, String returnTypeStr, String name, ClassLoader loader) {
195 returnType = Class.forName(returnTypeStr, true, loader);
196 Method method = clazz.getMethod(name);
197 assertEquals(returnType, method.getReturnType());
198 } catch (ClassNotFoundException e) {
199 throw new AssertionError("Return type of method '" + name + "' not found");
200 } catch (NoSuchMethodException e) {
201 throw new AssertionError("Method " + name + " does not exists in class " + clazz.getSimpleName());
206 * Asserts that class contains hashCode, equals and toString methods.
211 static void assertContainsDefaultMethods(Class<?> clazz) {
212 assertContainsMethod(clazz, Integer.TYPE, "hashCode");
213 assertContainsMethod(clazz, Boolean.TYPE, "equals", Object.class);
214 assertContainsMethod(clazz, String.class, "toString");
218 * Asserts that constructor contains check for illegal argument.
221 * constructor to invoke
223 * expected error message
225 * constructor arguments
228 static void assertContainsRestrictionCheck(Constructor<?> constructor, String errorMsg, Object... args)
231 constructor.newInstance(args);
232 fail("constructor invocation should fail");
233 } catch (InvocationTargetException e) {
234 Throwable cause = e.getCause();
235 assertTrue(cause instanceof IllegalArgumentException);
236 assertEquals(errorMsg, cause.getMessage());
241 * Asserts that method contains check for illegal argument.
244 * object to test (can be null, if method is static)
248 * expected error message
250 * constructor arguments
253 static void assertContainsRestrictionCheck(Object obj, Method method, String errorMsg, Object... args)
256 method.invoke(obj, args);
257 fail("method invocation should fail");
258 } catch (InvocationTargetException e) {
259 Throwable cause = e.getCause();
260 assertTrue(cause instanceof IllegalArgumentException);
261 assertEquals(errorMsg, cause.getMessage());
266 * Asserts that class contains 'public static
267 * java.util.List<com.google.common.collect.Range<java.lang.Integer>>
268 * getLength()' method.
273 static void assertContainsGetLengthOrRange(Class<?> clazz, boolean isLength) {
275 Method m = clazz.getDeclaredMethod(isLength ? "length" : "range");
276 java.lang.reflect.Type returnType = m.getGenericReturnType();
277 assertTrue("Return type of getLength method must be ParameterizedType",
278 returnType instanceof ParameterizedType);
279 ParameterizedType listType = (ParameterizedType) returnType;
280 assertEquals("interface java.util.List", listType.getRawType().toString());
282 java.lang.reflect.Type[] args = listType.getActualTypeArguments();
283 assertEquals(1, args.length);
284 java.lang.reflect.Type range = args[0];
285 assertTrue(range instanceof ParameterizedType);
286 ParameterizedType pRange = (ParameterizedType) range;
287 assertEquals("class com.google.common.collect.Range", pRange.getRawType().toString());
289 args = pRange.getActualTypeArguments();
290 assertEquals(1, args.length);
291 } catch (NoSuchMethodException e) {
292 throw new AssertionError("Method length()/range() does not exists in class " + clazz.getSimpleName());
297 * Asserts that class implements given interface.
304 static void assertImplementsIfc(Class<?> clazz, Class<?> ifc) {
305 Class<?>[] interfaces = clazz.getInterfaces();
306 List<Class<?>> ifcsList = Arrays.asList(interfaces);
307 if (!ifcsList.contains(ifc)) {
308 throw new AssertionError(clazz + " should implement " + ifc);
313 * Test if interface generated from augment extends Augmentation interface
314 * with correct generic type.
317 * interface generated from augment
318 * @param genericTypeName
319 * fully qualified name of expected parameter type
321 static void testAugmentation(Class<?> clazz, String genericTypeName) {
322 final String ifcName = "interface org.opendaylight.yangtools.yang.binding.Augmentation";
323 assertImplementsParameterizedIfc(clazz, ifcName, genericTypeName);
327 * Asserts that class implements interface with given name and generic type
334 * @param genericTypeName
335 * name of generic type
337 static void assertImplementsParameterizedIfc(Class<?> clazz, String ifcName, String genericTypeName) {
338 ParameterizedType ifcType = null;
339 for (java.lang.reflect.Type ifc : clazz.getGenericInterfaces()) {
340 if (ifc instanceof ParameterizedType) {
341 ParameterizedType pt = (ParameterizedType) ifc;
342 if (ifcName.equals(pt.getRawType().toString())) {
347 assertNotNull(ifcType);
349 java.lang.reflect.Type[] typeArguments = ifcType.getActualTypeArguments();
350 assertEquals(1, typeArguments.length);
351 assertEquals("interface " + genericTypeName, typeArguments[0].toString());
355 * Test if source code is compilable.
357 * @param sourcesOutputDir
358 * directory containing source files
359 * @param compiledOutputDir
360 * compiler output directory
362 static void testCompilation(File sourcesOutputDir, File compiledOutputDir) {
363 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
364 StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
365 List<File> filesList = getJavaFiles(sourcesOutputDir);
366 Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(filesList);
367 Iterable<String> options = Arrays.asList("-d", compiledOutputDir.getAbsolutePath());
368 boolean compiled = compiler.getTask(null, null, null, options, null, compilationUnits).call();
369 assertTrue(compiled);
373 * Asserts that directory contains exactly given count of files.
378 * expected count of files in directory
380 static void assertFilesCount(File dir, int count) {
381 File[] dirContent = dir.listFiles();
382 if (dirContent == null) {
383 throw new AssertionError("File " + dir + " doesn't exists or it's not a directory");
385 assertEquals("Unexpected count of generated files", count, dirContent.length);
390 * Search recursively given directory for *.java files.
393 * directory to search
394 * @return List of java files found
396 private static List<File> getJavaFiles(File directory) {
397 List<File> result = new ArrayList<>();
398 File[] filesToRead = directory.listFiles();
399 if (filesToRead != null) {
400 for (File file : filesToRead) {
401 if (file.isDirectory()) {
402 result.addAll(getJavaFiles(file));
404 String absPath = file.getAbsolutePath();
405 if (absPath.endsWith(".java")) {
414 static List<File> getSourceFiles(String path) throws Exception {
415 final URI resPath = BaseCompilationTest.class.getResource(path).toURI();
416 final File sourcesDir = new File(resPath);
417 if (sourcesDir.exists()) {
418 final List<File> sourceFiles = new ArrayList<>();
419 final File[] fileArray = sourcesDir.listFiles();
420 if (fileArray == null) {
421 throw new IllegalArgumentException("Unable to locate files in " + sourcesDir);
423 sourceFiles.addAll(Arrays.asList(fileArray));
426 throw new FileNotFoundException("Testing files were not found(" + sourcesDir.getName() + ")");
430 static void deleteTestDir(File file) {
431 if (file.isDirectory()) {
432 File[] filesToDelete = file.listFiles();
433 if (filesToDelete != null) {
434 for (File f : filesToDelete) {
439 if (!file.delete()) {
440 throw new RuntimeException("Failed to clean up after test");