/** * Copyright (C) 2010-2017 Gordon Fraser, Andrea Arcuri and EvoSuite * contributors * * This file is part of EvoSuite. * * EvoSuite is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3.0 of the License, or * (at your option) any later version. * * EvoSuite is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with EvoSuite. If not, see <http://www.gnu.org/licenses/>. */ package org.evosuite.junit; import static org.junit.Assert.assertNotNull; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; import java.net.URL; import java.net.URLClassLoader; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Locale; import javax.tools.DiagnosticCollector; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.JavaFileObject; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; import org.apache.commons.io.FileUtils; import org.junit.Test; import com.examples.with.different.packagename.junit.Foo; public class FooTestClassLoader { private static final String FOO_TEST_CLASS_NAME = "com.examples.with.different.packagename.junit.FooTest"; @Test public void testFooTestClassCreation() throws IOException { Class<?> clazz = loadFooTestClass(); assertNotNull(clazz); } private static String createFooTestJavaText() { StringBuffer buff = new StringBuffer(); buff.append("package com.examples.with.different.packagename.junit;\n"); buff.append("import static org.junit.Assert.assertEquals;\n"); buff.append("import org.junit.Test;\n"); buff.append("public class FooTest {\n"); buff.append(" @Test\n"); buff.append(" public void test1() {\n"); buff.append(" Foo foo = new Foo();\n"); buff.append(" int result = foo.add(10, 15);\n"); buff.append(" assertEquals(25, result);\n"); buff.append(" }\n"); buff.append(" @Test\n"); buff.append(" public void test2() {\n"); buff.append(" Foo foo = new Foo();\n"); buff.append(" int result = foo.add(20, 35);\n"); buff.append(" assertEquals(55, result);\n"); buff.append(" }\n"); buff.append(" @Test \n"); buff.append(" public void test3() {\n"); buff.append(" Foo foo = new Foo();\n"); buff.append(" int result = foo.add(10, 35);\n"); buff.append(" assertEquals(46, result);\n"); buff.append(" }\n"); buff.append("}\n"); return buff.toString(); } private static File createNewTmpDir() { File dir = null; String dirName = FileUtils.getTempDirectoryPath() + File.separator + "EvoSuite_" + JUnitResultBuilderTest.class.getCanonicalName() + "_" + +System.currentTimeMillis(); //first create a tmp folder dir = new File(dirName); if (!dir.mkdirs()) { return null; } if (!dir.exists()) { return null; } return dir; } public Class<?> loadFooTestClass() { File tempDir = createNewTmpDir(); if (tempDir == null) { return null; //fail } String javaSrcDirName = tempDir.getAbsolutePath() + File.separator + "src"; String javaBinDirName = tempDir.getAbsolutePath() + File.separator + "bin"; String javaSrcPackageDirName = javaSrcDirName + File.separator + "com.examples.with.different.packagename.junit".replace(".", File.separator); String javaBinPackageDirName = javaBinDirName + File.separator + "com.examples.with.different.packagename.junit".replace(".", File.separator); File javaBinDir = new File(javaBinDirName); if (!javaBinDir.mkdirs()) { return null; //fail } File packageDir = new File(javaSrcPackageDirName); if (!packageDir.mkdirs()) { return null; //fail } String javaFilename = javaSrcPackageDirName + File.separator + "FooTest.java"; String classFilename = javaBinPackageDirName + File.separator + "FooTest.class"; String javaSourceText = createFooTestJavaText(); File javaFile = writeJavaSourceText(javaSourceText, javaFilename); if (javaFile == null) { return null; //fail } boolean compiled = compileJavaFile(javaBinDirName, javaFile); if (!compiled) { return null; //fail } File classFile = new File(classFilename); if (!classFile.exists()) { return null; //fail } Class<?> clazz = loadClass(javaBinDir); if (clazz == null) { return null; //fail } //delete class file on exit classFile.delete(); return clazz; } private static Class<?> loadClass(File javaBinDir) { URLClassLoader urlClassLoader = null; try { URI javaBinURI = javaBinDir.toURI(); URL javaBinURL = javaBinURI.toURL(); urlClassLoader = new URLClassLoader(new URL[] { javaBinURL }, Foo.class.getClassLoader()); Class<?> clazz = urlClassLoader.loadClass(FOO_TEST_CLASS_NAME); return clazz; } catch (ClassNotFoundException e) { return null; } catch (MalformedURLException e) { return null; } } private static boolean compileJavaFile(String javaBinDirName, File javaFile) { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); if (compiler == null) { return false; //fail } DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>(); StandardJavaFileManager fileManager = compiler.getStandardFileManager( diagnostics, Locale.getDefault(), Charset.forName("UTF-8")); Iterable<? extends JavaFileObject> compilationUnits = fileManager .getJavaFileObjectsFromFiles(Collections .singletonList(javaFile)); List<String> optionList; optionList = new ArrayList<String>(); optionList.addAll(Arrays.asList("-d", javaBinDirName)); CompilationTask task = compiler.getTask(null, fileManager, diagnostics, optionList, null, compilationUnits); boolean compiled = task.call(); try { fileManager.close(); } catch (IOException e) { return false; } return compiled; } private File writeJavaSourceText(String javaSourceText, String javaFilename) { File javaFile = new File(javaFilename); if (javaFile.exists()) { return null; //fail } BufferedWriter writer = null; try { writer = new BufferedWriter(new FileWriter(javaFilename)); writer.write(javaSourceText); writer.close(); } catch (IOException e) { return null; } return javaFile; } }