/** * This methods derive the dependencies between {@link CBranchTestFitness} and branches. * Therefore, it is used to update 'this.dependencies' */ @SuppressWarnings("unchecked") private void addDependencies4CBranch() { logger.debug("Added dependencies for CBranch"); CallGraph callGraph = DependencyAnalysis.getCallGraph(); for (BranchCoverageTestFitness branch : this.dependencies.keySet()) { for (CallContext context : callGraph.getMethodEntryPoint(branch.getClassName(), branch.getMethod())) { CBranchTestFitness cBranch = new CBranchTestFitness(branch.getBranchGoal(), context); this.dependencies.get(branch).add((FitnessFunction<T>) cBranch); logger.debug("Added context branch: " + cBranch.toString()); } } }
/** * For now use the cache provided by dependency analysis * * @param className * @return */ private ClassNode getClassNode(String className) { return DependencyAnalysis.getClassNode(className); }
private boolean checkAnyOverridingMethodImpure(MethodEntry entry, Stack<MethodEntry> callStack) { InheritanceTree inheritanceTree = DependencyAnalysis .getInheritanceTree();
/** * Start analysis from target class * * @param className */ public static void analyzeClass(String className, List<String> classPath) throws RuntimeException, ClassNotFoundException { initInheritanceTree(classPath); analyze(className, classPath); }
/** * Determine if the given method should be instrumented * * @param className * @param methodName * @return */ public static boolean shouldInstrument(String className, String methodName) { // Always analyze if it is a target class if (isTargetClassName(className)) return true; // Also analyze if it is a superclass and instrument_parent = true if (Properties.INSTRUMENT_PARENT) { if (inheritanceTree.getSuperclasses(Properties.TARGET_CLASS).contains(className)) return true; } // Also analyze if it is in the calltree and we are considering the // context if (Properties.INSTRUMENT_CONTEXT) { CallGraph callGraph = callGraphs.get(Properties.TARGET_CLASS); if (callGraph != null && callGraph.isCalledMethod(className, methodName)){ if(Properties.INSTRUMENT_LIBRARIES || DependencyAnalysis.isTargetProject(className)) return true; } } return false; }
private void initializeTargetClass() throws Throwable { String cp = ClassPathHandler.getInstance().getTargetProjectClasspath(); // Here is where the <clinit> code should be invoked for the first time DefaultTestCase test = buildLoadTargetClassTestCase(Properties.TARGET_CLASS); ExecutionResult execResult = TestCaseExecutor.getInstance().execute(test, Integer.MAX_VALUE); if (hasThrownInitializerError(execResult)) { // create single test suite with Class.forName() writeJUnitTestSuiteForFailedInitialization(); ExceptionInInitializerError ex = getInitializerError(execResult); throw ex; } else if (!execResult.getAllThrownExceptions().isEmpty()) { // some other exception has been thrown during initialization Throwable t = execResult.getAllThrownExceptions().iterator().next(); throw t; } DependencyAnalysis.analyzeClass(Properties.TARGET_CLASS, Arrays.asList(cp.split(File.pathSeparator))); LoggingUtils.getEvoLogger().info("* " + ClientProcess.getPrettyPrintIdentifier() + "Finished analyzing classpath"); }
DependencyAnalysis.analyzeClass(Properties.TARGET_CLASS, Arrays.asList(cp.split(File.pathSeparator))); testClusterGenerator = new TestClusterGenerator( DependencyAnalysis.getInheritanceTree()); testClusterGenerator.generateCluster(DependencyAnalysis.getCallGraph()); } catch (RuntimeException e) { logger.error(e.getMessage(), e);
/** * As RESET_STATIC_FINAL_FIELDS=true removes the <code>final</code> modifier * of static fields in the target class, the purpose of this test case is to * check that the TestClusterGenerator indeed does not include these fields. * * * @throws ClassNotFoundException * @throws RuntimeException */ @Test public void test() throws ClassNotFoundException, RuntimeException { Properties.TARGET_CLASS = FinalPrimitiveField.class.getCanonicalName(); Properties.RESET_STATIC_FINAL_FIELDS = true; ClassPathHandler.getInstance().changeTargetCPtoTheSameAsEvoSuite(); String cp = ClassPathHandler.getInstance().getTargetProjectClasspath(); DependencyAnalysis.analyzeClass(Properties.TARGET_CLASS, Arrays.asList(cp.split(File.pathSeparator))); InheritanceTree tree = DependencyAnalysis.getInheritanceTree(); TestClusterGenerator gen = new TestClusterGenerator(tree); assertNotNull(gen); TestCluster cluster = TestCluster.getInstance(); List<GenericAccessibleObject<?>> testCalls = cluster.getTestCalls(); assertEquals("Unexpected number of TestCalls", 2, testCalls.size()); }
targetClasses = DependencyAnalysis.analyzeTarget(Properties.TARGET_CLASS, Arrays.asList(cp.split(File.pathSeparator))); DependencyAnalysis.analyzeClass(Properties.TARGET_CLASS, Arrays.asList(cp.split(File.pathSeparator)));
private static void analyze(String className, List<String> classPath) throws RuntimeException, ClassNotFoundException { if (!inheritanceTree.hasClass(Properties.TARGET_CLASS)) { throw new ClassNotFoundException("Target class not found in inheritance tree"); } logger.debug("Calculate call tree"); CallGraph callGraph = CallGraphGenerator.analyze(className); callGraphs.put(className, callGraph); loadCallTreeClasses(callGraph); // include all the project classes in the inheritance tree and in the callgraph. if (ArrayUtil.contains(Properties.CRITERION, Criterion.IBRANCH) || Properties.INSTRUMENT_CONTEXT) { for (String classn : inheritanceTree.getAllClasses()) { if (isTargetProject(classn)) { CallGraphGenerator.analyzeOtherClasses(callGraph, classn); } } } // TODO: Need to make sure that all classes in calltree are instrumented logger.debug("Update call tree with calls to overridden methods"); CallGraphGenerator.update(callGraph, inheritanceTree); logger.debug("Create test cluster"); // if a class is not instrumented but part of the callgraph, the // generateCluster method will instrument it // update: we instrument only classes reachable from the class // under test, the callgraph is populated with all classes, but only the // set of relevant ones are instrumented - mattia TestGenerationContext.getInstance().getTestClusterGenerator().generateCluster(callGraph); gatherStatistics(); }
/** {@inheritDoc} */ @Override public void visitLdcInsn(Object cst) { // constantPool.add(cst); if (DependencyAnalysis.isTargetClassName(className)) { poolManager.addSUTConstant(cst); } else { poolManager.addNonSUTConstant(cst); } super.visitLdcInsn(cst); }
@BeforeClass public static void initialize() { Properties.TARGET_CLASS = "com.examples.with.different.packagename.context.complex.EntryPointsClass"; Properties.CRITERION = new Criterion[1]; Properties.CRITERION[0]=Criterion.IBRANCH; List<String> classpath = new ArrayList<>(); String cp = System.getProperty("user.dir") + "/target/test-classes"; classpath.add(cp); ClassPathHandler.getInstance().addElementToTargetProjectClassPath(cp); try { DependencyAnalysis .analyzeClass( "com.examples.with.different.packagename.context.complex.EntryPointsClass", classpath); } catch (ClassNotFoundException | RuntimeException e) { Assert.fail(e.toString()); } }
/** * As RESET_STATIC_FINAL_FIELDS=true removes the <code>final</code> modifier * of static fields in the target class, the purpose of this test case is to * check that the TestClusterGenerator indeed does not include these fields. * * * @throws ClassNotFoundException * @throws RuntimeException */ @Test public void test() throws ClassNotFoundException, RuntimeException { Properties.TARGET_CLASS = FinalReferenceField.class.getCanonicalName(); Properties.RESET_STATIC_FINAL_FIELDS = true; ClassPathHandler.getInstance().changeTargetCPtoTheSameAsEvoSuite(); String cp = ClassPathHandler.getInstance().getTargetProjectClasspath(); DependencyAnalysis.analyzeClass(Properties.TARGET_CLASS, Arrays.asList(cp.split(File.pathSeparator))); InheritanceTree tree = DependencyAnalysis.getInheritanceTree(); TestClusterGenerator gen = new TestClusterGenerator(tree); assertNotNull(gen); TestCluster cluster = TestCluster.getInstance(); List<GenericAccessibleObject<?>> testCalls = cluster.getTestCalls(); assertEquals("Unexpected number of TestCalls", 2, testCalls.size()); }
/** {@inheritDoc} */ @Override public MethodVisitor visitMethod(int methodAccess, String name, String descriptor, String signature, String[] exceptions) { MethodVisitor mv = super.visitMethod(methodAccess, name, descriptor, signature, exceptions); /* String classNameWithDots = Utils.getClassNameFromResourcePath(className); if (REPLACE_STRING && (classNameWithDots.equals(target_class) || (classNameWithDots.startsWith(target_class + "$")))) { mv = new StringReplacementMethodAdapter(methodAccess, descriptor, mv); } */ if (DependencyAnalysis.isTargetClassName(className)) { for (Type argumentType : Type.getArgumentTypes(descriptor)) { poolManager.addSUTConstant(argumentType); } } mv = new PrimitivePoolMethodAdapter(mv, className); return mv; }
/** * Start analysis from target * * @param target (e.g., directory, or jar file) */ public static Set<String> analyzeTarget(String target, List<String> classPath) throws RuntimeException, ClassNotFoundException { initInheritanceTree(classPath); targetClasses = ResourceList.getInstance(TestGenerationContext.getInstance().getClassLoaderForSUT()).getAllClasses(target, false); for (String className : targetClasses) { Properties.TARGET_CLASS = className; analyze(className, classPath); } return targetClasses; }
@Override public void run() { changeState(ClientState.STARTED); Sandbox.goingToExecuteSUTCode(); TestGenerationContext.getInstance().goingToExecuteSUTCode(); Sandbox.goingToExecuteUnsafeCodeOnSameThread(); try { LoggingUtils.getEvoLogger().info("* Analyzing classpath (dependency analysis)"); DependencyAnalysis.analyzeClass(Properties.TARGET_CLASS, Arrays.asList(ClassPathHandler.getInstance().getClassPathElementsForTargetProject())); StringBuffer fileNames = new StringBuffer(); for(Class<?> clazz : TestCluster.getInstance().getAnalyzedClasses()) { fileNames.append(clazz.getName()); fileNames.append("\n"); } LoggingUtils.getEvoLogger().info("* Writing class dependencies to file "+fileName); FileIOUtils.writeFile(fileNames.toString(), fileName); } catch (Throwable t) { logger.error("Error when analysing coverage for: " + Properties.TARGET_CLASS + " with seed " + Randomness.getSeed() + ". Configuration id : " + Properties.CONFIGURATION_ID, t); } finally { Sandbox.doneWithExecutingUnsafeCodeOnSameThread(); Sandbox.doneWithExecutingSUTCode(); TestGenerationContext.getInstance().doneWithExecutingSUTCode(); } changeState(ClientState.DONE); } });
public static CallGraph analyzeOtherClasses(CallGraph callgraph, String className) { ClassNode targetClass = DependencyAnalysis.getClassNode(className); if (targetClass != null) handle(callgraph, targetClass, 0); return callgraph; }
@Override public List<CBranchTestFitness> getCoverageGoals() { //TODO this creates duplicate goals. Momentary fixed using a Set, but it should be optimised Set<CBranchTestFitness> goals = new HashSet<>(); // retrieve set of branches BranchCoverageFactory branchFactory = new BranchCoverageFactory(); List<BranchCoverageTestFitness> branchGoals = branchFactory.getCoverageGoals(); CallGraph callGraph = DependencyAnalysis.getCallGraph(); // try to find all occurrences of this branch in the call tree for (BranchCoverageTestFitness branchGoal : branchGoals) { logger.info("Adding context branches for " + branchGoal.toString()); for (CallContext context : callGraph.getMethodEntryPoint(branchGoal.getClassName(), branchGoal.getMethod())) { goals.add(new CBranchTestFitness(branchGoal.getBranchGoal(), context)); } } logger.info("Created " + goals.size() + " goals"); return new ArrayList<CBranchTestFitness>(goals); } }
return true; } else { InheritanceTree inheritanceTree = DependencyAnalysis.getInheritanceTree(); Set<Class<?>> boundCandidates = new LinkedHashSet<Class<?>>(); for (Type bound : typeVariable.getBounds()) {
@Override public void visitInnerClass(String name, String outerName, String innerName, int access) { if ((access & Opcodes.ACC_PUBLIC) == Opcodes.ACC_PUBLIC) { if (DependencyAnalysis.isTargetClassName(className)) { Type type = Type.getObjectType(name); poolManager.addSUTConstant(type); } } super.visitInnerClass(name, outerName, innerName, access); } }