0

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?

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192

1 Answers1

2

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
}
Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192