Skip to content

Commit

Permalink
add krakatau for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
radioegor146 committed Feb 7, 2024
1 parent ff353f4 commit 008c03e
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 74 deletions.
12 changes: 12 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,17 @@ jobs:
os:
- os: ubuntu-latest
compiler_install_command: sudo apt install g++ cmake
krakatau_install_command: sudo cp ./target/release/krak2 /usr/local/bin/
cc: gcc
cxx: g++
- os: macos-latest
compiler_install_command: brew install cmake
krakatau_install_command: cp ./target/release/krak2 /usr/local/bin/
cc: clang
cxx: clang++
- os: windows-latest
compiler_install_command: choco install cmake
krakatau_install_command: copy ./target/release/krak2.exe C:/Windows
prebuild_script: '"C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Auxiliary/Build/vcvars64.bat"'
cc: cl
cxx: cl
Expand All @@ -28,6 +31,15 @@ jobs:
with:
java-version: ${{ matrix.java }}
distribution: temurin
- name: Install Rust toolchain for Krakatau
uses: dtolnay/rust-toolchain@stable
- name: Build Krakatau
run: |
git clone https://github.com/Storyyeller/Krakatau.git
cd Krakatau
cargo build --release
- name: Install Krakatau
run: ${{ matrix.os.krakatau_install_command }}
- name: Install C++ dependencies
run: ${{ matrix.os.compiler_install_command }}
- name: Build with Gradle
Expand Down
54 changes: 32 additions & 22 deletions obfuscator/src/test/java/by/radioegor146/ClassicTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class ClassicTest implements Executable {

private final Path testData;
private Path temp;
private final String testName;
private final boolean useKrakatau;

ClassicTest(Path path, String testName) {
ClassicTest(Path path, String testName, boolean useKrakatau) {
testData = path;
this.testName = testName;
this.useKrakatau = useKrakatau;
}

private void clean() {
Expand All @@ -50,18 +50,24 @@ public void execute() throws Throwable {
temp = Files.createTempDirectory(String.format("native-obfuscator-test-%s-", testData.toFile().getName()));

Path tempSource = temp.resolve("source");
Path tempKrakatauSource = temp.resolve("source-krakatau");
Path tempClasses = temp.resolve("classes");
Files.createDirectories(tempSource);
Files.createDirectories(tempKrakatauSource);
Files.createDirectories(tempClasses);

Path idealJar = temp.resolve("test.jar");

List<Path> javaFiles = new ArrayList<>();
List<Path> krakatauFiles = new ArrayList<>();
List<Path> resourceFiles = new ArrayList<>();
Files.find(testData, 10, (path, attr) -> true)
.filter(p -> Files.isRegularFile(p) && p.toString().endsWith(".java"))
.forEach(javaFiles::add);
Files.find(testData, 10, (path, attr) -> attr.isDirectory() || !path.toString().endsWith(".java"))
Files.find(testData, 10, (path, attr) -> true)
.filter(p -> Files.isRegularFile(p) && p.toString().endsWith(".j"))
.forEach(krakatauFiles::add);
Files.find(testData, 10, (path, attr) -> attr.isDirectory() || (!path.toString().endsWith(".java") && !path.toString().endsWith(".j")))
.filter(Files::isRegularFile)
.forEach(resourceFiles::add);

Expand All @@ -74,11 +80,12 @@ public void execute() throws Throwable {

if (!mainClassOptional.isPresent()) {
System.out.println("Can't find main class");
return;
throw new RuntimeException("Main class not found");
}

javaFiles.forEach(unchecked(p -> Files.copy(p, tempSource.resolve(p.getFileName()))));
resourceFiles.forEach(unchecked(p -> {
javaFiles.forEach(uncheckedConsumer(p -> Files.copy(p, tempSource.resolve(p.getFileName()))));
krakatauFiles.forEach(uncheckedConsumer(p -> Files.copy(p, tempKrakatauSource.resolve(p.getFileName()))));
resourceFiles.forEach(uncheckedConsumer(p -> {
Path target = temp.resolve(testData.relativize(p));
Files.createDirectories(target.getParent());
Files.copy(p, target);
Expand All @@ -92,6 +99,17 @@ public void execute() throws Throwable {
ProcessHelper.run(temp, 10_000, javacParameters)
.check("Compilation");

if (useKrakatau) {
System.out.println("Compiling Krakatau...");
krakatauFiles.stream().forEach(uncheckedConsumer(path -> {
List<String> krakatauParameters = new ArrayList<>(Arrays.asList("krak2", "asm", "--out",
tempClasses.resolve(testData.relativize(path)).toString().replaceAll("\\.j$", ".class"),
path.toString()));
ProcessHelper.run(temp, 1_000, krakatauParameters)
.check("Krakatau compilation");
}));
}

List<String> jarParameters = new ArrayList<>(Arrays.asList(
"jar", "cvfe", idealJar.toString(), mainClassOptional.get(),
"-C", tempClasses + File.separator, "."));
Expand Down Expand Up @@ -141,7 +159,7 @@ public void execute() throws Throwable {


Files.find(tempCpp.resolve("build").resolve("lib"), 1, (path, args) -> Files.isRegularFile(path))
.forEach(unchecked(p -> Files.copy(p, tempOutput.resolve(p.getFileName()))));
.forEach(uncheckedConsumer(p -> Files.copy(p, tempOutput.resolve(p.getFileName()))));

System.out.println("Running test...");

Expand All @@ -157,21 +175,13 @@ public void execute() throws Throwable {
testRunResult.check("Test run");

if (!testRunResult.stdout.equals(idealRunResult.stdout)) {
// Some tests are random based
Pattern testResult = Pattern.compile("^Passed = \\d+,? failed = (\\d+)$", Pattern.MULTILINE);
Matcher matcher = testResult.matcher(testRunResult.stdout);
if (matcher.find()) {
if (!matcher.group(1).equals("0")) {
fail(testRunResult, idealRunResult);
}
} else {
fail(testRunResult, idealRunResult);
}
fail(testRunResult, idealRunResult);
}

System.out.println("OK");
}
// clean();

clean();
} catch (IOException | RuntimeException e) {
e.printStackTrace(System.err);
throw e;
Expand All @@ -186,17 +196,17 @@ private void fail(ProcessResult testRun, ProcessResult ideaRun) {
throw new RuntimeException("Ideal != Test");
}

private <T> Predicate<T> uncheckedPredicate(UncheckedPredicate<T> consumer) {
private <T> Predicate<T> uncheckedPredicate(UncheckedPredicate<T> predicate) {
return value -> {
try {
return consumer.test(value);
return predicate.test(value);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
}

private <T> Consumer<T> unchecked(UncheckedConsumer<T> consumer) {
private <T> Consumer<T> uncheckedConsumer(UncheckedConsumer<T> consumer) {
return value -> {
try {
consumer.accept(value);
Expand Down

This file was deleted.

18 changes: 17 additions & 1 deletion obfuscator/src/test/java/by/radioegor146/TestsGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,27 @@ public Stream<DynamicTest> generateTests() throws URISyntaxException, IOExceptio
URL tests = TestsGenerator.class.getClassLoader().getResource("tests");
Objects.requireNonNull(tests, "No tests dir in resources");

boolean useKrakatau;

try {
Process process = new ProcessBuilder().command("krak2", "-V").start();
process.waitFor();
if (process.exitValue() != 0) {
throw new RuntimeException("krak2 -V failed");
}
useKrakatau = true;
} catch (Exception e) {
System.err.println("No Krakatau2 found (krak2), so tests with it will fail");
useKrakatau = false;
}

boolean finalUseKrakatau = useKrakatau;

Path testDir = Paths.get(tests.toURI());
return Files.walk(testDir, FileVisitOption.FOLLOW_LINKS).filter(Files::isDirectory)
.filter(TestsGenerator::hasJavaFiles).filter(TestsGenerator::testAllowed)
.map(p -> DynamicTest.dynamicTest(testDir.relativize(p).toString(),
new ClassicTest(p, testDir.relativize(p).toString())));
new ClassicTest(p, testDir.relativize(p).toString(), finalUseKrakatau)));
}

private static boolean hasJavaFiles(Path path) {
Expand Down
11 changes: 11 additions & 0 deletions obfuscator/test_data/tests/pull-requests/PullRequest72/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
public class Main {
public static void main(String[] args) throws Exception {
try {
Class.forName("java.lang.invoke.StringConcatFactory");
} catch (Exception e) {
System.out.println("No java/lang/invoke/StringConcatFactory found, probably Java 1.8 or older");
return;
}
Class.forName("TestStringConcatFactory").getMethod("test").invoke(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.version 55 0
.class public super TestStringConcatFactory
.super java/lang/Object

.method public static test : ()V
.code stack 4 locals 1
L0: getstatic Field java/lang/System out Ljava/io/PrintStream;
L3: iconst_1
L4: iconst_2
L5: iconst_3
L6: invokedynamic [_28]
L11: invokevirtual Method java/io/PrintStream println (Ljava/lang/String;)V
L14: return
L15:
.end code
.end method
.bootstrapmethods
.const [_28] = InvokeDynamic invokeStatic Method java/lang/invoke/StringConcatFactory makeConcatWithConstants (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite; String "\u0001-\u0001-\u0001-\u0002-\u0002-\u0002" Double 3.14e0 Int 123 Int 1 : makeConcatWithConstants (III)Ljava/lang/String;
.end class

0 comments on commit 008c03e

Please sign in to comment.