Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
7488843
tuscan and alphabetical
Jul 22, 2022
d17683c
tuscan
Jul 22, 2022
8ed860a
detector factory
Jul 22, 2022
05c1213
fixed tuscan for 3 and 5
Jul 23, 2022
ba89c16
fixed tuscan for 3 and 5
Jul 23, 2022
9bf7466
fixed tuscan orders for 3 & 5
Jul 25, 2022
128a489
fixed typo
Jul 25, 2022
59f11bf
squashed commits
Jul 22, 2022
990ad2c
Merge branch 'master' of https://github.com/mmk-1/iDFlakies
mmk-1 Jul 25, 2022
c54ee57
fixed whitespaces
Jul 27, 2022
72a0e41
fixed Tuscan.java
Jul 27, 2022
bf1cc28
fixed alphabeticalDetector.java
Jul 27, 2022
b2a9236
fixed DetectorFactory.java
Jul 27, 2022
a29ea16
fixed whitespaces
Jul 27, 2022
9c305ec
fixed issues mentioned in PR review
Jul 28, 2022
259518c
TuscanIntraClass
Aug 3, 2022
9d726a3
update tuscanIntraClassOrder()
Aug 5, 2022
e8cff40
add test
Aug 6, 2022
2c3f205
update testshuffler
Aug 6, 2022
1193c73
update tuscan only class detector
Aug 6, 2022
a8e7b13
update tuscan
Aug 6, 2022
0a0d910
inter class
Aug 10, 2022
6553dcb
fixed round calculation in inter-class
Aug 13, 2022
6ce0959
removed unnecessary imports
Aug 13, 2022
2e5dc88
added tuscan inter class test
Aug 15, 2022
cb62cf8
added inter-class test
Aug 16, 2022
a489f2c
fixed tests
Aug 16, 2022
964d150
fixed onlyclass
Aug 17, 2022
9c505cd
fixed whitespaced
Aug 17, 2022
4087f5e
added alphabetical-class-method
Aug 17, 2022
1b40aea
fixed empty line
Aug 17, 2022
9a0dafd
reflected PR #48 changes
Aug 20, 2022
52d0aa8
Merge branch 'master' into tuscan_square_detectors
Aug 21, 2022
6e3a511
fixed assertion error
Aug 21, 2022
24e0e51
moved tuscan-inter-class to another branch
Aug 27, 2022
0db2f7d
Revert "fixed assertion error"
mmk-1 Aug 27, 2022
c635c0b
fixed tuscan assert error
Aug 27, 2022
dd81e59
fixed PR #49 commented issues
Sep 7, 2022
f2dade2
indentation
Sep 7, 2022
702a3fd
spacing
Sep 7, 2022
b558112
refactored tuscan tests
Sep 11, 2022
add6792
refactored another tuscan test
Sep 11, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public static String className(final String testName) {
}

private final HashMap<String, List<String>> classToMethods;

private final String type;
private final List<String> tests;
private final Set<String> alreadySeenOrders = new HashSet<>();
Expand Down Expand Up @@ -203,7 +202,7 @@ public List<String> alphabeticalOrderSelector(int round) {
return alphabeticalAndTuscanOrder(round, false);
}
}

private List<String> alphabeticalClassMethodOrder() {
final List<String> fullTestOrder = new ArrayList<>();
for (String className : classToMethods.keySet()) {
Expand Down Expand Up @@ -234,4 +233,46 @@ public List<String> alphabeticalAndTuscanOrder(int count, boolean isTuscan) {
}
return fullTestOrder;
}

public List<String> tuscanIntraClassOrder(int round) {
List<String> classes = new ArrayList<>(classToMethods.keySet());
HashMap<String, int[][]> classToPermutations = new HashMap<String, int[][]>();
Collections.sort(classes);
final List<String> fullTestOrder = new ArrayList<>();
int n = classes.size(); // n is number of classes
int[][] classOrdering = Tuscan.generateTuscanPermutations(n);
for (String className : classes) {
int[][] methodPermuation = Tuscan.generateTuscanPermutations(classToMethods.get(className).size());
classToPermutations.put(className, methodPermuation);
}
HashMap<String, List<String>> newClassToMethods = new HashMap<String, List<String>>();
List<String> permClasses = new ArrayList<String>();
int classRound = round;
while ((classOrdering.length - 1) < classRound) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should add some comment to explain the reasoning/intention behind this loop concerning the class round, so we remember later what is the goal.

// When a intra-class method ordering has covered all pairs but other classes not,
// it will start to loop through the intra-class method ordering again until all rounds are done.
classRound -= classOrdering.length;
}
for (int i = 0; i < classOrdering[classRound].length - 1; i++) {
permClasses.add(classes.get(classOrdering[classRound][i]));
}
for (String className : permClasses) {
List<String> methods = classToMethods.get(className);
List<String> permMethods = new ArrayList<String>();
int[][] currMethodOrdering = classToPermutations.get(className);
n = methods.size();
int methodRound = round;
while((currMethodOrdering.length - 1) < methodRound) {
methodRound -= currMethodOrdering.length;
}
for (int i = 0; i < currMethodOrdering[methodRound].length - 1; i++) {
permMethods.add(methods.get(currMethodOrdering[methodRound][i]));
}
newClassToMethods.put(className, permMethods);
}
for (String className : permClasses) {
fullTestOrder.addAll(newClassToMethods.get(className));
}
return fullTestOrder;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package edu.illinois.cs.dt.tools.detection.detectors;

import edu.illinois.cs.dt.tools.runner.InstrumentingSmartRunner;
import edu.illinois.cs.dt.tools.utility.Tuscan;
import edu.illinois.cs.testrunner.configuration.Configuration;

import java.io.File;
Expand All @@ -24,10 +25,12 @@ public static Detector makeDetector(final InstrumentingSmartRunner runner, final
return new OriginalDetector(runner, baseDir, rounds, tests);
} else if (detectorType().equals("smart-shuffle")) {
return new SmartShuffleDetector(runner, baseDir, rounds, tests, detectorType());
} else if (detectorType().equals("tuscan")){
return new TuscanOnlyClassDetector(runner, baseDir, rounds, detectorType(), tests);
} else if (detectorType().startsWith("alphabetical")) {
return new AlphabeticalDetector(runner, baseDir, rounds, detectorType(), tests);
} else if (detectorType().equals("tuscan")) {
return new TuscanOnlyClassDetector(runner, baseDir, rounds, detectorType(), tests);
} else if (detectorType().equals("tuscan-intra-class")) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe move this above to put next to tuscan (or move tuscan below to be next to this one).

return new TuscanIntraClassDetector(runner, baseDir, rounds, detectorType(), tests);
}
return new RandomDetector("random", baseDir, runner, rounds, tests);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package edu.illinois.cs.dt.tools.detection.detectors;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import edu.illinois.cs.dt.tools.detection.DetectionRound;
import edu.illinois.cs.dt.tools.detection.DetectorUtil;
import edu.illinois.cs.dt.tools.detection.TestShuffler;
import edu.illinois.cs.dt.tools.detection.filters.ConfirmationFilter;
import edu.illinois.cs.dt.tools.detection.filters.UniqueFilter;
import edu.illinois.cs.dt.tools.runner.InstrumentingSmartRunner;
import edu.illinois.cs.testrunner.data.results.TestRunResult;
import edu.illinois.cs.testrunner.runner.Runner;

