Skip to content

Commit

Permalink
Refactoring and JavaDocs
Browse files Browse the repository at this point in the history
  • Loading branch information
henriquelemos0 committed Apr 15, 2014
1 parent 916a67b commit cd97d88
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 52 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package br.usp.each.saeg.jaguar.main;
package br.usp.each.saeg.jaguar;

import java.io.File;
import java.io.IOException;
Expand All @@ -16,20 +16,40 @@
import br.usp.each.saeg.jaguar.heuristic.Heuristic;
import br.usp.each.saeg.jaguar.heuristic.HeuristicCalculator;

/**
* This class store the coverage information received from Jacoco and generate a
* rank of more suspicious test requirement based on one SFL Heuristic.
*
* @author Henrique Ribeiro
*/
public class Jaguar {

private int nTests;
private int nTestsFailed;
private Heuristic heuristic;
private int nTests = 0;
private int nTestsFailed = 0;
private HashMap<Integer, TestRequirement> testRequirements = new HashMap<Integer, TestRequirement>();
private Heuristic heuristic;

/**
* Construct the Jaguar object.
*
* @param heuristic
* the heuristic to be used on the fault localization rank.
*/
public Jaguar(Heuristic heuristic) {
this.heuristic = heuristic;
}

public void analyse(final ExecutionDataStore executionData, boolean currentTestFailed) {
/**
* Receive the coverage information and store it on Test Requiremtns.
*
* @param executionData the covarege data from Jacoco
* @param currentTestFailed result of the test
*
*/
public void collect(final ExecutionDataStore executionData, boolean currentTestFailed) {
final CoverageBuilder coverageVisitor = new CoverageBuilder();
Analyzer analyzer = new Analyzer(executionData, coverageVisitor);

try {
analyzer.analyzeAll(new File("/home/unknown/workspace/jaguar/target/classes/"));
} catch (IOException e) {
Expand All @@ -44,26 +64,49 @@ public void analyse(final ExecutionDataStore executionData, boolean currentTestF
ILine line = clazz.getLine(currentLine);
LineCoverageStatus coverageStatus = LineCoverageStatus.as(line.getStatus());
if (LineCoverageStatus.FULLY_COVERED == coverageStatus || LineCoverageStatus.PARTLY_COVERED == coverageStatus) {
TestRequirement testRequirement = new TestRequirement(clazz.getName(), currentLine);
TestRequirement foundTest = testRequirements.get(testRequirement.hashCode());

if (foundTest == null) {
testRequirements.put(testRequirement.hashCode(), testRequirement);
} else {
testRequirement = foundTest;
}

if (currentTestFailed) {
testRequirement.increaseFailed();
} else {
testRequirement.increasePassed();
}
updateRequirement(clazz.getName(), currentLine, currentTestFailed);
}
}
}
}
}

/**
* Update the testRequirement info. If it does not exist, create a new one.
* If the test has failed, increment the cef (coefficient of executed and
* failed) If the test has passed, increment the cep (coefficient of
* executed and passed)
*
* @param className
* the class name, including package
* @param lineNumber
* the line number
* @param failed
* if the test has failed
*
*/
private void updateRequirement(String className, int lineNumber, boolean failed) {
TestRequirement testRequirement = new TestRequirement(className, lineNumber);
TestRequirement foundRequirement = testRequirements.get(testRequirement.hashCode());

if (foundRequirement == null) {
testRequirements.put(testRequirement.hashCode(), testRequirement);
} else {
testRequirement = foundRequirement;
}

if (failed) {
testRequirement.increaseFailed();
} else {
testRequirement.increasePassed();
}
}

/**
* Calculate the rank based on the heuristic and testRequirements. Print the
* rank in descending order.
*
*/
public void generateRank() {
HeuristicCalculator calc = new HeuristicCalculator(heuristic, testRequirements.values(), nTests - nTestsFailed, nTestsFailed);
ArrayList<TestRequirement> result = calc.calculateRank();
Expand Down
7 changes: 7 additions & 0 deletions src/main/java/br/usp/each/saeg/jaguar/infra/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
import java.util.ArrayList;
import java.util.List;

/**
* Provides utilies methods that can be used to search and list files within a
* directory.
*
* @author Henrique Ribeiro
*
*/
public class FileUtils {

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package br.usp.each.saeg.jaguar.main;
package br.usp.each.saeg.jaguar.runner;

import java.io.IOException;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collection;
Expand All @@ -18,8 +13,8 @@
import org.junit.runners.Suite;
import org.junit.runners.model.InitializationError;

import br.usp.each.saeg.jaguar.Jaguar;
import br.usp.each.saeg.jaguar.heuristic.Heuristic;
import br.usp.each.saeg.jaguar.heuristic.HeuristicEnum;
import br.usp.each.saeg.jaguar.heuristic.impl.DRTHeuristic;
import br.usp.each.saeg.jaguar.heuristic.impl.JaccardHeuristic;
import br.usp.each.saeg.jaguar.heuristic.impl.Kulczynski2Heuristic;
Expand All @@ -33,6 +28,22 @@
import br.usp.each.saeg.jaguar.infra.FileUtils;
import br.usp.each.saeg.jaguar.jacoco.JacocoTCPClient;

/**
* JUnit Runner for fault localization.
* <p>
*
* This runner will search recursively for JUnits tests in all classes within
* the current directory. Then will run the tests, collecting coverage
* information using a jacocoagent running as tcpserver. Finally, will print a
* list of tests requiremtns order by suspisciousness.
* <p>
*
* It is mandatory to run using the following JM arguments:
* -javaagent:{jacoco_agent_path}/jacocoagent.jar=output=tcpserver
*
* @author Henrique Ribeiro
*
*/
public class JaguarRunner extends Suite {

private static Collection<Heuristic> heuristics = new ArrayList<Heuristic>() {
Expand All @@ -54,18 +65,31 @@ public class JaguarRunner extends Suite {
private static Jaguar jaguar;
private static Heuristic heuristic;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface JaguarHeuristic {
/**
* @return the classes to be run
*/
public HeuristicEnum value();
/**
* Constructor.
*
* @param clazz
* * the class calling the runner
* @throws InitializationError
* @throws ClassNotFoundException
*/
public JaguarRunner(final Class<?> clazz) throws InitializationError, ClassNotFoundException {
super(clazz, FileUtils.findTestClasses(clazz));
heuristic = getHeuristic(clazz);
}

/**
* Return the heuristic based on the enum passed on the annotation
* {@link JaguarRunnerHeuristic}. If no heuristic is found,
* {@link TarantulaHeuristic} is used.
*
* @param klass
* class annotated
* @return the heuristic
* @throws InitializationError
*/
private static Heuristic getHeuristic(Class<?> klass) throws InitializationError {
JaguarHeuristic heuristicAnnotation = klass.getAnnotation(JaguarHeuristic.class);
JaguarRunnerHeuristic heuristicAnnotation = klass.getAnnotation(JaguarRunnerHeuristic.class);
if (heuristicAnnotation == null) {
return new TarantulaHeuristic();
}
Expand All @@ -77,19 +101,6 @@ private static Heuristic getHeuristic(Class<?> klass) throws InitializationError
return new TarantulaHeuristic();
}

/**
* Constructor.
*
* @param clazz
* * the class calling the runner
* @throws InitializationError
* @throws ClassNotFoundException
*/
public JaguarRunner(final Class<?> clazz) throws InitializationError, ClassNotFoundException {
super(clazz, FileUtils.findTestClasses(clazz));
heuristic = getHeuristic(clazz);
}

/**
* {@inheritDoc}
*
Expand All @@ -111,7 +122,7 @@ public void testStarted(final Description description) {
@Override
public void testFinished(final Description description) {
try {
jaguar.analyse(tcpClient.read(), currentTestFailed);
jaguar.collect(tcpClient.read(), currentTestFailed);
} catch (IOException e) {
e.printStackTrace();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package br.usp.each.saeg.jaguar.runner;

import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import br.usp.each.saeg.jaguar.heuristic.HeuristicEnum;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited
public @interface JaguarRunnerHeuristic {
/**
* @return the heuristic to be used
*/
public HeuristicEnum value();
}
6 changes: 3 additions & 3 deletions src/test/java/br/usp/each/saeg/jaguar/AllTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
import org.junit.runner.RunWith;

import br.usp.each.saeg.jaguar.heuristic.HeuristicEnum;
import br.usp.each.saeg.jaguar.main.JaguarRunner;
import br.usp.each.saeg.jaguar.main.JaguarRunner.JaguarHeuristic;
import br.usp.each.saeg.jaguar.runner.JaguarRunnerHeuristic;
import br.usp.each.saeg.jaguar.runner.JaguarRunner;

@RunWith(JaguarRunner.class)
@JaguarHeuristic(HeuristicEnum.JACCARD)
@JaguarRunnerHeuristic(HeuristicEnum.OCHIAI)
public class AllTests {

}

0 comments on commit cd97d88

Please sign in to comment.