Skip to content

Commit

Permalink
8225471: Test utility jdk.test.lib.util.FileUtils.areAllMountPointsAc…
Browse files Browse the repository at this point in the history
…cessible needs to tolerate duplicates

Reviewed-by: alanb
  • Loading branch information
Brian Burkhalter committed Jan 23, 2020
1 parent 2f2594d commit f4f7dbd
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 69 deletions.
4 changes: 2 additions & 2 deletions test/jdk/java/nio/file/FileStore/Basic.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 2020, 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
Expand Down Expand Up @@ -115,7 +115,7 @@ static void doTests(Path dir) throws IOException {
/**
* Test: Enumerate all FileStores
*/
if (FileUtils.areAllMountPointsAccessible()) {
if (FileUtils.areMountPointsAccessibleAndUnique()) {
FileStore prev = null;
for (FileStore store: FileSystems.getDefault().getFileStores()) {
System.out.format("%s (name=%s type=%s)\n", store, store.name(),
Expand Down
132 changes: 65 additions & 67 deletions test/lib/jdk/test/lib/util/FileUtils.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2020, 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
Expand Down Expand Up @@ -47,6 +47,7 @@
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -242,87 +243,84 @@ public static boolean areFileSystemsAccessible() throws IOException {
}

/**
* Checks whether all file systems are accessible. This is performed
* by checking free disk space on all mounted file systems via a
* separate, spawned process. File systems are considered to be
* accessible if this process completes successfully before a given
* fixed duration has elapsed.
* Checks whether all file systems are accessible and there are no
* duplicate mount points. This is performed by checking free disk
* space on all mounted file systems via a separate, spawned process.
* File systems are considered to be accessible if this process completes
* successfully before a given fixed duration has elapsed.
*
* @implNote On Unix this executes the {@code df} command in a separate
* process and on Windows always returns {@code true}.
*
* @return whether file systems appear to be accessible
*
* @throws RuntimeException if there are duplicate mount points or some
* other execution problem occurs
* @return whether file systems appear to be accessible and duplicate-free
*/
public static boolean areAllMountPointsAccessible() {
public static boolean areMountPointsAccessibleAndUnique() {
if (IS_WINDOWS) return true;

final AtomicBoolean areMountPointsOK = new AtomicBoolean(true);
if (!IS_WINDOWS) {
Thread thr = new Thread(() -> {
try {
Process proc = new ProcessBuilder("df").start();
BufferedReader reader = new BufferedReader
(new InputStreamReader(proc.getInputStream()));
// Skip the first line as it is the "df" output header.
if (reader.readLine() != null ) {
String prevMountPoint = null, mountPoint = null;
while ((mountPoint = reader.readLine()) != null) {
if (prevMountPoint != null &&
mountPoint.equals(prevMountPoint)) {
throw new RuntimeException
("System configuration error: " +
"duplicate mount point " + mountPoint +
" detected");
}
prevMountPoint = mountPoint;
Thread thr = new Thread(() -> {
try {
Process proc = new ProcessBuilder("df").start();
BufferedReader reader = new BufferedReader
(new InputStreamReader(proc.getInputStream()));
// Skip the first line as it is the "df" output header.
if (reader.readLine() != null ) {
Set mountPoints = new HashSet();
String mountPoint = null;
while ((mountPoint = reader.readLine()) != null) {
if (!mountPoints.add(mountPoint)) {
System.err.printf
("Config error: duplicate mount point %s%n",
mountPoint);
areMountPointsOK.set(false);
break;
}
}
}

try {
proc.waitFor(90, TimeUnit.SECONDS);
} catch (InterruptedException ignored) {
}
try {
int exitValue = proc.exitValue();
if (exitValue != 0) {
System.err.printf("df process exited with %d != 0%n",
exitValue);
areMountPointsOK.set(false);
}
} catch (IllegalThreadStateException ignored) {
System.err.println("df command apparently hung");
try {
proc.waitFor(90, TimeUnit.SECONDS);
} catch (InterruptedException ignored) {
}
try {
int exitValue = proc.exitValue();
if (exitValue != 0) {
System.err.printf("df process exited with %d != 0%n",
exitValue);
areMountPointsOK.set(false);
}
} catch (IOException ioe) {
throw new RuntimeException(ioe);
};
});
} catch (IllegalThreadStateException ignored) {
System.err.println("df command apparently hung");
areMountPointsOK.set(false);
}
} catch (IOException ioe) {
throw new RuntimeException(ioe);
};
});

final AtomicReference throwableReference =
new AtomicReference<Throwable>();
thr.setUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
throwableReference.set(e);
}
});
final AtomicReference throwableReference =
new AtomicReference<Throwable>();
thr.setUncaughtExceptionHandler(
new Thread.UncaughtExceptionHandler() {
public void uncaughtException(Thread t, Throwable e) {
throwableReference.set(e);
}
});

thr.start();
try {
thr.join(120*1000L);
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
thr.start();
try {
thr.join(120*1000L);
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}

Throwable uncaughtException = (Throwable)throwableReference.get();
if (uncaughtException != null) {
throw new RuntimeException(uncaughtException);
}
Throwable uncaughtException = (Throwable)throwableReference.get();
if (uncaughtException != null) {
throw new RuntimeException(uncaughtException);
}

if (thr.isAlive()) {
throw new RuntimeException("df thread did not join in time");
}
if (thr.isAlive()) {
throw new RuntimeException("df thread did not join in time");
}

return areMountPointsOK.get();
Expand Down

0 comments on commit f4f7dbd

Please sign in to comment.