public class TuscanIntraClassDetector extends ExecutingDetector {
private final List<String> tests;
private TestRunResult origResult;

private final HashMap<String, List<String>> classToMethods;
private final TestShuffler testShuffler;

public static int getClassesSize(List<String> tests) {
List<String> classes = new ArrayList<String>();
for (final String test : tests) {
final String className = TestShuffler.className(test);
if (!classes.contains(className)) {
classes.add(className);
}
}
return classes.size();
}

public static int findMaxMethodSize(HashMap<String, List<String>> classToMethods) {
int maxMethodSize = 0;
for (String className : classToMethods.keySet()) {
int nn = classToMethods.get(className).size();
if (maxMethodSize < nn) {
maxMethodSize = nn;
}
}
return maxMethodSize;
}

public TuscanIntraClassDetector(final Runner runner, final File baseDir, final int rounds, final String type, final List<String> tests) {
super(runner, baseDir, rounds, type);
classToMethods = new HashMap<>();
for (final String test : tests) {
final String className = TestShuffler.className(test);
if (!classToMethods.containsKey(className)) {
classToMethods.put(className, new ArrayList<>());
}
classToMethods.get(className).add(test);
}
int classSize = classToMethods.keySet().size();
if (classSize == 3 || classSize == 5) {
classSize++;
}
int maxMethodSize = findMaxMethodSize(classToMethods);
if (maxMethodSize == 3 || maxMethodSize == 5) {
maxMethodSize++;
}
this.rounds = rounds;
if (classSize > maxMethodSize) {
if (this.rounds > classSize) {
this.rounds = classSize;
}
} else {
if (this.rounds > maxMethodSize) {
this.rounds = maxMethodSize;
}
}
this.tests = tests;
this.testShuffler = new TestShuffler(type, rounds, tests, baseDir);
this.origResult = DetectorUtil.originalResults(tests, runner);
if (runner instanceof InstrumentingSmartRunner) {
addFilter(new ConfirmationFilter(name, tests, (InstrumentingSmartRunner) runner));
} else {
addFilter(new ConfirmationFilter(name, tests, InstrumentingSmartRunner.fromRunner(runner, baseDir)));
}
addFilter(new UniqueFilter());
}

@Override
public DetectionRound results() throws Exception {
return makeDts(origResult, runList(testShuffler.tuscanIntraClassOrder(absoluteRound.get())));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

public class Tuscan {
public static int[][] generateTuscanPermutations(int arg) {
if (arg == 3) {
if (arg == 1) {
generateOne();
} else if (arg == 3) {
generateThree();
} else if (arg == 5) {
generateFive();
Expand All @@ -11,7 +13,7 @@ public static int[][] generateTuscanPermutations(int arg) {
}
return r;
}

private static int[][] r;

private static void helper(int[] a, int i) {
Expand Down Expand Up @@ -85,7 +87,7 @@ private static void generateTuscanSquare(int n) {
while (nn != n) {
// https://ww.sciencedirect.com/science/article/pii/0095895680900441
n = n * 2 - 1;
int h = (n + 1) / 2;
int h = (n + 1) / 2;
for (int i = 0; i < h; i++) {
for (int j = 0; j < h; j++) {
r[i][n - j] = r[i][j] + h;
Expand Down Expand Up @@ -113,6 +115,13 @@ private static void generateTuscanSquare(int n) {
}
}

private static void generateOne() {
int[][] t = {
{ 0, 0 }
};
r = t;
}

private static void generateThree() {
int[][] t = {
{ 0, 1, 2, 0 },
Expand Down
142 changes: 142 additions & 0 deletions idflakies-core/src/test/java/edu/illinois/TuscanIntraClassTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package edu.illinois;

import java.util.*;

import org.junit.Test;
import org.junit.Assert;

import edu.illinois.cs.dt.tools.detection.TestShuffler;
import edu.illinois.cs.dt.tools.detection.detectors.TuscanIntraClassDetector;

public class TuscanIntraClassTest {
@Test
public void test() throws Exception {
String[] testArray = {
"cn.edu.hfut.dmic.webcollector.util.CharsetDetectorTest.testGuessEncodingByMozilla",
"cn.edu.hfut.dmic.webcollector.util.CharsetDetectorTest.testGuessEncoding",
"cn.edu.hfut.dmic.webcollector.util.CrawlDatumTest.testKey",
"cn.edu.hfut.dmic.webcollector.util.DBManagerTest.testBerkeleyDBInjector",
"cn.edu.hfut.dmic.webcollector.util.DBManagerTest.testRocksDBInjector",
"cn.edu.hfut.dmic.webcollector.util.CrawlDatumsTest.testAdd",
"cn.edu.hfut.dmic.webcollector.util.CrawlDatumsTest.testAddAndReturn",
"cn.edu.hfut.dmic.webcollector.util.MetaTest.testMetaSetterAndGetter",
"cn.edu.hfut.dmic.webcollector.util.OkHttpRequesterTest.testHttpCode"
};
List<String> tests = Arrays.asList(testArray);
TestShuffler testShuffler = new TestShuffler("", 0, tests, null);
HashMap<String, List<String>> classToMethods = generateClassToMethods(tests);

int maxMethodSize = TuscanIntraClassDetector.findMaxMethodSize(classToMethods);
if (maxMethodSize == 3 || maxMethodSize == 5) {
maxMethodSize++;
}
int rounds;
int classSize = classToMethods.keySet().size();
if (classSize == 3 || classSize == 5) {
classSize++;
}
if (classSize > maxMethodSize) {
rounds = classSize;
} else {
rounds = maxMethodSize;
}

// Each List inside a set is basically a pair
Set<List<String>> allClassPairs = generateAllPairs(tests, false);
Set<List<String>> tuscanCoveredClassPairs = tuscanClassPairs(rounds, tests, testShuffler);

Assert.assertEquals(allClassPairs, tuscanCoveredClassPairs);

Set<List<String>> allMethodPairs = generateAllPairs(tests, true);
Set<List<String>> tuscanCoveredMethodPairs = tuscanMethodPairs(rounds, tests, testShuffler);

Assert.assertEquals(allMethodPairs, tuscanCoveredMethodPairs);
}

public static HashMap<String, List<String>> generateClassToMethods(List<String> tests) {
HashMap<String, List<String>> classToMethods = new HashMap<>();
for (final String test : tests) {
final String className = TestShuffler.className(test);
if (!classToMethods.containsKey(className)) {
classToMethods.put(className, new ArrayList<>());
}
classToMethods.get(className).add(test);
}
return classToMethods;
}

public static Set<List<String>> generateAllPairs(List<String> tests) {
Set<List<String>> allPairs = new LinkedHashSet<List<String>>();
for (int i = 0; i < tests.size(); i++) {
for (int j = 0; j < tests.size(); j++) {
if (!tests.get(i).equals(tests.get(j))) {
List<String> newPair = new ArrayList<String>();
newPair.add(tests.get(i));
newPair.add(tests.get(j));
allPairs.add(newPair);
}
}
}
return allPairs;
}

private static Set<List<String>> generateAllPairs(List<String> tests, boolean isMethods) {
// Generates all pairs with a naive algorithm for comparison with tuscan-intra-class method
Set<List<String>> allPairs = new LinkedHashSet<List<String>>();
for (int i = 0; i < tests.size(); i++) {
for (int j = 0; j < tests.size(); j++) {
String className1 = TestShuffler.className(tests.get(i));
String className2 = TestShuffler.className(tests.get(j));
List<String> newPair = new ArrayList<String>();
if (!isMethods && !className1.equals(className2)) {
newPair.add(className1);
newPair.add(className2);
allPairs.add(newPair);
} else if (isMethods && className1.equals(className2) && !tests.get(i).equals(tests.get(j))) {
newPair.add(tests.get(i));
newPair.add(tests.get(j));
allPairs.add(newPair);
}
}
}
return allPairs;
}

private static Set<List<String>> tuscanClassPairs(int rounds, List<String> tests, TestShuffler testShuffler) {
// Generates the class pairs using tuscan-intra-class algorithm
Set<List<String>> visitedClassPairs = new LinkedHashSet<List<String>>();
for (int i = 0; i < rounds; i++) {
List<String> currentOrder = testShuffler.tuscanIntraClassOrder(i);
for (int j = 0; j < currentOrder.size() - 1; j++) {
String className1 = TestShuffler.className(currentOrder.get(j));
String className2 = TestShuffler.className(currentOrder.get(j + 1));
List<String> newPair = new ArrayList<String>();
if (!className1.equals(className2)) {
newPair.add(className1);
newPair.add(className2);
visitedClassPairs.add(newPair);
}
}
}
return visitedClassPairs;
}

private static Set<List<String>> tuscanMethodPairs(int rounds, List<String> tests, TestShuffler testShuffler) {
// Generates the intra-class method pairs using tuscan-intra-class algorithm
Set<List<String>> visitedMethodPairs = new LinkedHashSet<List<String>>();
for (int i = 0; i < rounds; i++) {
List<String> currentOrder = testShuffler.tuscanIntraClassOrder(i);
for (int j = 0; j < currentOrder.size() - 1; j++) {
String class1 = TestShuffler.className(currentOrder.get(j));
String class2 = TestShuffler.className(currentOrder.get(j + 1));
if (class1.equals(class2)) {
List<String> newPair = new ArrayList<String>();
newPair.add(currentOrder.get(j));
newPair.add(currentOrder.get(j + 1));
visitedMethodPairs.add(newPair);
}
}
}
return visitedMethodPairs;
}
}
Loading