Unit testing concurrent code
-
Upload
rafael-winterhalter -
Category
Software
-
view
353 -
download
2
description
Transcript of Unit testing concurrent code
Unit testingconcurrent code
public class FlawedList<T> extends ArrayList<T> { public boolean putIfAbsent(T object) { boolean absent = !super.contains(object); if (absent) { super.add(object); } return absent; }}
Implementing a broken unique list
@Testpublic void testPutIfAbsent() { FlawedList<String> list = new FlawedList<String>(); list.putIfAbsent("foo"); list.putIfAbsent("foo"); assertThat(list.size(), is(1)); }
JUnit
FlawedList<String> list = new FlawedList<String>();
@Test(threadPoolSize = 5, invocationCount = 20) public void testList() { list.putIfAbsent("foo"); assertThat(list.size(), is(1)); }
TestNG
TestNG with breakpoints
public class FlawedList<T> extends ArrayList<T> { public boolean putIfAbsent(T object) { boolean absent = !super.contains(object); if (absent) { super.add(object); } return absent; }}
FlawedList<String> list = new FlawedList<String>();
@Test(threadPoolSize = 5, invocationCount = 20) public void testList() { list.putIfAbsent("foo"); assertThat(list.size(), is(1)); }
public boolean putIfAbsent(T object) { boolean absent = !super.contains(object); if (absent) { super.add(object); } return absent; }
Testing with break points: first weaving
FlawedList["foo", "foo"]FlawedList["foo"]FlawedList[]
Testing with break points: second weaving
Thread 1Thread 2
Legend:
ThreadWeaver
absent
true
falsetrue
public class WeavedFlawedListTest { private FlawedList<String> list;
@ThreadedBefore public void before() { list = new FlawedList<String>(); }
@ThreadedMain public void mainThread() { list.putIfAbsent("foo"); } @ThreadedSecondary public void secondThread() { list.putIfAbsent("foo"); }
@ThreadedAfter public void after() { assertEquals(1, list.size()); } }
ThreadWeaver (https://code.google.com/p/thread-weaver)
Seamless JUnit integration
public class MyListTest {
@Test public void testFlawedList() { AnnotatedTestRunner runner = new AnnotatedTestRunner(); runner.runTests(getClass(), FlawedList.class); }
// put method with @Threaded<...> annotations here}
@Test public void testFlawedList() { AnnotatedTestRunner runner = new AnnotatedTestRunner(); runner.runTests(getClass(), FlawedList.class); }
How does it work?
Instrumented code:
public boolean putIfAbsent(T object) { Framework.considerBreakpoint(Thread.currentThread(), 0); boolean absent = !super.contains(object); Framework.considerBreakpoint(Thread.currentThread(), 1); if (absent) { Framework.considerBreakpoint(Thread.currentThread(), 2); super.add(object); } Framework.considerBreakpoint(Thread.currentThread(), 3); return absent; }
http://rafael.codes@rafaelcodes
http://www.kantega.nohttp://blogg.kantega.no
http://bytebuddy.nethttps://github.com/raphw/byte-buddy