Hi all,
Still working on the Express and Custom runners for the Terracotta extension to
jUnit.
Some unexpected work came on top, and, despite what I had expected, this turns
out to be much more plumbing than I innocently had expected!
Yet the main bits are in placed and Standalone are functional as of now. Looks
like I need to fix some concurrency issue with junit itself still so that the
reporting doesn't get confused every now and then... but you can write and run
tests.
To do so, one would need to annotate his class with the
@RunWith(TerracottaRunner.class) annotation.
This is currently the most simple way of running a TC backed up test. It will
by default involve 2 participants and (once I'm have them properly functioning)
run in Custom, Express and Standalone mode.
A class can additionally be annotated with :
- @TerracottaTest
To define the TargetEnvironment the test needs to be run in & the amount of
participants:
@TerracottaTest(participants = 1, value =
TerracottaTest.TargetEnvironment.STANDALONE)
- @TerracottaServerConfig
To define some l2 properties when run in clustered:
@TerracottaServerConfig(hostname = "localhost", dsoPort = 5678, adminPort
= 5679)
More will probably be added as need arises.
At the field level, you can inject the ClusteringToolkit used by annotation the
proper typed field with @Inject
In standalone, a Dummy implementation is inject that should mimic clustered
behavior.
Now at the method level, I introduced an (hopefully soon renamed) additional 2
annotations:
@BeforeAll
@AfterAll
These static methods will be executed once for the cluster (like if you need to
start a DB instance or something)
This can store references in static fields, but these won't be available in
other methods (as these will be executed on their l1).
@BeforeClass
@AfterClass
Will be executed once for every participant. In standalone, classloader
isolation is mimicking multiple l1
The @Before, @After, @Test annotations work just as with the regular junit
runner. (Still wondering about @Ignore, which afaik can't be time bombed)
Not all methods from the latest refactorings on ClusteringToolkit are currently
implemented for Standalone mode. Mainly ClusterInfo is currently missing...
Here is a test from the org.terracotta.test:junit-runner:1.0.0-SNAPSHOT
available as forge project in svn,
that I hope should explain it all much better:
@RunWith(TerracottaRunner.class)
public static class SuccessfulRunTest {
private static final String OUTER_COUNTER = "outerCounter";
private static final String INNER_COUNTER = "innerCounter";
private static final AtomicInteger classInvokes = new AtomicInteger(0);
private static final AtomicInteger aroundInvokes = new AtomicInteger(0);
private static final AtomicInteger invokes = new AtomicInteger(0);
private static Object someValue;
private Object localValue;
@Inject
private static volatile ClusteringToolkit clusteringToolkit;
@Inject
private volatile ClusteringToolkit localClusteringToolkit;
private volatile Barrier barrier;
@BeforeAll
public static void once() {
assertThat(clusteringToolkit, notNullValue());
ClusteredMap<String, Integer> map = clusteringToolkit.getMap("counters");
if (map.putIfAbsent(OUTER_COUNTER, 1) != null) {
for (Integer old = map.get(OUTER_COUNTER); !map.replace(OUTER_COUNTER,
old, ++old); old = map.get(OUTER_COUNTER))
;
}
someValue = new Object();
assertThat(clusteringToolkit.getMap("counters").get(OUTER_COUNTER),
notNullValue());
}
@BeforeClass
public static void preSetup() {
classInvokes.getAndIncrement();
verify(1, 0, 0);
assertThat(someValue, nullValue());
}
@Before
public void setup() {
assertThat(localClusteringToolkit, sameInstance(clusteringToolkit));
barrier = localClusteringToolkit.getBarrier("barrier", 2);
aroundInvokes.getAndIncrement();
assertThat(someValue, nullValue());
}
@Test
public void testNothing() throws Exception {
assertThat(clusteringToolkit.getMap("counters").get(OUTER_COUNTER),
notNullValue());
barrier.await();
assertThat(localClusteringToolkit, sameInstance(clusteringToolkit));
assertThat(invokes.incrementAndGet(), equalTo(1));
localValue = new Object();
assertThat(someValue, nullValue());
}
@Test
public void testNothingAgain() {
assertThat(invokes.incrementAndGet(), equalTo(2));
assertThat(localValue, notNullValue());
assertThat(someValue, nullValue());
clusteringToolkit.getAtomicLong(INNER_COUNTER).getAndIncrement();
}
@After
public void tearDown() {
assertThat(classInvokes.get(), equalTo(1));
aroundInvokes.getAndIncrement();
assertThat(someValue, nullValue());
}
@AfterClass
public static void afterTearDown() {
classInvokes.getAndIncrement();
verify(2, 4, 2);
assertThat(someValue, nullValue());
}
@AfterAll
public static void checkOuterCounter() {
assertThat("BeforeAll methods is to be called once only!",
(Integer)clusteringToolkit.getMap("counters").get(OUTER_COUNTER),
equalTo(1));
assertThat("Value should still be visible here", someValue,
notNullValue());
assertThat("This should have been incremented twice in
SuccessfulRunTest.testNothingAgain",
clusteringToolkit.getAtomicLong(INNER_COUNTER).get(), is(2L));
}
private static void verify(final int beforeClass, final int before, final
int invokes) {
assertThat("Wrong (Before|After)Class invocation count",
classInvokes.get(), equalTo(beforeClass));
assertThat("Wrong (Before|After) invocation count", aroundInvokes.get(),
equalTo(before));
assertThat("Wrong test method invocation count",
SuccessfulRunTest.invokes.get(), equalTo(invokes));
}
}
Questions, comments, requests, ... complaints ? (sounds familiar somehow...)
Cheers,
Alex
_______________________________________________
tc-dev mailing list
[email protected]
http://lists.terracotta.org/mailman/listinfo/tc-dev