Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 15 additions & 9 deletions core/src/main/kotlin/org/pastalab/fray/core/command/Executor.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.pastalab.fray.core.command

import java.lang.reflect.InvocationTargetException
import java.net.URI
import java.net.URLClassLoader
import kotlinx.serialization.SerialName
Expand Down Expand Up @@ -37,17 +38,22 @@ data class MethodExecutor(

override fun execute() {
val clazz = Class.forName(clazz, true, Thread.currentThread().contextClassLoader)
if (args.isEmpty() && method != "main") {
val m = clazz.getMethod(method)
if (m.modifiers and java.lang.reflect.Modifier.STATIC == 0) {
val obj = clazz.getConstructor().newInstance()
m.invoke(obj)
try {

if (args.isEmpty() && method != "main") {
val m = clazz.getMethod(method)
if (m.modifiers and java.lang.reflect.Modifier.STATIC == 0) {
val obj = clazz.getConstructor().newInstance()
m.invoke(obj)
} else {
m.invoke(null)
}
} else {
m.invoke(null)
val m = clazz.getMethod(method, Array<String>::class.java)
m.invoke(null, args.toTypedArray())
}
} else {
val m = clazz.getMethod(method, Array<String>::class.java)
m.invoke(null, args.toTypedArray())
} catch (e: InvocationTargetException) {
throw e.targetException
}
}

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class ApplicationCodeTransformer : ClassFileTransformer {
) ||
(dotClassName.startsWith("org.pastalab.fray") &&
!dotClassName.startsWith("org.pastalab.fray.benchmark") &&
!dotClassName.startsWith("org.pastalab.fray.test") &&
!dotClassName.startsWith(
"org.pastalab.fray.core.test",
))) {
Expand Down
33 changes: 33 additions & 0 deletions integration-test/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
plugins {
id("java")
}

group = "org.pastalab.fray.test"
version = "0.1.4-SNAPSHOT"

repositories {
mavenCentral()
}

dependencies {
testImplementation(platform("org.junit:junit-bom:5.10.0"))
testImplementation("org.junit.jupiter:junit-jupiter")
testImplementation(project(":core"))
testImplementation("io.github.classgraph:classgraph:4.8.177")
testCompileOnly(project(":runtime"))
}

tasks.test {
useJUnitPlatform()
val jvmti = project(":jvmti")
val jdk = project(":instrumentation:jdk")
val agent = project(":instrumentation:agent")
executable("${jdk.layout.buildDirectory.get().asFile}/java-inst/bin/java")
jvmArgs("-agentpath:${jvmti.layout.buildDirectory.get().asFile}/native-libs/libjvmti.so")
jvmArgs("-javaagent:${agent.layout.buildDirectory.get().asFile}/libs/" +
"${agent.name}-${agent.version}-shadow.jar")
jvmArgs("-Dfray.debug=true")
dependsOn(":instrumentation:jdk:build")
dependsOn(":instrumentation:agent:build")
dependsOn(":jvmti:build")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.pastalab.fray.test;

public class ExpectedException extends RuntimeException {
public ExpectedException() {
}

public ExpectedException(String message) {
super(message);
}

public ExpectedException(String message, Throwable cause) {
super(message, cause);
}

public ExpectedException(Throwable cause) {
super(cause);
}

public ExpectedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.pastalab.fray.test.fail.wait;

import org.pastalab.fray.test.ExpectedException;

import java.util.concurrent.atomic.AtomicInteger;

public class IntStream {
public static void main(String[] args) {
AtomicInteger x = new AtomicInteger();
java.util.stream.IntStream.range(1, 10).parallel().forEach((i) -> x.compareAndSet(i-1, i+1));
if (x.get() != 10) {
throw new ExpectedException("x (" + x.get() + ") is not 10");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.pastalab.fray.test.fail.wait;

import org.pastalab.fray.test.ExpectedException;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

public class NotifyOrder {
public static void notifyOrder() throws InterruptedException {
Object o = new Object();
CountDownLatch latch = new CountDownLatch(2);
AtomicBoolean flag = new AtomicBoolean(false);
AtomicBoolean notifyFlag = new AtomicBoolean(false);
AtomicBoolean bugFound = new AtomicBoolean(false);
Thread t1 = new Thread(() -> {
synchronized (o) {
try {
latch.countDown();
while (!notifyFlag.get()) {
o.wait();
}
flag.set(true);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
Thread t2 = new Thread(() -> {
synchronized (o) {
try {
latch.countDown();
while (!notifyFlag.get()) {
o.wait();
}
if (!flag.get()) {
bugFound.set(true);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
});
t1.start();
t2.start();
latch.await();
synchronized (o) {
notifyFlag.set(true);
o.notifyAll();
}
t1.join();
t2.join();
if (bugFound.get()) {
throw new ExpectedException("notify order bug found");
}
}

public static void main(String[] args) throws InterruptedException {
notifyOrder();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package org.pastalab.fray.test.fail.wait;

import org.pastalab.fray.test.ExpectedException;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

public class WaitSpuriousWakeup {
public static void main(String[] args) {
Object o = new Object();
CountDownLatch latch = new CountDownLatch(1);
AtomicBoolean flag = new AtomicBoolean(false);
Thread t = new Thread(() -> {
synchronized (o) {
try {
latch.countDown();
o.wait();
flag.set(true);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});

t.start();
try {
latch.await(); // Wait for the thread to start
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
synchronized (o) {
// Flag can be set before notify is called due to spurious wake up
if (flag.get()) {
throw new ExpectedException("Spurious wakeup bug found");
}
o.notify();
}
}
}
Loading