-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compile and overwrite test #175
Merged
Merged
Changes from 7 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
17784d3
Refactored TestingDummyHelper to it and SourceTestClassWrapper
judovana c6919b1
Moved shared logic from CliTest.java to AbstractAgentNeedingTest.java
judovana 7a63bcd
Made checkstyle happy
judovana 4442dde
Added checks about modifed/same stdout of running test class
judovana a78837d
Added tests for compilation
judovana ff68b6a
Added test to test api
judovana 1b5c069
Made GitHub Ci run all tests matching *CliTest
AurumTheEnd 7861716
Introduced a 10 minute timeout into CI "Test Cli" step
AurumTheEnd 931cdf8
At least in CompileUploadCliTest removed missuse of global variables …
judovana 799b770
listjvms, listplugins, api now can use saveaas
judovana 8202359
Plugin dependent tests are now ignored if given plugin is not configured
judovana 7f2058d
Merge branch 'comileAndOverwriteTest' of github.com:pmikova/java-runt…
judovana fdbdcf5
Removed duplicated code in CompileUploadCliTest
judovana d78e0aa
Changed decompileJavaP tests to not fail due to stream buffer filling…
AurumTheEnd 9ec2f10
Made GitHub CI CliTests show what's being skipped
AurumTheEnd 036a98b
Fixed CliTest of first plugin in list not running
AurumTheEnd File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
223 changes: 223 additions & 0 deletions
223
runtime-decompiler/src/test/java/org/jrd/backend/data/AbstractAgentNeedingTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
package org.jrd.backend.data; | ||
|
||
import org.jrd.backend.core.AgentRequestAction; | ||
import org.jrd.frontend.frame.main.DecompilationController; | ||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Assumptions; | ||
import org.junit.jupiter.api.BeforeAll; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Timeout; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.io.File; | ||
import java.io.FileInputStream; | ||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.io.PrintStream; | ||
import java.nio.charset.Charset; | ||
import java.nio.charset.CharsetDecoder; | ||
import java.nio.charset.CodingErrorAction; | ||
import java.nio.charset.StandardCharsets; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
public abstract class AbstractAgentNeedingTest { | ||
|
||
protected Model model; | ||
protected AbstractSourceTestClass dummy; | ||
protected final JunitStderrOutThief streams = new JunitStderrOutThief(); | ||
|
||
abstract AbstractSourceTestClass dummyProvider() throws AbstractSourceTestClass.SourceTestClassWrapperException; | ||
|
||
@BeforeAll | ||
static void startup() { | ||
String agentPath = Config.getConfig().getAgentExpandedPath(); | ||
|
||
Assumptions.assumeTrue( | ||
!agentPath.isEmpty(), | ||
"Agent path is not set up, aborting CliTest." | ||
); | ||
Assumptions.assumeTrue( | ||
new File(agentPath).exists(), | ||
"Agent path is set up to nonexistent file, aborting CliTest." | ||
); | ||
} | ||
|
||
@Timeout(5) | ||
@BeforeEach | ||
void setup() throws InterruptedException { | ||
try { | ||
dummy = dummyProvider(); | ||
} catch (AbstractSourceTestClass.SourceTestClassWrapperException e) { | ||
Assertions.fail(e); | ||
} | ||
Assertions.assertTrue(dummy.isAlive()); | ||
|
||
model = new Model(); // must be below dummy process execution to be aware of it during VmManager instantiation | ||
while (model.getVmManager().findVmFromPidNoException(dummy.getPid()) == null) { | ||
Thread.sleep(100); | ||
model.getVmManager().updateLocalVMs(); | ||
} | ||
|
||
streams.captureStreams(true); | ||
} | ||
|
||
@AfterEach | ||
void cleanup() { | ||
streams.captureStreams(false); | ||
|
||
Assertions.assertTrue(dummy.isAlive()); | ||
// halt agent, otherwise an open socket prevents termination of dummy process | ||
AgentRequestAction request = DecompilationController.createRequest( | ||
model.getVmManager().findVmFromPid(dummy.getPid()), AgentRequestAction.RequestAction.HALT, "" | ||
); | ||
String response = DecompilationController.submitRequest(model.getVmManager(), request); | ||
Assertions.assertEquals("ok", response); | ||
|
||
Assertions.assertTrue(dummy.isAlive()); | ||
dummy.terminate(); | ||
} | ||
|
||
private static boolean isDifferenceTolerable(double samenessPercentage, int actualChanges, int totalSize) { | ||
assert samenessPercentage >= 0 && samenessPercentage <= 1.0; | ||
|
||
double changesAllowed = (1.0 - samenessPercentage) * totalSize; | ||
return actualChanges <= changesAllowed; | ||
} | ||
|
||
static void assertEqualsWithTolerance(String s1, String s2, double samenessPercentage) { | ||
Assertions.assertTrue(isDifferenceTolerable( | ||
samenessPercentage, | ||
LevenshteinDistance.calculate(s1, s2), | ||
Math.max(s1.length(), s2.length()) | ||
)); | ||
} | ||
|
||
static void assertEqualsWithTolerance(List<String> l1, List<String> l2, double samenessPercentage) { | ||
// symmetric difference | ||
Set<String> intersection = new HashSet<>(l1); | ||
intersection.retainAll(l2); | ||
|
||
Set<String> difference = new HashSet<>(); | ||
difference.addAll(l1); | ||
difference.addAll(l2); | ||
difference.removeAll(intersection); | ||
|
||
Assertions.assertTrue(isDifferenceTolerable(samenessPercentage, difference.size(), Math.max(l1.size(), l2.size()))); | ||
} | ||
|
||
public static final class LevenshteinDistance { | ||
/** | ||
* Calculates the Levenshtein distance between two strings.<br/> | ||
* Uses a 2D array to represent individual changes, therefore the time complexity is quadratic | ||
* (in reference to the strings' length). | ||
* | ||
* @param str1 the first string | ||
* @param str2 the second string | ||
* @return an integer representing the amount of atomic changes between {@code str1} and {@code str2} | ||
*/ | ||
public static int calculate(String str1, String str2) { | ||
int[][] matrix = new int[str1.length() + 1][str2.length() + 1]; | ||
|
||
for (int i = 0; i <= str1.length(); i++) { | ||
for (int j = 0; j <= str2.length(); j++) { | ||
if (i == 0) { // distance between "" and str2 == how long str2 is | ||
matrix[i][j] = j; | ||
} else if (j == 0) { // distance between str1 and "" == how long str1 is | ||
matrix[i][j] = i; | ||
} else { | ||
int substitution = matrix[i - 1][j - 1] + | ||
substitutionCost(str1.charAt(i - 1), str2.charAt(j - 1)); | ||
int insertion = matrix[i][j - 1] + 1; | ||
int deletion = matrix[i - 1][j] + 1; | ||
|
||
matrix[i][j] = min3(substitution, insertion, deletion); | ||
} | ||
} | ||
} | ||
|
||
return matrix[str1.length()][str2.length()]; // result is in the bottom-right corner | ||
} | ||
|
||
private static int substitutionCost(char a, char b) { | ||
return (a == b) ? 0 : 1; | ||
} | ||
|
||
private static int min3(int a, int b, int c) { | ||
return Math.min(a, Math.min(b, c)); | ||
} | ||
} | ||
|
||
|
||
public static class JunitStderrOutThief { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do not understand this renaming. |
||
private final ByteArrayOutputStream out; | ||
private final ByteArrayOutputStream err; | ||
|
||
private final PrintStream originalOut; | ||
private final PrintStream originalErr; | ||
|
||
JunitStderrOutThief() { | ||
out = new ByteArrayOutputStream(); | ||
err = new ByteArrayOutputStream(); | ||
originalOut = System.out; | ||
originalErr = System.err; | ||
} | ||
|
||
public void captureStreams(boolean capture) { | ||
if (capture) { | ||
out.reset(); | ||
err.reset(); | ||
} | ||
|
||
System.setOut(capture ? new PrintStream(out, true, StandardCharsets.UTF_8) : originalOut); | ||
System.setErr(capture ? new PrintStream(err, true, StandardCharsets.UTF_8) : originalErr); | ||
} | ||
|
||
private String get(ByteArrayOutputStream which) { | ||
String string = which.toString(StandardCharsets.UTF_8); | ||
which.reset(); | ||
|
||
return string; | ||
} | ||
|
||
public String getOut() { | ||
return get(out); | ||
} | ||
|
||
public byte[] getOutBytes() { | ||
byte[] bytes = out.toByteArray(); | ||
out.reset(); | ||
|
||
return bytes; | ||
} | ||
|
||
public String getErr() { | ||
return get(err); | ||
} | ||
} | ||
|
||
|
||
public static String readBinaryAsString(File f) throws IOException { | ||
try (FileInputStream fis = new FileInputStream(f)) { | ||
return readBinaryAsString(fis, "UTF-8", CodingErrorAction.REPLACE); | ||
} | ||
} | ||
|
||
public static String readBinaryAsString(FileInputStream input, String charBase, CodingErrorAction action) throws IOException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unused parameter |
||
CharsetDecoder decoder = Charset.forName(charBase).newDecoder(); | ||
decoder.onMalformedInput(CodingErrorAction.IGNORE); | ||
InputStreamReader reader = new InputStreamReader(input, decoder); | ||
StringBuilder sb = new StringBuilder(); | ||
while (true) { | ||
int i = reader.read(); | ||
if (i < 0) { | ||
break; | ||
} | ||
sb.append((char) i); | ||
} | ||
reader.close(); | ||
return sb.toString(); | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why there is this condition at all? Test all!
Also the -DfailIfNoTests=false seems wrong. lets fail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ook. thanx