/* * SonarQube * Copyright (C) 2009-2017 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package org.sonar.process; import org.junit.Rule; import org.junit.Test; import org.junit.rules.DisableOnDebug; import org.junit.rules.TestRule; import org.junit.rules.Timeout; import org.sonar.test.TestUtils; import static org.assertj.core.api.Assertions.assertThat; import static org.sonar.process.ProcessUtils.awaitTermination; public class ProcessUtilsTest { @Rule public TestRule safeguardTimeout = new DisableOnDebug(Timeout.seconds(60)); @Test public void private_constructor() { assertThat(TestUtils.hasOnlyPrivateConstructors(ProcessUtils.class)).isTrue(); } @Test public void awaitTermination_does_not_fail_on_null_Thread_argument() { awaitTermination(null); } @Test public void awaitTermination_does_not_wait_on_currentThread() { awaitTermination(Thread.currentThread()); } @Test public void awaitTermination_ignores_interrupted_exception_of_current_thread() throws InterruptedException { final EverRunningThread runningThread = new EverRunningThread(); final Thread safeJoiner = new Thread(() -> awaitTermination(runningThread)); final Thread simpleJoiner = new Thread(() -> { 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(); } 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; } } }