ThreadWeaver always throws IllegalArgumentException

437 Views Asked by At

I am trying to use Google ThreadWeaver to write a unit test for concurrent code. No matter what I do, I will get an IllegalArgumentException. I am still working with an example, but even that does not work. This is what I tried:

public class ExampleTest {
  public static class ExampleMain implements MainRunnable<Example> {
    private Example example;
    @Override
    public Class<Example> getClassUnderTest() {
      return Example.class;
    }
    @Override
    public String getMethodName() {
      return null;
    }
    @Override
    public Method getMethod() throws NoSuchMethodException {
      return null;
    }
    @Override
    public void initialize() throws Exception {
      example = new Example();
    }
    @Override
    public Example getMainObject() {
      return example;
    }
    @Override
    public void terminate() throws Exception {
    }

    @Override
    public void run() throws Exception {
      example.test("second");
    }
  }

  public static class ExampleSecondary implements SecondaryRunnable<Example, ExampleMain> {

  private ExampleMain exampleMain;

  @Override
  public void initialize(ExampleMain main) throws Exception {
    exampleMain = main;
  }

  @Override
  public void terminate() throws Exception {
  }

  @Override
  public boolean canBlock() {
    return false;
  }

  @Override
  public void run() throws Exception {
    exampleMain.getMainObject().test("main");
  }
}

public static class Example {
  private List<String> list = new ArrayList<String>();
  public String test(String s) {
    System.out.println("1" + s);
    list.add(s);
    System.out.println("2" + s);
    return list.get(0);
  }
}

@Test
public void testThreadWeaver() throws Exception {
  ClassInstrumentation instrumentation = Instrumentation.getClassInstrumentation(Example.class);
  Method tested = Example.class.getDeclaredMethod("test", String.class);
  Method breakpoint = List.class.getDeclaredMethod("add", Object.class);
  CodePosition codePosition = instrumentation.afterCall(tested, breakpoint);
  InterleavedRunner.interleave(new ExampleMain(), new ExampleSecondary(), Arrays.asList(codePosition)).throwExceptionsIfAny();
}

}

The stack trace says:

java.lang.IllegalArgumentException: Class Example is not instrumented at com.google.testing.threadtester.CallLoggerFactory.getClassInstrumentation(CallLoggerFactory.java:108) at com.google.testing.threadtester.Instrumentation.getClassInstrumentation(Instrumentation.java:65) at MyTest.testThreadWeaver(MyTest.java:92

I followed the instructions at the official Google code webpage, but it does not seem to work. Any ideas?

1

There are 1 best solutions below

0
On BEST ANSWER

ThreadWeaver needs to instrument your classes in order to add breakpoints to your methods. Therefore, you cannot run the tests with JUnit directly but you must run your test from a specific test runner. For your case this would be ThreadedTestRunner. The actual test methods must then be annotated with @ThreadedTest instead of @Test. This should work:

@Test
public void startTest() throws Exception {
    new ThreadedTestRunner().runTests(getClass(), Example.class);
}

@ThreadedTest
public void testThreadWeaver() throws Exception {
  // here comes your test
}