diff --git a/.github/workflows/buildPeass.yml b/.github/workflows/buildPeass.yml index 380c7a3b6..e323157d4 100644 --- a/.github/workflows/buildPeass.yml +++ b/.github/workflows/buildPeass.yml @@ -28,7 +28,7 @@ jobs: mvn -version fi shell: bash - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Install git-crypt run: | if [ "$RUNNER_OS" == "Linux" ]; then diff --git a/analysis/pom.xml b/analysis/pom.xml index 5046b2159..3d0e384eb 100644 --- a/analysis/pom.xml +++ b/analysis/pom.xml @@ -39,6 +39,11 @@ + + io.github.terahidro2003 + sfsw + 0.2.0 + org.hamcrest hamcrest @@ -49,6 +54,12 @@ de.dagere.peass measurement ${project.version} + + + sfsw + io.github.terahidro2003 + + de.dagere.peass diff --git a/analysis/src/main/java/de/dagere/peass/analysis/guessing/GuessDecider.java b/analysis/src/main/java/de/dagere/peass/analysis/guessing/GuessDecider.java index 9a39dfa83..7d951dede 100644 --- a/analysis/src/main/java/de/dagere/peass/analysis/guessing/GuessDecider.java +++ b/analysis/src/main/java/de/dagere/peass/analysis/guessing/GuessDecider.java @@ -8,9 +8,10 @@ import org.apache.commons.io.FileUtils; -import difflib.Delta; -import difflib.DiffUtils; -import difflib.Patch; +import com.github.difflib.DiffUtils; +import com.github.difflib.patch.AbstractDelta; +import com.github.difflib.patch.Patch; + public class GuessDecider { @@ -40,7 +41,7 @@ public Guess guess(Set methods) throws IOException { Patch patch = getDiff(method); for (Guesser guesser : Guesser.allGuessers) { - for (Delta delta : patch.getDeltas()) { + for (AbstractDelta delta : patch.getDeltas()) { if (guesser.isGuessTrue(delta)) { currentGuess.add(guesser); } diff --git a/analysis/src/main/java/de/dagere/peass/analysis/guessing/Guesser.java b/analysis/src/main/java/de/dagere/peass/analysis/guessing/Guesser.java index eb09ca187..961df16b4 100644 --- a/analysis/src/main/java/de/dagere/peass/analysis/guessing/Guesser.java +++ b/analysis/src/main/java/de/dagere/peass/analysis/guessing/Guesser.java @@ -3,8 +3,9 @@ import java.util.LinkedList; import java.util.List; +import com.github.difflib.patch.AbstractDelta; + import de.dagere.peass.analysis.guessing.GuessDecider.ConditionChecker; -import difflib.Delta; public class Guesser { @@ -60,12 +61,12 @@ public class Guesser { this.direction = direction; } - boolean isGuessTrue(Delta delta) { + boolean isGuessTrue(AbstractDelta delta) { boolean fullfills = false; - if (check(delta.getOriginal().getLines(), checker) && check(delta.getRevised().getLines(), checkerOld)) { + if (check(delta.getSource().getLines(), checker) && check(delta.getTarget().getLines(), checkerOld)) { fullfills = true; } - if (check(delta.getOriginal().getLines(), checkerOld) && check(delta.getRevised().getLines(), checker)) { + if (check(delta.getSource().getLines(), checkerOld) && check(delta.getTarget().getLines(), checker)) { fullfills = true; } return fullfills; diff --git a/analysis/src/main/java/de/dagere/peass/analysis/guessing/OneSideGuesser.java b/analysis/src/main/java/de/dagere/peass/analysis/guessing/OneSideGuesser.java index 3d3939ad6..18810895c 100644 --- a/analysis/src/main/java/de/dagere/peass/analysis/guessing/OneSideGuesser.java +++ b/analysis/src/main/java/de/dagere/peass/analysis/guessing/OneSideGuesser.java @@ -2,8 +2,9 @@ import java.util.List; +import com.github.difflib.patch.AbstractDelta; + import de.dagere.peass.analysis.guessing.GuessDecider.ConditionChecker; -import difflib.Delta; class OneSideGuesser extends Guesser { @@ -12,9 +13,9 @@ class OneSideGuesser extends Guesser { } @Override - boolean isGuessTrue(Delta delta) { - List lines = delta.getRevised().getLines(); - List lines2 = delta.getOriginal().getLines(); + boolean isGuessTrue(AbstractDelta delta) { + List lines = delta.getTarget().getLines(); + List lines2 = delta.getSource().getLines(); if (lines2.size() < lines.size()) { return testOneSideCondition(checker, lines, lines2); } else if (lines2.size() > lines.size()) { diff --git a/analysis/src/main/java/de/dagere/peass/analysis/properties/PropertyChangeGuesser.java b/analysis/src/main/java/de/dagere/peass/analysis/properties/PropertyChangeGuesser.java index af01936b6..7f8972fa9 100644 --- a/analysis/src/main/java/de/dagere/peass/analysis/properties/PropertyChangeGuesser.java +++ b/analysis/src/main/java/de/dagere/peass/analysis/properties/PropertyChangeGuesser.java @@ -9,6 +9,9 @@ import java.util.Map.Entry; import java.util.Set; +import com.github.difflib.DiffUtils; +import com.github.difflib.patch.AbstractDelta; +import com.github.difflib.patch.Patch; import com.github.javaparser.ast.CompilationUnit; import de.dagere.nodeDiffDetector.data.MethodCall; @@ -20,9 +23,6 @@ import de.dagere.nodeDiffDetector.utils.JavaParserProvider; import de.dagere.peass.config.ExecutionConfig; import de.dagere.peass.folders.PeassFolders; -import difflib.Delta; -import difflib.DiffUtils; -import difflib.Patch; public class PropertyChangeGuesser { @@ -45,9 +45,9 @@ public Set getGuesses(final PeassFolders folders, final Entry changedLinesMethod = DiffUtils.diff(Arrays.asList(sourceOld.split("\n")), Arrays.asList(source.split("\n"))); - for (final Delta delta : changedLinesMethod.getDeltas()) { - getDeltaGuess(guessedTypes, (delta.getOriginal().getLines())); - getDeltaGuess(guessedTypes, (delta.getRevised().getLines())); + for (final AbstractDelta delta : changedLinesMethod.getDeltas()) { + getDeltaGuess(guessedTypes, (delta.getSource().getLines())); + getDeltaGuess(guessedTypes, (delta.getTarget().getLines())); } } } diff --git a/dependency/pom.xml b/dependency/pom.xml index 7cbafe38b..154be8e68 100644 --- a/dependency/pom.xml +++ b/dependency/pom.xml @@ -181,16 +181,10 @@ test - - com.googlecode.java-diff-utils - diffutils - 1.3.0 - - org.apache.groovy groovy-astbuilder - 4.0.15 + 4.0.22 diff --git a/dependency/src/main/java/de/dagere/peass/analysis/properties/MethodChangeReader.java b/dependency/src/main/java/de/dagere/peass/analysis/properties/MethodChangeReader.java index f008af760..2fd9efbb6 100644 --- a/dependency/src/main/java/de/dagere/peass/analysis/properties/MethodChangeReader.java +++ b/dependency/src/main/java/de/dagere/peass/analysis/properties/MethodChangeReader.java @@ -8,13 +8,14 @@ import org.apache.commons.io.FileUtils; +import com.github.difflib.DiffUtils; +import com.github.difflib.patch.Patch; + import de.dagere.nodeDiffDetector.data.MethodCall; import de.dagere.nodeDiffDetector.diffDetection.FileComparisonUtil; import de.dagere.nodeDiffDetector.sourceReading.MethodReader; import de.dagere.peass.config.ExecutionConfig; import de.dagere.peass.dependency.traces.diff.DiffUtilJava; -import difflib.DiffUtils; -import difflib.Patch; public class MethodChangeReader { diff --git a/dependency/src/main/java/de/dagere/peass/analysis/properties/PropertyReadHelper.java b/dependency/src/main/java/de/dagere/peass/analysis/properties/PropertyReadHelper.java index eed1a639a..74a155543 100644 --- a/dependency/src/main/java/de/dagere/peass/analysis/properties/PropertyReadHelper.java +++ b/dependency/src/main/java/de/dagere/peass/analysis/properties/PropertyReadHelper.java @@ -16,6 +16,11 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.github.difflib.DiffUtils; +import com.github.difflib.patch.AbstractDelta; +import com.github.difflib.patch.DeltaType; +import com.github.difflib.patch.Patch; + import de.dagere.nodeDiffDetector.data.MethodCall; import de.dagere.nodeDiffDetector.data.Type; import de.dagere.nodeDiffDetector.diffDetection.ClazzChangeData; @@ -40,10 +45,6 @@ import de.dagere.peass.vcs.CommitIteratorGit; import de.dagere.peass.vcs.GitUtils; import de.dagere.requitur.Sequitur; -import difflib.Delta; -import difflib.Delta.TYPE; -import difflib.DiffUtils; -import difflib.Patch; public class PropertyReadHelper { @@ -263,11 +264,11 @@ public void getKeywordChanges(final ChangeProperty property, final MethodChangeR final Map vNewkeywords = new HashMap<>(); final Map vOldkeywords = new HashMap<>(); - for (final Delta changeSet : patch.getDeltas()) { - for (final String line : changeSet.getOriginal().getLines()) { + for (final AbstractDelta changeSet : patch.getDeltas()) { + for (final String line : changeSet.getSource().getLines()) { getKeywordCount(vOldkeywords, line); } - for (final String line : changeSet.getRevised().getLines()) { + for (final String line : changeSet.getTarget().getLines()) { getKeywordCount(vNewkeywords, line); } } @@ -357,12 +358,12 @@ public static void determineTraceSizeChanges(final ChangeProperty property, fina LOG.debug(patch); int added = 0, removed = 0; - for (final Delta delta : patch.getDeltas()) { - if (delta.getType().equals(TYPE.DELETE)) { + for (final AbstractDelta delta : patch.getDeltas()) { + if (delta.getType().equals(DeltaType.DELETE)) { removed++; - } else if (delta.getType().equals(TYPE.INSERT)) { + } else if (delta.getType().equals(DeltaType.INSERT)) { added++; - } else if (delta.getType().equals(TYPE.CHANGE)) { + } else if (delta.getType().equals(DeltaType.CHANGE)) { added++; removed++; } diff --git a/dependency/src/main/java/de/dagere/peass/dependency/ChangeManager.java b/dependency/src/main/java/de/dagere/peass/dependency/ChangeManager.java index 34908fb81..c805a3e21 100644 --- a/dependency/src/main/java/de/dagere/peass/dependency/ChangeManager.java +++ b/dependency/src/main/java/de/dagere/peass/dependency/ChangeManager.java @@ -4,7 +4,6 @@ import java.io.FileFilter; import java.io.FileNotFoundException; import java.io.IOException; -import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -14,20 +13,15 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import de.dagere.nodeDiffDetector.data.MethodCall; import de.dagere.nodeDiffDetector.data.Type; import de.dagere.nodeDiffDetector.diffDetection.ChangeDetector; import de.dagere.nodeDiffDetector.diffDetection.ClazzChangeData; -import de.dagere.nodeDiffDetector.diffDetection.FileComparisonUtil; -import de.dagere.nodeDiffDetector.sourceReading.MethodReader; import de.dagere.peass.config.ExecutionConfig; import de.dagere.peass.dependency.analysis.data.CommitDiff; import de.dagere.peass.execution.utils.TestExecutor; import de.dagere.peass.folders.PeassFolders; import de.dagere.peass.vcs.CommitIterator; import de.dagere.peass.vcs.GitUtils; -import difflib.DiffUtils; -import difflib.Patch; /** * Determines whether a file has a change, and whether this change is class-wide or only affecting a method. diff --git a/dependency/src/main/java/de/dagere/peass/dependency/KiekerResultManager.java b/dependency/src/main/java/de/dagere/peass/dependency/KiekerResultManager.java index eee0c9487..2ed278f10 100644 --- a/dependency/src/main/java/de/dagere/peass/dependency/KiekerResultManager.java +++ b/dependency/src/main/java/de/dagere/peass/dependency/KiekerResultManager.java @@ -122,7 +122,7 @@ public void executeKoPeMeKiekerRun(final TestSet testsToUpdate, final String com executor.prepareKoPeMeExecution(new File(commitLogFolder, "clean.txt")); for (final TestMethodCall testcase : testsToUpdate.getTestMethods()) { - executor.executeTest(testcase, commitLogFolder, testTransformer.getConfig().getTimeoutInSeconds()); + executor.executeTest(testcase, commitLogFolder, testTransformer.getConfig().getTimeoutInSeconds(), ""); } LOG.debug("KoPeMe-Kieker-Run finished"); } diff --git a/dependency/src/main/java/de/dagere/peass/dependency/reader/twiceExecution/TwiceExecutableChecker.java b/dependency/src/main/java/de/dagere/peass/dependency/reader/twiceExecution/TwiceExecutableChecker.java index e484c9610..aa0534d6a 100644 --- a/dependency/src/main/java/de/dagere/peass/dependency/reader/twiceExecution/TwiceExecutableChecker.java +++ b/dependency/src/main/java/de/dagere/peass/dependency/reader/twiceExecution/TwiceExecutableChecker.java @@ -43,7 +43,7 @@ public void checkTwiceExecution(String commit, String predecessor, Set3.14.0 - - org.jgrapht @@ -110,6 +108,12 @@ ${mockito.version} test + + io.github.terahidro2003 + sjsw + 0.1.0 + compile + diff --git a/measurement/src/main/java/de/dagere/peass/SearchCauseStarter.java b/measurement/src/main/java/de/dagere/peass/SearchCauseStarter.java index f05c4c883..f9a08001a 100644 --- a/measurement/src/main/java/de/dagere/peass/SearchCauseStarter.java +++ b/measurement/src/main/java/de/dagere/peass/SearchCauseStarter.java @@ -25,7 +25,9 @@ import de.dagere.peass.measurement.rca.kieker.BothTreeReader; import de.dagere.peass.measurement.rca.searcher.CauseSearcher; import de.dagere.peass.measurement.rca.searcher.CauseSearcherComplete; +import de.dagere.peass.measurement.rca.searcher.ICauseSearcher; import de.dagere.peass.measurement.rca.searcher.LevelCauseSearcher; +import de.dagere.peass.measurement.rca.searcher.SamplingCauseSearcher; import de.dagere.peass.measurement.rca.searcher.TreeAnalyzerCreator; import net.kieker.sourceinstrumentation.AllowedKiekerRecord; import picocli.CommandLine; @@ -92,7 +94,7 @@ public Void call() throws Exception { new EnvironmentVariables(measurementConfiguration.getExecutionConfig().getProperties())); CommitComparatorInstance comparator = new CommitComparatorInstance(staticTestSelection); - final CauseSearcher tester = getCauseSeacher(measurementConfiguration, causeSearcherConfig, alternateFolders, reader, comparator); + final ICauseSearcher tester = getCauseSeacher(measurementConfiguration, causeSearcherConfig, alternateFolders, reader, comparator); tester.search(); return null; @@ -139,7 +141,7 @@ private MeasurementConfig getConfiguration(final String predecessor) { return measurementConfiguration; } - public static CauseSearcher getCauseSeacher(final MeasurementConfig measurementConfiguration, + public static ICauseSearcher getCauseSeacher(final MeasurementConfig measurementConfiguration, final CauseSearcherConfig causeSearcherConfig, final CauseSearchFolders alternateFolders, final BothTreeReader reader, CommitComparatorInstance comparator) throws IOException, InterruptedException { if (measurementConfiguration.getKiekerConfig().isOnlyOneCallRecording()) { @@ -150,7 +152,7 @@ public static CauseSearcher getCauseSeacher(final MeasurementConfig measurementC } EnvironmentVariables env = reader.getEnv(); - final CauseSearcher tester; + final ICauseSearcher tester; final CauseTester measurer = new CauseTester(alternateFolders, measurementConfiguration, causeSearcherConfig, env, comparator); if (causeSearcherConfig.getRcaStrategy() != null) { switch (causeSearcherConfig.getRcaStrategy()) { @@ -186,6 +188,9 @@ public TreeAnalyzer getAnalyzer(final BothTreeReader reader, final CauseSearcher }; tester = new CauseSearcherComplete(reader, causeSearcherConfig, measurer, measurementConfiguration, alternateFolders, creator, env); break; + case SAMPLING: + tester = new SamplingCauseSearcher(causeSearcherConfig.getTestCase(), measurementConfiguration, alternateFolders, env); + break; default: throw new RuntimeException("Strategy " + causeSearcherConfig.getRcaStrategy() + " not expected"); } diff --git a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/AbstractMeasurementProcessRunner.java b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/AbstractMeasurementProcessRunner.java new file mode 100644 index 000000000..d4c0250a0 --- /dev/null +++ b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/AbstractMeasurementProcessRunner.java @@ -0,0 +1,68 @@ +package de.dagere.peass.measurement.dependencyprocessors; + +import java.io.File; +import java.io.IOException; + +import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import de.dagere.nodeDiffDetector.data.TestMethodCall; +import de.dagere.peass.folders.PeassFolders; +import de.dagere.peass.vcs.GitUtils; +import de.dagere.peass.vcs.VersionControlSystem; + +public abstract class AbstractMeasurementProcessRunner { + private static final Logger LOG = LogManager.getLogger(AbstractMeasurementProcessRunner.class); + + protected final VersionControlSystem vcs; + protected final PeassFolders folders; + + public AbstractMeasurementProcessRunner(PeassFolders folders) { + this.folders = folders; + this.vcs = folders.getVCS(); + } + + public abstract void runOnce(final TestMethodCall testcase, final String commit, final int vmid, final File logFolder, final File projectFolder); + + protected void initCommit(final String commit) { + if (vcs.equals(VersionControlSystem.SVN)) { + throw new RuntimeException("SVN not supported currently."); + } else { + GitUtils.goToCommit(commit, folders.getProjectFolder()); + } + } + + protected File initVMFolder(final String commit, final int vmid, final File logFolder) { + File vmidFolder = new File(logFolder, "vm_" + vmid + "_" + commit); + vmidFolder.mkdirs(); + + LOG.info("Initial checkout finished, VM-Folder " + vmidFolder.getAbsolutePath() + " exists: " + vmidFolder.exists()); + return vmidFolder; + } + + void cleanup() { + emptyFolder(folders.getTempDir()); + emptyFolder(folders.getKiekerTempFolder()); + System.gc(); + try { + Thread.sleep(1); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + private void emptyFolder(final File tempDir) { + for (final File createdTempFile : tempDir.listFiles()) { + try { + if (createdTempFile.isDirectory()) { + FileUtils.deleteDirectory(createdTempFile); + } else { + createdTempFile.delete(); + } + } catch (final IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/DependencyTester.java b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/DependencyTester.java index fbb419d47..287a0b949 100644 --- a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/DependencyTester.java +++ b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/DependencyTester.java @@ -188,7 +188,7 @@ public void runSequential(final File logFolder, final TestMethodCall testcase, f private void runOnce(final TestMethodCall testcase, final String commit, final int vmid, final File logFolder) { final TestExecutor testExecutor = getExecutor(folders, commit); final OnceRunner runner = new OnceRunner(folders, testExecutor, getCurrentOrganizer(), this); - runner.runOnce(testcase, commit, vmid, logFolder); + runner.runOnce(testcase, commit, vmid, logFolder, folders.getProjectFolder()); } protected synchronized TestExecutor getExecutor(final PeassFolders currentFolders, final String commit) { diff --git a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/OnceRunner.java b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/OnceRunner.java index d59046e2b..40261500d 100644 --- a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/OnceRunner.java +++ b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/OnceRunner.java @@ -15,12 +15,10 @@ import de.dagere.peass.vcs.GitUtils; import de.dagere.peass.vcs.VersionControlSystem; -public class OnceRunner { +public class OnceRunner extends AbstractMeasurementProcessRunner { private static final Logger LOG = LogManager.getLogger(OnceRunner.class); - protected final PeassFolders folders; - private final VersionControlSystem vcs; protected final TestTransformer testTransformer; protected final TestExecutor testExecutor; @@ -28,8 +26,7 @@ public class OnceRunner { private final KiekerResultHandler resultHandler; public OnceRunner(final PeassFolders folders, final TestExecutor testExecutor, final ResultOrganizer currentOrganizer, final KiekerResultHandler resultHandler) { - this.folders = folders; - this.vcs = folders.getVCS(); + super(folders); this.testTransformer = testExecutor.getTestTransformer(); this.testExecutor = testExecutor; this.currentOrganizer = currentOrganizer; @@ -42,12 +39,8 @@ public OnceRunner(final PeassFolders folders, final TestExecutor testExecutor, f } } - public void runOnce(final TestMethodCall testcase, final String commit, final int vmid, final File logFolder) { - if (vcs.equals(VersionControlSystem.SVN)) { - throw new RuntimeException("SVN not supported currently."); - } else { - GitUtils.goToCommit(commit, folders.getProjectFolder()); - } + public void runOnce(final TestMethodCall testcase, final String commit, final int vmid, final File logFolder, final File projectFolderToIgnore) { + initCommit(commit); final File vmidFolder = initVMFolder(commit, vmid, logFolder); @@ -56,7 +49,7 @@ public void runOnce(final TestMethodCall testcase, final String commit, final in } testExecutor.prepareKoPeMeExecution(new File(logFolder, "clean.txt")); final long outerTimeout = 10 + (int) (this.testTransformer.getConfig().getTimeoutInSeconds() * 1.2); - testExecutor.executeTest(testcase, vmidFolder, outerTimeout); + testExecutor.executeTest(testcase, vmidFolder, outerTimeout, ""); if (testTransformer.getConfig().isDirectlyMeasureKieker()) { DirectKiekerMeasurementTransformer measurementTransformer = new DirectKiekerMeasurementTransformer(folders); @@ -72,40 +65,7 @@ public void runOnce(final TestMethodCall testcase, final String commit, final in cleanup(); } - private File initVMFolder(final String commit, final int vmid, final File logFolder) { - File vmidFolder = new File(logFolder, "vm_" + vmid + "_" + commit); - vmidFolder.mkdirs(); - - LOG.info("Initial checkout finished, VM-Folder " + vmidFolder.getAbsolutePath() + " exists: " + vmidFolder.exists()); - return vmidFolder; - } - - void cleanup() { - emptyFolder(folders.getTempDir()); - emptyFolder(folders.getKiekerTempFolder()); - System.gc(); - try { - Thread.sleep(1); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - public ResultOrganizer getCurrentOrganizer() { return currentOrganizer; } - - private void emptyFolder(final File tempDir) { - for (final File createdTempFile : tempDir.listFiles()) { - try { - if (createdTempFile.isDirectory()) { - FileUtils.deleteDirectory(createdTempFile); - } else { - createdTempFile.delete(); - } - } catch (final IOException e) { - e.printStackTrace(); - } - } - } } diff --git a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/ParallelExecutionRunnable.java b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/ParallelExecutionRunnable.java index 3845a957a..05e6569d0 100644 --- a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/ParallelExecutionRunnable.java +++ b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/ParallelExecutionRunnable.java @@ -33,7 +33,7 @@ public ParallelExecutionRunnable(final ResultOrganizerParallel organizer, final public void run() { final TestExecutor testExecutor = tester.getExecutor(temporaryFolders, commit); final OnceRunner runner = new OnceRunner(temporaryFolders, testExecutor, organizer, tester); - runner.runOnce(testcase, commit, vmid, logFolder); + runner.runOnce(testcase, commit, vmid, logFolder, logFolder); } private PeassFolders cloneProjectFolder(final String gitCryptKey) throws IOException { diff --git a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/SamplingRunner.java b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/SamplingRunner.java new file mode 100644 index 000000000..14a4bb9cc --- /dev/null +++ b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/SamplingRunner.java @@ -0,0 +1,118 @@ +package de.dagere.peass.measurement.dependencyprocessors; + +import java.io.File; +import java.io.IOException; +import java.time.Duration; + +import de.dagere.peass.measurement.rca.data.CallTreeNode; +import io.github.terahidro2003.config.Config; +import io.github.terahidro2003.result.SamplerResultsProcessor; +import io.github.terahidro2003.samplers.SamplerExecutorPipeline; +import io.github.terahidro2003.samplers.asyncprofiler.AsyncProfilerExecutor; +import io.github.terahidro2003.samplers.asyncprofiler.MeasurementInformation; +import org.apache.commons.io.FileUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import de.dagere.nodeDiffDetector.data.TestMethodCall; +import de.dagere.peass.execution.utils.TestExecutor; +import de.dagere.peass.folders.PeassFolders; +import de.dagere.peass.measurement.organize.ResultOrganizer; +import de.dagere.peass.measurement.rca.searcher.ICauseSearcher; +import de.dagere.peass.testtransformation.TestTransformer; + +public class SamplingRunner extends AbstractMeasurementProcessRunner { + private static final Logger LOG = LogManager.getLogger(OnceRunner.class); + + protected final TestTransformer testTransformer; + protected final TestExecutor testExecutor; + + protected final ResultOrganizer currentOrganizer; + private final ICauseSearcher resultHandler; + + public SamplingRunner(final PeassFolders folders, final TestExecutor testExecutor, final ResultOrganizer currentOrganizer, final ICauseSearcher resultHandler) { + super(folders); + this.testTransformer = testExecutor.getTestTransformer(); + this.testExecutor = testExecutor; + this.currentOrganizer = currentOrganizer; + this.resultHandler = resultHandler; + + try { + FileUtils.cleanDirectory(folders.getTempDir()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @Override + public void runOnce(TestMethodCall testcase, String commit, int vmid, File logFolder, File projectFolder) { + initCommit(commit); + + final File vmidFolder = initVMFolder(commit, vmid, logFolder); + + testExecutor.prepareKoPeMeExecution(new File(logFolder, "clean.txt")); + + final long outerTimeout = 10 + (int) (this.testTransformer.getConfig().getTimeoutInSeconds() * 1.2); + + try { + /* + CONFIGURATION + + Most properties should be null, as SJSW executor itself won't be used + (i.e., SJSW won't attach async-profiler's Java agent by itself) + profilerPath is intentionally left null as SJSW it this case should download, extract and locate + async-profiler's executable. + */ + Config config = new Config( + null, + null, + null, + vmidFolder.getAbsolutePath() + "/sjsw-results", + true, + 100 + ); + + /* + DURATION (TIMEOUT) + + Sampling duration is the equivalent to the timeout of the test. + Sampling continues until either the test terminates by itself, or after the sampling duration. + */ + Duration duration = Duration.ofSeconds(outerTimeout); + + /* + JAVA AGENT RETRIEVAL + + Retrieves java agent as string to be attached to the maven lifecycle + */ + SamplerExecutorPipeline pipeline = new AsyncProfilerExecutor(); + MeasurementInformation agent = pipeline.javaAgent(config, duration); + + /* + EXECUTION + + Executes the test with maven executor (sampling should be done as asprof agent is passed to the + MavenExecutor). + + It should skip the instrumentation, assuming that useKieker = false + */ + testExecutor.executeTest(testcase, logFolder, outerTimeout, agent.javaAgentPath()); + + SamplerResultsProcessor processor = new SamplerResultsProcessor(); + var parsedJFR = processor.extractSamplesFromJFR(new File(agent.rawOutputPath()), config); + + // CallTreeNode requires two commits that are not provided here + // where to provide oldCommit hash???? + // If everything works, then root should represent sampling results from a single commit + CallTreeNode root = processor.convertResultsToPeassTree(parsedJFR, commit, commit); + System.out.println(root); + } catch (IOException e) { + throw new RuntimeException(e); + } + + LOG.info("Organizing result paths"); + currentOrganizer.saveResultFiles(commit, vmid); + + cleanup(); + } +} diff --git a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/helper/ProgressWriter.java b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/helper/ProgressWriter.java index 2b58218b3..62bdc50d4 100644 --- a/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/helper/ProgressWriter.java +++ b/measurement/src/main/java/de/dagere/peass/measurement/dependencyprocessors/helper/ProgressWriter.java @@ -11,8 +11,12 @@ public class ProgressWriter implements AutoCloseable { private final SummaryStatistics durationStatistics = new SummaryStatistics(); private final int vms; - public ProgressWriter(final File resultFile, final int vms) throws FileNotFoundException { - progressFileWriter = new PrintWriter(resultFile); + public ProgressWriter(final File resultFile, final int vms) { + try { + progressFileWriter = new PrintWriter(resultFile); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } this.vms = vms; } diff --git a/measurement/src/main/java/de/dagere/peass/measurement/rca/RCAStrategy.java b/measurement/src/main/java/de/dagere/peass/measurement/rca/RCAStrategy.java index e9e05a44a..e06a840b4 100644 --- a/measurement/src/main/java/de/dagere/peass/measurement/rca/RCAStrategy.java +++ b/measurement/src/main/java/de/dagere/peass/measurement/rca/RCAStrategy.java @@ -20,5 +20,9 @@ public enum RCAStrategy { /** * Searches for root causes by analyzing all nodes on the path to a changed source code, implemented by {@link SourceChangeTreeAnalyzer} */ - UNTIL_SOURCE_CHANGE + UNTIL_SOURCE_CHANGE, + /** + * Read the whole tree using sampling + */ + SAMPLING } diff --git a/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/CauseSearcher.java b/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/CauseSearcher.java index dbd5d4ce7..19bad9743 100644 --- a/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/CauseSearcher.java +++ b/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/CauseSearcher.java @@ -21,7 +21,7 @@ import de.dagere.peass.measurement.rca.kieker.BothTreeReader; import de.dagere.peass.measurement.rca.treeanalysis.AllDifferingDeterminer; -public abstract class CauseSearcher { +public abstract class CauseSearcher implements ICauseSearcher { private static final Logger LOG = LogManager.getLogger(CauseSearcher.class); diff --git a/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/ICauseSearcher.java b/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/ICauseSearcher.java new file mode 100644 index 000000000..4ac3c7e18 --- /dev/null +++ b/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/ICauseSearcher.java @@ -0,0 +1,9 @@ +package de.dagere.peass.measurement.rca.searcher; + +import java.util.Set; + +import de.dagere.nodeDiffDetector.data.MethodCall; + +public interface ICauseSearcher { + public Set search(); +} diff --git a/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/SamplingCauseSearcher.java b/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/SamplingCauseSearcher.java new file mode 100644 index 000000000..573e35688 --- /dev/null +++ b/measurement/src/main/java/de/dagere/peass/measurement/rca/searcher/SamplingCauseSearcher.java @@ -0,0 +1,132 @@ +package de.dagere.peass.measurement.rca.searcher; + +import java.io.File; +import java.util.Set; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import de.dagere.nodeDiffDetector.data.MethodCall; +import de.dagere.nodeDiffDetector.data.TestMethodCall; +import de.dagere.peass.config.FixedCommitConfig; +import de.dagere.peass.config.MeasurementConfig; +import de.dagere.peass.config.MeasurementStrategy; +import de.dagere.peass.dependency.ExecutorCreator; +import de.dagere.peass.execution.processutils.ProcessBuilderHelper; +import de.dagere.peass.execution.utils.EnvironmentVariables; +import de.dagere.peass.execution.utils.TestExecutor; +import de.dagere.peass.folders.PeassFolders; +import de.dagere.peass.measurement.dependencyprocessors.SamplingRunner; +import de.dagere.peass.measurement.dependencyprocessors.helper.ProgressWriter; +import de.dagere.peass.measurement.organize.FolderDeterminer; +import de.dagere.peass.measurement.organize.ResultOrganizer; +import de.dagere.peass.testtransformation.TestTransformer; + +public class SamplingCauseSearcher implements ICauseSearcher { + + private static final Logger LOG = LogManager.getLogger(SamplingCauseSearcher.class); + + private final TestMethodCall testcase; + protected final MeasurementConfig configuration; + protected final PeassFolders folders; + private ResultOrganizer currentOrganizer; + protected final EnvironmentVariables env; + + protected long currentChunkStart = 0; + + public SamplingCauseSearcher(TestMethodCall testcase, MeasurementConfig configuration, PeassFolders folders, EnvironmentVariables env) { + this.testcase = testcase; + this.configuration = configuration; + this.folders = folders; + this.env = env; + } + + @Override + public Set search() { + FixedCommitConfig fixedCommitConfig = configuration.getFixedCommitConfig(); + LOG.info("Executing test " + testcase.getClazz() + " " + testcase.getMethod() + " in commits {} and {}", fixedCommitConfig.getCommitOld(), + fixedCommitConfig.getCommit()); + new FolderDeterminer(folders).testResultFolders(fixedCommitConfig.getCommit(), fixedCommitConfig.getCommitOld(), testcase); + + final File logFolder = folders.getMeasureLogFolder(configuration.getFixedCommitConfig().getCommit(), testcase); + try (ProgressWriter writer = new ProgressWriter(folders.getProgressFile(), configuration.getVms())) { + evaluateSimple(testcase, logFolder, writer); + } + + throw new RuntimeException("Not implemented yet"); + } + + private void evaluateSimple(TestMethodCall testcase2, File logFolder, ProgressWriter writer) { + currentChunkStart = System.currentTimeMillis(); + for (int finishedVMs = 0; finishedVMs < configuration.getVms(); finishedVMs++) { + long comparisonStart = System.currentTimeMillis(); + + runOneComparison(logFolder, testcase, finishedVMs); + + long durationInSeconds = (System.currentTimeMillis() - comparisonStart) / 1000; + writer.write(durationInSeconds, finishedVMs); + + betweenVMCooldown(); + } + } + + public void runOneComparison(final File logFolder, final TestMethodCall testcase, final int vmid) { + String[] commits = getVersions(); + + if (configuration.getMeasurementStrategy().equals(MeasurementStrategy.SEQUENTIAL)) { + LOG.info("Running sequential"); + runSequential(logFolder, testcase, vmid, commits); + } else if (configuration.getMeasurementStrategy().equals(MeasurementStrategy.PARALLEL)) { + LOG.info("Running parallel"); + runParallel(logFolder, testcase, vmid, commits); + } + } + + private void runParallel(File logFolder, TestMethodCall testcase2, int vmid, String[] commits) { + throw new RuntimeException("Not implemented yet"); + } + + private void runSequential(File logFolder, TestMethodCall testcase2, int vmid, String[] commits) { + currentOrganizer = new ResultOrganizer(folders, configuration.getFixedCommitConfig().getCommit(), currentChunkStart, configuration.getKiekerConfig().isUseKieker(), + configuration.isSaveAll(), + testcase, configuration.getAllIterations()); + for (String commit : commits) { + runOnce(testcase, commit, vmid, logFolder, folders.getProjectFolder()); + } + } + + private void runOnce(final TestMethodCall testcase, final String commit, final int vmid, final File logFolder, File projectFolder) { + final TestExecutor testExecutor = getExecutor(folders, commit); + final SamplingRunner runner = new SamplingRunner(folders, testExecutor, getCurrentOrganizer(), this); + runner.runOnce(testcase, commit, vmid, logFolder, projectFolder); + } + + protected synchronized TestExecutor getExecutor(final PeassFolders currentFolders, final String commit) { + TestTransformer transformer = ExecutorCreator.createTestTransformer(currentFolders, configuration.getExecutionConfig(), configuration); + final TestExecutor testExecutor = ExecutorCreator.createExecutor(currentFolders, transformer, env); + return testExecutor; + } + + protected void betweenVMCooldown() { + if (configuration.isCallSyncBetweenVMs()) { + ProcessBuilderHelper.syncToHdd(); + } + try { + Thread.sleep(configuration.getWaitTimeBetweenVMs()); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + public ResultOrganizer getCurrentOrganizer() { + return currentOrganizer; + } + + private String[] getVersions() { + String commits[] = new String[2]; + commits[0] = configuration.getFixedCommitConfig().getCommitOld().equals("HEAD~1") ? configuration.getFixedCommitConfig().getCommit() + "~1" + : configuration.getFixedCommitConfig().getCommitOld(); + commits[1] = configuration.getFixedCommitConfig().getCommit(); + return commits; + } +} diff --git a/measurement/src/test/java/de/dagere/peass/measurement/kieker/DirectKiekerExecutionIT.java b/measurement/src/test/java/de/dagere/peass/measurement/kieker/DirectKiekerExecutionIT.java index 6a6f876ec..9a563a801 100644 --- a/measurement/src/test/java/de/dagere/peass/measurement/kieker/DirectKiekerExecutionIT.java +++ b/measurement/src/test/java/de/dagere/peass/measurement/kieker/DirectKiekerExecutionIT.java @@ -70,7 +70,9 @@ private void runOnce(JUnitTestTransformer testTransformer, PeassFolders folders, testTransformer.determineVersions(Arrays.asList(new File[] { DependencyTestConstants.CURRENT })); testTransformer.transformTests(); - runner.runOnce(new TestMethodCall("defaultpackage.TestMe", "testMe"), "123456", 0, folders.getMeasureLogFolder()); + runner.runOnce(new TestMethodCall("defaultpackage.TestMe", "testMe"), "123456", 0, folders.getMeasureLogFolder(), File.createTempFile("tmps", "d")); + } catch (IOException e) { + throw new RuntimeException(e); } } } diff --git a/measurement/src/test/java/de/dagere/peass/measurement/rca/CauseSearcherIT.java b/measurement/src/test/java/de/dagere/peass/measurement/rca/CauseSearcherIT.java index 01abea0d7..e852fdc43 100644 --- a/measurement/src/test/java/de/dagere/peass/measurement/rca/CauseSearcherIT.java +++ b/measurement/src/test/java/de/dagere/peass/measurement/rca/CauseSearcherIT.java @@ -9,7 +9,6 @@ import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.hamcrest.MatcherAssert; import org.hamcrest.Matchers; import org.junit.Assert; @@ -33,7 +32,6 @@ import de.dagere.peass.measurement.rca.searcher.CauseSearcherComplete; import de.dagere.peass.vcs.GitUtils; import de.dagere.peass.vcs.VersionControlSystem; -import kieker.analysis.exception.AnalysisConfigurationException; public class CauseSearcherIT { @@ -62,7 +60,7 @@ public void setUp() throws InterruptedException, IOException { @Test public void testSlowerState() - throws InterruptedException, IOException, IllegalStateException, XmlPullParserException, AnalysisConfigurationException { + throws InterruptedException, IOException, IllegalStateException { try (MockedStatic mockedVCS = Mockito.mockStatic(VersionControlSystem.class); MockedStatic mockedGitUtils = Mockito.mockStatic(GitUtils.class)) { mockEnvironment(mockedVCS, mockedGitUtils); diff --git a/pom.xml b/pom.xml index fae1baf9b..3c4aab918 100644 --- a/pom.xml +++ b/pom.xml @@ -56,7 +56,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 3.6.3 + 3.7.0 none true @@ -108,7 +108,7 @@ org.apache.maven.plugins maven-source-plugin - 3.3.0 + 3.3.1 org.codehaus.mojo @@ -123,17 +123,17 @@ org.apache.maven.plugins maven-jar-plugin - 3.3.0 + 3.4.2 org.apache.maven.plugins maven-failsafe-plugin - 3.2.2 + 3.3.0 org.apache.maven.plugins maven-surefire-plugin - 3.2.2 + 3.3.0