RFR for bug JDK-8004807: java/util/Timer/Args.java failing intermittently in HS testing
Eric Wang
yiming.wang at oracle.com
Wed Jun 4 01:12:26 UTC 2014
Hi Martin,
To sleep(1000) is not enough to reproduce the failure, because it is
much lower than the period DELAY_MS (10*1000) of the repeated task
created by "scheduleAtFixedRate(t, counter(y3), past, DELAY_MS)".
Try sleep(DELAY_MS), the failure can be reproduced.
Thanks,
Eric
On 2014/6/4 8:33, Martin Buchholz wrote:
> On Tue, Jun 3, 2014 at 11:12 AM, roger riggs <roger.riggs at oracle.com> wrote:
>
>> Hi Martin,
>>
>> Is it possible that the main thread takes too long to go from y3.await()
>> to the t.cancel() that the fixed rate timer (y3) gets called again?
>>
>>
> If that was true, adding a sleep(1000) after the awaits in my version would
> cause consistent failures, but I don't see any.
>
>
>> It seems unlikely, but with the printf, its not just compute time.
>> Canceling the timer before the printf would likely reduce the failures.
>>
> Again, we need to understand the failures independently. I have never seen
> this test fail. Is there some environmental thing?
>
>
>> Another alternative is to increase the period to allow more time for the
>> main thread to respond.
>>
> I agree that this would make the test more robust, and that's one thing my
> version does.
>
>
>> From the error, its not clear which timer was called an extra time.
>>
>>
> True.
> My updated version tries to fix that problem.
> Hopefully you can report which task is being scheduled too often.
>
>
> import java.util.*;
> import java.util.concurrent.*;
>
> public class Args {
> static final long DELAY_MS = 10 * 1000L;
>
> void schedule(final Timer t, final TimerTask task, final Date d) {
> t.schedule(task, d);
> assertThrows
> (IllegalStateException.class,
> () -> t.schedule(task, d));
> }
>
> void schedule(final Timer t, final TimerTask task, final Date d, final
> long period) {
> t.schedule(task, d, period);
> assertThrows
> (IllegalStateException.class,
> () -> t.schedule(task, d, period));
> }
>
> void scheduleAtFixedRate(final Timer t, final TimerTask task, final
> Date d, final long period) {
> t.scheduleAtFixedRate(task, d, period);
> assertThrows
> (IllegalStateException.class,
> () -> t.scheduleAtFixedRate(task, d, period));
> }
>
> TimerTask counter(final CountDownLatch latch) {
> return new TimerTask() { public void run() {
> if (latch.getCount() == 0)
> fail(String.format("Latch counted down too many times: " +
> latch));
> latch.countDown();
> }};
> }
>
> TimerTask nop() {
> return new TimerTask() { public void run() { }};
> }
>
> void test(String[] args) throws Throwable {
> final Timer t = new Timer();
> try {
> test(t);
> } finally {
> // Ensure this test doesn't interfere with subsequent
> // tests even in case of failure.
> t.cancel();
> }
>
> // Attempts to schedule tasks on a cancelled Timer result in ISE.
>
> final Date past = new Date(System.currentTimeMillis() - DELAY_MS);
> final Date future = new Date(System.currentTimeMillis() + DELAY_MS);
> assertThrows
> (IllegalStateException.class,
> () -> t.schedule(nop(), 42),
> () -> t.schedule(nop(), 42),
> () -> t.schedule(nop(), past),
> () -> t.schedule(nop(), 42, 42),
> () -> t.schedule(nop(), past, 42),
> () -> t.scheduleAtFixedRate(nop(), 42, 42),
> () -> t.scheduleAtFixedRate(nop(), past, 42),
> () -> t.scheduleAtFixedRate(nop(), future, 42));
> }
>
> void test(Timer t) throws Throwable {
> final TimerTask x = new TimerTask() { public void run() {}};
> assertThrows
> (IllegalArgumentException.class,
> () -> t.schedule(x, -42),
> () -> t.schedule(x, new Date(-42)),
>
> () -> t.schedule(x, Long.MAX_VALUE),
> () -> t.schedule(x, -42, 42),
> () -> t.schedule(x, new Date(-42), 42),
> () -> t.schedule(x, Long.MAX_VALUE, 42),
> () -> t.schedule(x, 42, 0),
> () -> t.schedule(x, new Date(42), 0),
> () -> t.schedule(x, 42, -42),
> () -> t.schedule(x, new Date(42), -42),
>
> () -> t.scheduleAtFixedRate(x, -42, 42),
> () -> t.scheduleAtFixedRate(x, new Date(-42), 42),
> () -> t.scheduleAtFixedRate(x, Long.MAX_VALUE, 42),
> () -> t.scheduleAtFixedRate(x, 42, 0),
> () -> t.scheduleAtFixedRate(x, new Date(42), 0),
> () -> t.scheduleAtFixedRate(x, 42, -42),
> () -> t.scheduleAtFixedRate(x, new Date(42), -42));
>
> assertThrows
> (NullPointerException.class,
> () -> t.schedule(null, 42),
> () -> t.schedule(x, (Date)null),
>
> () -> t.schedule(null, 42, 42),
> () -> t.schedule(x, (Date)null, 42),
>
> () -> t.scheduleAtFixedRate(null, 42, 42),
> () -> t.scheduleAtFixedRate(x, (Date)null, 42));
>
> // Create local classes for clearer diagnostics in case of failure
> class OneShotLatch extends CountDownLatch {
> OneShotLatch() { super(1); }
> }
> class FixedRateLatch extends CountDownLatch {
> FixedRateLatch() { super(11); }
> }
> class FixedDelayLatch extends CountDownLatch {
> FixedDelayLatch() { super(1); }
> }
> final CountDownLatch y1 = new OneShotLatch();
> final CountDownLatch y2 = new FixedDelayLatch();
> final CountDownLatch y3 = new FixedRateLatch();
> final long start = System.currentTimeMillis();
> final Date past = new Date(start - (10 * DELAY_MS + DELAY_MS / 2));
>
> schedule( t, counter(y1), past);
> schedule( t, counter(y2), past, DELAY_MS);
> scheduleAtFixedRate(t, counter(y3), past, DELAY_MS);
> y1.await();
> y2.await();
> y3.await();
>
> final long elapsed = System.currentTimeMillis() - start;
> if (elapsed >= DELAY_MS / 2)
> fail(String.format("Test took too long: elapsed=%d%n",
> elapsed));
> }
>
> //--------------------- Infrastructure ---------------------------
> volatile int passed = 0, failed = 0;
> void pass() {passed++;}
> void fail() {failed++; Thread.dumpStack();}
> void fail(String msg) {System.err.println(msg); fail();}
> void unexpected(Throwable t) {failed++; t.printStackTrace();}
> void check(boolean cond) {if (cond) pass(); else fail();}
> void equal(Object x, Object y) {
> if (x == null ? y == null : x.equals(y)) pass();
> else fail(x + " not equal to " + y);}
> public static void main(String[] args) throws Throwable {
> new Args().instanceMain(args);}
> void instanceMain(String[] args) throws Throwable {
> try {test(args);} catch (Throwable t) {unexpected(t);}
> System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
> if (failed > 0) throw new AssertionError("Some tests failed");}
> interface F { void f() throws Throwable; }
> void assertThrows(Class<? extends Throwable> k, F... fs) {
> for (F f : fs)
> try {f.f(); fail("Expected " + k.getName() + " not thrown");}
> catch (Throwable t) {
> if (k.isAssignableFrom(t.getClass())) pass();
> else unexpected(t);}}
> }
More information about the core-libs-dev
mailing list