Java Reference
In-Depth Information
thread is associated, so some work may be required to relay success or failure information
back to the main test runner thread so it can be reported.
For the conformance tests for java.util.concurrent , it was important that failures
be clearly associated with a specific test. Hence the JSR 166 Expert Group created a base
class [3] that provided methods to relay and report failures during tearDown , following the
convention that every test must wait until all the threads it created terminate. You may not
need to go to such lengths; the key requirements are that it be clear whether the tests passed
and that failure information is reported somewhere for use in diagnosing the problem.
If a method is supposed to block under certain conditions, then a test for that behavior should
succeed only if the thread does not proceed. Testing that a method blocks is similar to testing
that a method throws an exception; if the method returns normally, the test has failed.
Testing that a method blocks introduces an additional complication: once the method suc-
cessfully blocks, you have to convince it somehow to unblock. The obvious way to do this
is via interruption—start a blocking activity in a separate thread, wait until the thread blocks,
interrupt it, and then assert that the blocking operation completed. Of course, this requires
your blocking methods to respond to interruption by returning early or throwing Inter-
ruptedException .
The “wait until the thread blocks” part is easier said than done; in practice, you have to make
an arbitrary decision about how long the few instructions being executed could possibly take,
and wait longer than that. You should be prepared to increase this value if you are wrong (in
which case you will see spurious test failures).
Listing 12.3 shows an approach to testing blocking operations. It creates a “taker” thread that
attempts to take an element from an empty buffer. If take succeeds, it registers failure.
The test runner thread starts the taker thread, waits a long time, and then interrupts it. If the
taker thread has correctly blocked in the take operation, it will throw InterruptedEx-
ception , and the catch block for this exception treats this as success and lets the thread
exit. The main test runner thread then attempts to join with the taker thread and verifies that
the join returned successfully by calling Thread.isAlive ; if the taker thread responded
to the interrupt, the join should complete quickly.
The timed join ensures that the test completes even if take gets stuck in some unexpected
way. This test method tests several properties of take —not only that it blocks but that, when
interrupted, it throws InterruptedException . This is one of the few cases in which
Search WWH ::




Custom Search