8175115: Improve instrumentation of java/nio/file/WatchService/LotsOfEvents.java

Attempt an additional long poll to check for missed events and print more information

Reviewed-by: rriggs
This commit is contained in:
Brian Burkhalter 2017-02-24 11:28:00 -08:00
parent 32e70396f4
commit c3b3895160

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -23,22 +23,25 @@
/* @test /* @test
* @bug 6907760 6929532 * @bug 6907760 6929532
* @summary Tests WatchService behavior when lots of events are pending * @summary Tests WatchService behavior when lots of events are pending (use -Dseed=X to set PRNG seed)
* @library .. * @library ..
* @library /lib/testlibrary/
* @build jdk.testlibrary.*
* @run main/timeout=180 LotsOfEvents * @run main/timeout=180 LotsOfEvents
* @key randomness * @key randomness
*/ */
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.file.*;
import static java.nio.file.StandardWatchEventKinds.*;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import jdk.testlibrary.RandomFactory;
public class LotsOfEvents { public class LotsOfEvents {
static final Random rand = new Random(); private static final Random RAND = RandomFactory.getRandom();
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Path dir = TestUtil.createTemporaryDirectory(); Path dir = TestUtil.createTemporaryDirectory();
@ -70,7 +73,7 @@ public class LotsOfEvents {
Thread.sleep(1000); Thread.sleep(1000);
// check that we see the create events (or overflow) // check that we see the create events (or overflow)
drainAndCheckOverflowEvents(watcher, ENTRY_CREATE, n); drainAndCheckOverflowEvents(dir, watcher, ENTRY_CREATE, n);
// delete the files // delete the files
for (int i=0; i<n; i++) { for (int i=0; i<n; i++) {
@ -81,11 +84,12 @@ public class LotsOfEvents {
Thread.sleep(1000); Thread.sleep(1000);
// check that we see the delete events (or overflow) // check that we see the delete events (or overflow)
drainAndCheckOverflowEvents(watcher, ENTRY_DELETE, n); drainAndCheckOverflowEvents(dir, watcher, ENTRY_DELETE, n);
} }
} }
static void drainAndCheckOverflowEvents(WatchService watcher, static void drainAndCheckOverflowEvents(Path dir,
WatchService watcher,
WatchEvent.Kind<?> expectedKind, WatchEvent.Kind<?> expectedKind,
int count) int count)
throws IOException, InterruptedException throws IOException, InterruptedException
@ -123,8 +127,25 @@ public class LotsOfEvents {
} }
// check that all expected events were received or there was an overflow // check that all expected events were received or there was an overflow
if (nread < count && !gotOverflow) if (nread < count && !gotOverflow) {
throw new RuntimeException("Insufficient events"); System.err.printf("Test directory %s contains %d files%n",
dir, Files.list(dir).count());
long timeBeforePoll = System.nanoTime();
key = watcher.poll(15, TimeUnit.SECONDS);
long timeAfterPoll = System.nanoTime();
if (key == null) {
System.err.println("key still null after extra polling");
} else {
List<WatchEvent<?>> events = key.pollEvents();
System.err.printf("Retrieved key with %d events after %d ns%n",
events.size(), timeAfterPoll - timeBeforePoll);
}
throw new RuntimeException("Insufficient "
+ expectedKind.name() + " events: expected "
+ count + ", received " + nread);
}
} }
/** /**
@ -134,14 +155,14 @@ public class LotsOfEvents {
throws IOException, InterruptedException throws IOException, InterruptedException
{ {
// this test uses a random number of files // this test uses a random number of files
final int nfiles = 5 + rand.nextInt(10); final int nfiles = 5 + RAND.nextInt(10);
DirectoryEntry[] entries = new DirectoryEntry[nfiles]; DirectoryEntry[] entries = new DirectoryEntry[nfiles];
for (int i=0; i<nfiles; i++) { for (int i=0; i<nfiles; i++) {
entries[i] = new DirectoryEntry(dir.resolve("foo" + i)); entries[i] = new DirectoryEntry(dir.resolve("foo" + i));
// "some" of the files exist, some do not. // "some" of the files exist, some do not.
entries[i].deleteIfExists(); entries[i].deleteIfExists();
if (rand.nextBoolean()) if (RAND.nextBoolean())
entries[i].create(); entries[i].create();
} }
@ -153,8 +174,8 @@ public class LotsOfEvents {
// make some noise!!! // make some noise!!!
for (int i=0; i<100; i++) { for (int i=0; i<100; i++) {
DirectoryEntry entry = entries[rand.nextInt(nfiles)]; DirectoryEntry entry = entries[RAND.nextInt(nfiles)];
int action = rand.nextInt(10); int action = RAND.nextInt(10);
switch (action) { switch (action) {
case 0 : entry.create(); break; case 0 : entry.create(); break;
case 1 : entry.deleteIfExists(); break; case 1 : entry.deleteIfExists(); break;