undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
182
test/jdk/java/nio/file/WatchService/MayFlies.java
Normal file
182
test/jdk/java/nio/file/WatchService/MayFlies.java
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 7164570 7191467
|
||||
* @summary Test that CREATE and DELETE events are paired for very
|
||||
* short lived files
|
||||
* @library ..
|
||||
* @run main MayFlies
|
||||
* @key randomness
|
||||
*/
|
||||
|
||||
import java.nio.file.*;
|
||||
import static java.nio.file.StandardWatchEventKinds.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
|
||||
public class MayFlies {
|
||||
|
||||
static volatile boolean stopped;
|
||||
|
||||
static volatile boolean failure;
|
||||
|
||||
/**
|
||||
* Continuously creates short-lived files in a directory until {@code
|
||||
* stopped} is set to {@code true}.
|
||||
*/
|
||||
static class MayFlyHatcher implements Runnable {
|
||||
static final Random rand = new Random();
|
||||
|
||||
private final Path dir;
|
||||
private final String prefix;
|
||||
|
||||
private MayFlyHatcher(Path dir, String prefix) {
|
||||
this.dir = dir;
|
||||
this.prefix = prefix;
|
||||
}
|
||||
|
||||
static void start(Path dir, String prefix) {
|
||||
MayFlyHatcher hatcher = new MayFlyHatcher(dir, prefix);
|
||||
new Thread(hatcher).start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
int n = 0;
|
||||
while (!stopped) {
|
||||
Path name = dir.resolve(prefix + (++n));
|
||||
Files.createFile(name);
|
||||
if (rand.nextBoolean())
|
||||
Thread.sleep(rand.nextInt(500));
|
||||
Files.delete(name);
|
||||
Thread.sleep(rand.nextInt(100));
|
||||
}
|
||||
System.out.format("%d %ss hatched%n", n, prefix);
|
||||
} catch (Exception x) {
|
||||
failure = true;
|
||||
x.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test phases.
|
||||
*/
|
||||
static enum Phase {
|
||||
/**
|
||||
* Short-lived files are being created
|
||||
*/
|
||||
RUNNING,
|
||||
/**
|
||||
* Draining the final events
|
||||
*/
|
||||
FINISHING,
|
||||
/**
|
||||
* No more events or overflow detected
|
||||
*/
|
||||
FINISHED
|
||||
};
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// schedules file creation to stop after 10 seconds
|
||||
ScheduledExecutorService pool = Executors.newSingleThreadScheduledExecutor();
|
||||
pool.schedule(
|
||||
new Runnable() { public void run() { stopped = true; }},
|
||||
10, TimeUnit.SECONDS);
|
||||
|
||||
Path dir = TestUtil.createTemporaryDirectory();
|
||||
|
||||
Set<Path> entries = new HashSet<>();
|
||||
int nCreateEvents = 0;
|
||||
boolean overflow = false;
|
||||
|
||||
try (WatchService watcher = FileSystems.getDefault().newWatchService()) {
|
||||
WatchKey key = dir.register(watcher, ENTRY_CREATE, ENTRY_DELETE);
|
||||
|
||||
// start hatching Mayflies
|
||||
MayFlyHatcher.start(dir, "clinger");
|
||||
MayFlyHatcher.start(dir, "crawler");
|
||||
MayFlyHatcher.start(dir, "burrower");
|
||||
MayFlyHatcher.start(dir, "swimmer");
|
||||
|
||||
Phase phase = Phase.RUNNING;
|
||||
while (phase != Phase.FINISHED) {
|
||||
// during the running phase then poll for 1 second.
|
||||
// once the file creation has stopped then move to the finishing
|
||||
// phase where we do a long poll to ensure that all events have
|
||||
// been read.
|
||||
int time = (phase == Phase.RUNNING) ? 1 : 15;
|
||||
key = watcher.poll(time, TimeUnit.SECONDS);
|
||||
if (key == null) {
|
||||
if (phase == Phase.RUNNING && stopped)
|
||||
phase = Phase.FINISHING;
|
||||
else if (phase == Phase.FINISHING)
|
||||
phase = Phase.FINISHED;
|
||||
} else {
|
||||
// process events
|
||||
for (WatchEvent<?> event: key.pollEvents()) {
|
||||
if (event.kind() == ENTRY_CREATE) {
|
||||
Path name = (Path)event.context();
|
||||
boolean added = entries.add(name);
|
||||
if (!added)
|
||||
throw new RuntimeException("Duplicate ENTRY_CREATE event");
|
||||
nCreateEvents++;
|
||||
} else if (event.kind() == ENTRY_DELETE) {
|
||||
Path name = (Path)event.context();
|
||||
boolean removed = entries.remove(name);
|
||||
if (!removed)
|
||||
throw new RuntimeException("ENTRY_DELETE event without ENTRY_CREATE event");
|
||||
} else if (event.kind() == OVERFLOW) {
|
||||
overflow = true;
|
||||
phase = Phase.FINISHED;
|
||||
} else {
|
||||
throw new RuntimeException("Unexpected event: " + event.kind());
|
||||
}
|
||||
}
|
||||
key.reset();
|
||||
}
|
||||
}
|
||||
|
||||
System.out.format("%d ENTRY_CREATE events read%n", nCreateEvents);
|
||||
|
||||
// there should be a DELETE event for each CREATE event and so the
|
||||
// entries set should be empty.
|
||||
if (!overflow && !entries.isEmpty())
|
||||
throw new RuntimeException("Missed " + entries.size() + " DELETE event(s)");
|
||||
|
||||
|
||||
} finally {
|
||||
try {
|
||||
TestUtil.removeAll(dir);
|
||||
} finally {
|
||||
pool.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
if (failure)
|
||||
throw new RuntimeException("Test failed - see log file for details");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue