Skip to content

Commit

Permalink
Parameterize OracleTest
Browse files Browse the repository at this point in the history
  • Loading branch information
pouryafard75 authored and tsantalis committed Apr 2, 2024
1 parent 3401ade commit 294e327
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 100 deletions.
19 changes: 7 additions & 12 deletions src/test/java/org/codetracker/util/AttributeOracleTest.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package org.codetracker.util;

import java.io.IOException;
import java.util.List;

import org.codetracker.api.AttributeTracker;
import org.codetracker.api.CodeTracker;
import org.codetracker.api.History;
import org.codetracker.element.Attribute;
import org.codetracker.experiment.oracle.AttributeOracle;
import org.codetracker.experiment.oracle.history.AttributeHistoryInfo;
import org.eclipse.jgit.lib.Repository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.Arguments;

import java.io.IOException;
import java.util.stream.Stream;

public class AttributeOracleTest extends OracleTest {
private static final String EXPECTED = System.getProperty("user.dir") + "/src/test/resources/attribute/";

private History<Attribute> attributeTracker(AttributeHistoryInfo attributeHistoryInfo, Repository repository) throws Exception {
private static History<Attribute> attributeTracker(AttributeHistoryInfo attributeHistoryInfo, Repository repository) throws Exception {
AttributeTracker attributeTracker = CodeTracker.attributeTracker()
.repository(repository)
.filePath(attributeHistoryInfo.getFilePath())
Expand All @@ -26,12 +26,7 @@ private History<Attribute> attributeTracker(AttributeHistoryInfo attributeHistor
return attributeTracker.track();
}

@Test
public void testAccuracy() throws IOException, InterruptedException {
List<AttributeOracle> oracles = AttributeOracle.all();
for (AttributeOracle oracle : oracles) {
loadExpected(EXPECTED + oracle.getName() + "-expected.txt");
codeTracker(oracle, this::attributeTracker, QUARTER_CORES);
}
public static Stream<Arguments> testProvider() throws IOException {
return getArgumentsStream(AttributeOracle.all(), EXPECTED, AttributeOracleTest::attributeTracker);
}
}
22 changes: 8 additions & 14 deletions src/test/java/org/codetracker/util/BlockOracleTest.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,37 @@
package org.codetracker.util;

import java.io.IOException;
import java.util.List;

import gr.uom.java.xmi.LocationInfo;
import org.codetracker.api.BlockTracker;
import org.codetracker.api.CodeTracker;
import org.codetracker.api.History;
import org.codetracker.element.Block;
import org.codetracker.experiment.oracle.BlockOracle;
import org.codetracker.experiment.oracle.history.BlockHistoryInfo;
import org.eclipse.jgit.lib.Repository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.Arguments;

import gr.uom.java.xmi.LocationInfo.CodeElementType;;
import java.io.IOException;
import java.util.stream.Stream;

public class BlockOracleTest extends OracleTest {
private static final String EXPECTED = System.getProperty("user.dir") + "/src/test/resources/block/";

private History<Block> blockTracker(BlockHistoryInfo blockHistoryInfo, Repository repository) throws Exception {
private static History<Block> blockTracker(BlockHistoryInfo blockHistoryInfo, Repository repository) throws Exception {
BlockTracker blockTracker = CodeTracker
.blockTracker()
.repository(repository)
.filePath(blockHistoryInfo.getFilePath())
.startCommitId(blockHistoryInfo.getStartCommitId())
.methodName(blockHistoryInfo.getFunctionName())
.methodDeclarationLineNumber(blockHistoryInfo.getFunctionStartLine())
.codeElementType(CodeElementType.valueOf(blockHistoryInfo.getBlockType()))
.codeElementType(LocationInfo.CodeElementType.valueOf(blockHistoryInfo.getBlockType()))
.blockStartLineNumber(blockHistoryInfo.getBlockStartLine())
.blockEndLineNumber(blockHistoryInfo.getBlockEndLine())
.build();
return blockTracker.track();
}

@Test
public void testAccuracy() throws IOException, InterruptedException {
List<BlockOracle> oracles = BlockOracle.all();
for (BlockOracle oracle : oracles) {
loadExpected(EXPECTED + oracle.getName() + "-expected.txt");
codeTracker(oracle, this::blockTracker, ALL_CORES);
}
public static Stream<Arguments> testProvider() throws IOException {
return getArgumentsStream(BlockOracle.all(), EXPECTED, BlockOracleTest::blockTracker);
}
}
20 changes: 7 additions & 13 deletions src/test/java/org/codetracker/util/MethodOracleTest.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package org.codetracker.util;

import java.io.IOException;
import java.util.List;

import org.codetracker.api.CodeTracker;
import org.codetracker.api.History;
import org.codetracker.api.MethodTracker;
import org.codetracker.element.Method;
import org.codetracker.experiment.oracle.MethodOracle;
import org.codetracker.experiment.oracle.history.MethodHistoryInfo;
import org.eclipse.jgit.lib.Repository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.Arguments;

import java.io.IOException;
import java.util.stream.Stream;

public class MethodOracleTest extends OracleTest {
private static final String EXPECTED = System.getProperty("user.dir") + "/src/test/resources/method/";

private History<Method> methodTracker(MethodHistoryInfo methodHistoryInfo, Repository repository) throws Exception {
private static History<Method> methodTracker(MethodHistoryInfo methodHistoryInfo, Repository repository) throws Exception {
MethodTracker methodTracker = CodeTracker.methodTracker()
.repository(repository)
.filePath(methodHistoryInfo.getFilePath())
Expand All @@ -25,13 +25,7 @@ private History<Method> methodTracker(MethodHistoryInfo methodHistoryInfo, Repos
.build();
return methodTracker.track();
}

@Test
public void testAccuracy() throws IOException, InterruptedException {
List<MethodOracle> oracles = MethodOracle.all();
for (MethodOracle oracle : oracles) {
loadExpected(EXPECTED + oracle.getName() + "-expected.txt");
codeTracker(oracle, this::methodTracker, ALL_CORES);
}
public static Stream<Arguments> testProvider() throws IOException {
return getArgumentsStream(MethodOracle.all(), EXPECTED, MethodOracleTest::methodTracker);
}
}
106 changes: 57 additions & 49 deletions src/test/java/org/codetracker/util/OracleTest.java
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package org.codetracker.util;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.google.common.graph.EndpointPair;
import org.codetracker.HistoryImpl;
import org.codetracker.api.CodeElement;
import org.codetracker.api.Edge;
import org.codetracker.api.History;
import org.codetracker.change.Change;
import org.codetracker.experiment.AbstractExperimentStarter;
import org.codetracker.experiment.AbstractExperimentStarter.CheckedBiFunction;
import org.codetracker.experiment.oracle.AbstractOracle;
import org.codetracker.experiment.oracle.history.AbstractHistoryInfo;
import org.codetracker.experiment.oracle.history.ChangeHistory;
import org.eclipse.jgit.lib.Repository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import org.refactoringminer.api.GitService;
import org.refactoringminer.util.GitServiceImpl;

import com.google.common.graph.EndpointPair;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;

public abstract class OracleTest {
private static final String FOLDER_TO_CLONE = "tmp/";
Expand Down Expand Up @@ -56,50 +57,57 @@ protected static void loadExpected(String filePath) {
}
}

protected <H extends AbstractHistoryInfo, E extends CodeElement> void codeTracker(AbstractOracle<H> oracle, CheckedBiFunction<H, Repository, History<E>> tracker, int cores) throws IOException, InterruptedException {
protected static <H extends AbstractHistoryInfo, E extends CodeElement> Stream<Arguments> codeTrackerTestProvider
(AbstractOracle<H> oracle, CheckedBiFunction<H, Repository, History<E>> tracker) {
GitService gitService = new GitServiceImpl();
ExecutorService pool = Executors.newWorkStealingPool(cores);
Stream.Builder<Arguments> builder = Stream.builder();
for (Map.Entry<String, H> oracleInstance : oracle.getOracle().entrySet()) {
String fileName = oracleInstance.getKey();
H historyInfo = oracleInstance.getValue();
builder.add(Arguments.of(tracker,historyInfo, gitService, fileName));
}
return builder.build();
}

//TODO: Replace with parameterized test
Runnable r = () -> {
String repositoryWebURL = historyInfo.getRepositoryWebURL();
String repositoryName = repositoryWebURL.replace("https://github.com/", "").replace(".git", "").replace("/", "\\");
String projectDirectory = FOLDER_TO_CLONE + repositoryName;

try (Repository repository = gitService.cloneIfNotExists(projectDirectory, repositoryWebURL)) {
HashMap<String, ChangeHistory> oracleChanges = oracle(historyInfo.getExpectedChanges());
History<E> history = tracker.apply(historyInfo, repository);
HashMap<String, ChangeHistory> detectedChanges = new HashMap<>();
HashMap<String, ChangeHistory> notDetectedChanges = new HashMap<>(oracleChanges);
HashMap<String, ChangeHistory> falseDetectedChanges = processHistory((HistoryImpl<E>) history);

for (Map.Entry<String, ChangeHistory> oracleChangeEntry : oracleChanges.entrySet()) {
String changeKey = oracleChangeEntry.getKey();
if (falseDetectedChanges.containsKey(changeKey)) {
detectedChanges.put(changeKey, falseDetectedChanges.get(changeKey));
notDetectedChanges.remove(changeKey);
falseDetectedChanges.remove(changeKey);
}
}
final int actualTP = detectedChanges.size();
final int actualFP = falseDetectedChanges.size();
final int actualFN = notDetectedChanges.size();
Assertions.assertAll(
() -> Assertions.assertEquals(expectedTP.get(fileName), actualTP, String.format("Should have %s True Positives, but has %s", expectedTP.get(fileName), actualTP)),
() -> Assertions.assertEquals(expectedFP.get(fileName), actualFP, String.format("Should have %s False Positives, but has %s", expectedFP.get(fileName), actualFP)),
() -> Assertions.assertEquals(expectedFN.get(fileName), actualFN, String.format("Should have %s False Negatives, but has %s", expectedFN.get(fileName), actualFN))
);
} catch (Exception e) {
e.printStackTrace();
@ParameterizedTest(name = "{index}: {0} , {1}")
@MethodSource(value = "testProvider")
public <H extends AbstractHistoryInfo, E extends CodeElement> void testCodeTracker(CheckedBiFunction<H, Repository, History<E>> tracker, H historyInfo, GitService gitService, String fileName) {
String repositoryWebURL = historyInfo.getRepositoryWebURL();
String repositoryName = repositoryWebURL.replace("https://github.com/", "").replace(".git", "").replace("/", "\\");
String projectDirectory = FOLDER_TO_CLONE + repositoryName;

try (Repository repository = gitService.cloneIfNotExists(projectDirectory, repositoryWebURL)) {
HashMap<String, ChangeHistory> oracleChanges = oracle(historyInfo.getExpectedChanges());
History<E> history = tracker.apply(historyInfo, repository);
HashMap<String, ChangeHistory> detectedChanges = new HashMap<>();
HashMap<String, ChangeHistory> notDetectedChanges = new HashMap<>(oracleChanges);
HashMap<String, ChangeHistory> falseDetectedChanges = processHistory((HistoryImpl<E>) history);

for (Map.Entry<String, ChangeHistory> oracleChangeEntry : oracleChanges.entrySet()) {
String changeKey = oracleChangeEntry.getKey();
if (falseDetectedChanges.containsKey(changeKey)) {
detectedChanges.put(changeKey, falseDetectedChanges.get(changeKey));
notDetectedChanges.remove(changeKey);
falseDetectedChanges.remove(changeKey);
}
};
pool.submit(r);
}
final int actualTP = detectedChanges.size();
final int actualFP = falseDetectedChanges.size();
final int actualFN = notDetectedChanges.size();
Assertions.assertAll(
() -> Assertions.assertEquals(expectedTP.get(fileName), actualTP, String.format("Should have %s True Positives, but has %s", expectedTP.get(fileName), actualTP)),
() -> Assertions.assertEquals(expectedFP.get(fileName), actualFP, String.format("Should have %s False Positives, but has %s", expectedFP.get(fileName), actualFP)),
() -> Assertions.assertEquals(expectedFN.get(fileName), actualFN, String.format("Should have %s False Negatives, but has %s", expectedFN.get(fileName), actualFN))
);
} catch (Exception e) {
e.printStackTrace();
}
pool.shutdown();
pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
}
protected static <H extends AbstractHistoryInfo, E extends CodeElement> Stream<Arguments> getArgumentsStream(List<? extends AbstractOracle<H>> all, String expected, AbstractExperimentStarter.CheckedBiFunction<H, Repository, History<E>> tracker) {
return all.stream().flatMap(oracle -> {
loadExpected(expected + oracle.getName() + "-expected.txt");
return codeTrackerTestProvider(oracle, tracker);
});
}

protected static HashMap<String, ChangeHistory> oracle(List<ChangeHistory> expectedChanges) {
Expand Down
19 changes: 7 additions & 12 deletions src/test/java/org/codetracker/util/VariableOracleTest.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
package org.codetracker.util;

import java.io.IOException;
import java.util.List;

import org.codetracker.api.CodeTracker;
import org.codetracker.api.History;
import org.codetracker.api.VariableTracker;
import org.codetracker.element.Variable;
import org.codetracker.experiment.oracle.VariableOracle;
import org.codetracker.experiment.oracle.history.VariableHistoryInfo;
import org.eclipse.jgit.lib.Repository;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.provider.Arguments;

import java.io.IOException;
import java.util.stream.Stream;

public class VariableOracleTest extends OracleTest {
private static final String EXPECTED = System.getProperty("user.dir") + "/src/test/resources/variable/";

private History<Variable> variableTracker(VariableHistoryInfo variableHistoryInfo, Repository repository) throws Exception {
private static History<Variable> variableTracker(VariableHistoryInfo variableHistoryInfo, Repository repository) throws Exception {
VariableTracker variableTracker = CodeTracker.variableTracker()
.repository(repository)
.filePath(variableHistoryInfo.getFilePath())
Expand All @@ -28,12 +28,7 @@ private History<Variable> variableTracker(VariableHistoryInfo variableHistoryInf
return variableTracker.track();
}

@Test
public void testAccuracy() throws IOException, InterruptedException {
List<VariableOracle> oracles = VariableOracle.all();
for (VariableOracle oracle : oracles) {
loadExpected(EXPECTED + oracle.getName() + "-expected.txt");
codeTracker(oracle, this::variableTracker, HALF_CORES);
}
public static Stream<Arguments> testProvider() throws IOException {
return getArgumentsStream(VariableOracle.all(), EXPECTED, VariableOracleTest::variableTracker);
}
}

0 comments on commit 294e327

Please sign in to comment.