aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-process/src
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-03-08 14:10:00 +0100
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-03-21 16:44:03 +0100
commitca0b3a94ced3ee10f76c9465ccfa19767d62884d (patch)
tree27a5bf6dc1717e2667034b8e89de8a95b5d3f87f /server/sonar-process/src
parent57ceade526c1319333b855d08319145c3471de52 (diff)
downloadsonarqube-ca0b3a94ced3ee10f76c9465ccfa19767d62884d.tar.gz
sonarqube-ca0b3a94ced3ee10f76c9465ccfa19767d62884d.zip
SONAR-7435 move awaitTermination to ProcessUtils and add UTs
Diffstat (limited to 'server/sonar-process/src')
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/ProcessUtils.java20
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/ProcessUtilsTest.java79
2 files changed, 99 insertions, 0 deletions
diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessUtils.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessUtils.java
index 041c4f5ccc1..e468172dfe9 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/ProcessUtils.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessUtils.java
@@ -71,4 +71,24 @@ public class ProcessUtils {
IOUtils.closeQuietly(process.getErrorStream());
}
}
+
+ public static void awaitTermination(Thread... threads) {
+ for (Thread thread : threads) {
+ awaitTermination(thread);
+ }
+ }
+
+ public static void awaitTermination(@Nullable Thread t) {
+ if (t == null || Thread.currentThread() == t) {
+ return;
+ }
+
+ while (t.isAlive()) {
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ // ignore, keep on waiting for t to stop
+ }
+ }
+ }
}
diff --git a/server/sonar-process/src/test/java/org/sonar/process/ProcessUtilsTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessUtilsTest.java
index 45aeb2a7079..9b6be953e6b 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/ProcessUtilsTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessUtilsTest.java
@@ -23,6 +23,7 @@ import org.junit.Test;
import org.sonar.test.TestUtils;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.process.ProcessUtils.awaitTermination;
public class ProcessUtilsTest {
@@ -30,4 +31,82 @@ public class ProcessUtilsTest {
public void private_constructor() {
assertThat(TestUtils.hasOnlyPrivateConstructors(ProcessUtils.class)).isTrue();
}
+
+ @Test
+ public void awaitTermination_does_not_fail_on_null_Thread_argument() {
+ awaitTermination((Thread) null);
+ }
+
+ @Test(timeout = 100L)
+ public void awaitTermination_does_not_wait_on_currentThread() {
+ awaitTermination(Thread.currentThread());
+ }
+
+ @Test(timeout = 3000)
+ public void awaitTermination_ignores_interrupted_exception_of_current_thread() throws InterruptedException {
+ final EverRunningThread runningThread = new EverRunningThread();
+ final Thread safeJoiner = new Thread() {
+ @Override
+ public void run() {
+ awaitTermination(runningThread);
+ }
+ };
+ final Thread simpleJoiner = new Thread() {
+ @Override
+ public void run() {
+ try {
+ runningThread.join();
+ } catch (InterruptedException e) {
+ System.err.println("runningThread interruption detected in SimpleJoiner");
+ }
+ }
+ };
+ runningThread.start();
+ safeJoiner.start();
+ simpleJoiner.start();
+
+ // interrupt safeJoiner _before simpleJoiner to work around some arbitrary sleep delay_ which should not stop watching
+ safeJoiner.interrupt();
+
+ // interrupting simpleJoiner which should stop
+ simpleJoiner.interrupt();
+
+ while (simpleJoiner.isAlive()) {
+ // wait for simpleJoiner to stop
+ }
+
+ // safeJoiner must still be alive
+ assertThat(safeJoiner.isAlive()).isTrue() ;
+
+ // stop runningThread
+ runningThread.stopIt();
+
+ while (runningThread.isAlive()) {
+ // wait for runningThread to stop
+ }
+
+ // wait for safeJoiner to stop because runningThread has stopped, if it doesn't, the test will fail with a timeout
+ safeJoiner.join();
+ }
+
+ @Test(timeout = 100L)
+ public void awaitTermination_of_vararg_does_not_fail_when_there_is_a_null_or_current_thread() {
+ awaitTermination(null, Thread.currentThread(), null);
+ }
+
+ private static class EverRunningThread extends Thread {
+ private volatile boolean stop = false;
+
+ @Override
+ public void run() {
+ while (!stop) {
+ // infinite loop!
+ }
+ }
+
+ public void stopIt() {
+ this.stop = true;
+ }
+ }
+
}