From: Simon Brandhof Date: Thu, 25 Sep 2014 21:29:55 +0000 (+0200) Subject: SONAR-4898 add missing tests X-Git-Tag: 4.5-RC3~4 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=9654662b48c918b55383846c6575b7f809437108;p=sonarqube.git SONAR-4898 add missing tests --- diff --git a/server/sonar-process/pom.xml b/server/sonar-process/pom.xml index fad6b0c5b48..1475d7099d6 100644 --- a/server/sonar-process/pom.xml +++ b/server/sonar-process/pom.xml @@ -41,13 +41,8 @@ - junit - junit - test - - - org.easytesting - fest-assert + org.codehaus.sonar + sonar-testing-harness test @@ -55,11 +50,6 @@ mockito-core test - - org.hamcrest - hamcrest-all - test - com.google.guava guava diff --git a/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java b/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java index 2441a193748..4ba726a2d85 100644 --- a/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java +++ b/server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java @@ -21,16 +21,26 @@ package org.sonar.process; import org.slf4j.LoggerFactory; +/** + * This watchdog asks for graceful termination of process when the file + * <process_key>.stop is created in temp directory. + */ public class StopWatcher extends Thread { private final Stoppable stoppable; private final ProcessCommands commands; private boolean watching = true; + private final long delayMs; public StopWatcher(ProcessCommands commands, Stoppable stoppable) { + this(commands, stoppable, 500L); + } + + StopWatcher(ProcessCommands commands, Stoppable stoppable, long delayMs) { super("Stop Watcher"); this.commands = commands; this.stoppable = stoppable; + this.delayMs = delayMs; } @Override @@ -44,7 +54,7 @@ public class StopWatcher extends Thread { watching = false; } else { try { - Thread.sleep(500L); + Thread.sleep(delayMs); } catch (InterruptedException ignored) { watching = false; } diff --git a/server/sonar-process/src/test/java/org/sonar/process/ConfigurationUtilsTest.java b/server/sonar-process/src/test/java/org/sonar/process/ConfigurationUtilsTest.java index de928b93850..4aa072a6eb3 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/ConfigurationUtilsTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/ConfigurationUtilsTest.java @@ -24,6 +24,7 @@ import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.sonar.test.TestUtils; import java.io.File; import java.util.Map; @@ -92,4 +93,9 @@ public class ConfigurationUtilsTest { assertThat(e).hasMessage("Could not read properties from file: " + propsFile.getAbsolutePath()); } } + + @Test + public void private_constructor() throws Exception { + TestUtils.assertPrivateConstructor(ConfigurationUtils.class); + } } diff --git a/server/sonar-process/src/test/java/org/sonar/process/LoopbackAddressTest.java b/server/sonar-process/src/test/java/org/sonar/process/LoopbackAddressTest.java index 6a8819c3a81..b612e24342d 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/LoopbackAddressTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/LoopbackAddressTest.java @@ -21,6 +21,7 @@ package org.sonar.process; import com.google.common.collect.Iterators; import org.junit.Test; +import org.sonar.test.TestUtils; import java.net.NetworkInterface; import java.util.Collections; @@ -48,4 +49,9 @@ public class LoopbackAddressTest { assertThat(e).hasMessage("Impossible to get a IPv4 loopback address"); } } + + @Test + public void private_constructor() throws Exception { + TestUtils.assertPrivateConstructor(LoopbackAddress.class); + } } diff --git a/server/sonar-process/src/test/java/org/sonar/process/NetworkUtilsTest.java b/server/sonar-process/src/test/java/org/sonar/process/NetworkUtilsTest.java index 9eb41dbf6ac..0462f76707a 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/NetworkUtilsTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/NetworkUtilsTest.java @@ -20,8 +20,7 @@ package org.sonar.process; import org.junit.Test; - -import java.net.ServerSocket; +import org.sonar.test.TestUtils; import static org.fest.assertions.Assertions.assertThat; @@ -38,23 +37,11 @@ public class NetworkUtilsTest { int port1 = NetworkUtils.freePort(); int port2 = NetworkUtils.freePort(); - assertThat(port1).isGreaterThan(1024); - assertThat(port2).isGreaterThan(1024); - assertThat(port1).isNotSameAs(port2); } @Test - public void find_multiple_free_non_adjacent_port() throws Exception { - int port1 = NetworkUtils.freePort(); - - ServerSocket socket = new ServerSocket(port1 + 1); - - int port2 = NetworkUtils.freePort(); - - assertThat(port1).isGreaterThan(1024); - assertThat(port2).isGreaterThan(1024); - - assertThat(port1).isNotSameAs(port2); + public void private_constructor() throws Exception { + TestUtils.assertPrivateConstructor(NetworkUtils.class); } } 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 new file mode 100644 index 00000000000..ae1f53b2653 --- /dev/null +++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessUtilsTest.java @@ -0,0 +1,31 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.Test; +import org.sonar.test.TestUtils; + +public class ProcessUtilsTest { + + @Test + public void private_constructor() throws Exception { + TestUtils.assertPrivateConstructor(ProcessUtils.class); + } +} diff --git a/server/sonar-process/src/test/java/org/sonar/process/PropsTest.java b/server/sonar-process/src/test/java/org/sonar/process/PropsTest.java index 5d283b44f8f..25feeef39b8 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/PropsTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/PropsTest.java @@ -19,8 +19,12 @@ */ package org.sonar.process; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import java.io.File; +import java.io.IOException; import java.util.Properties; import static org.fest.assertions.Assertions.assertThat; @@ -28,8 +32,11 @@ import static org.fest.assertions.Fail.fail; public class PropsTest { + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + @Test - public void of() throws Exception { + public void value() throws Exception { Properties p = new Properties(); p.setProperty("foo", "bar"); Props props = new Props(p); @@ -38,10 +45,18 @@ public class PropsTest { assertThat(props.value("foo", "default value")).isEqualTo("bar"); assertThat(props.value("unknown")).isNull(); assertThat(props.value("unknown", "default value")).isEqualTo("default value"); + + assertThat(props.nonNullValue("foo")).isEqualTo("bar"); + try { + props.nonNullValue("other"); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("Missing property: other"); + } } @Test - public void intOf() throws Exception { + public void valueAsInt() throws Exception { Properties p = new Properties(); p.setProperty("foo", "33"); p.setProperty("blank", ""); @@ -56,7 +71,7 @@ public class PropsTest { } @Test - public void intOf_not_integer() throws Exception { + public void valueAsInt_not_integer() throws Exception { Properties p = new Properties(); p.setProperty("foo", "bar"); Props props = new Props(p); @@ -130,6 +145,21 @@ public class PropsTest { // do not decrypt assertThat(props.rawProperties().get("encrypted_prop")).isEqualTo("{aes}abcde"); assertThat(props.rawProperties().get("clear_prop")).isEqualTo("foo"); + } + @Test + public void nonNullValueAsFile() throws IOException { + File file = temp.newFile(); + Props props = new Props(new Properties()); + props.set("path", file.getAbsolutePath()); + + assertThat(props.nonNullValueAsFile("path")).isEqualTo(file); + + try { + props.nonNullValueAsFile("other_path"); + fail(); + } catch (IllegalArgumentException e) { + assertThat(e).hasMessage("Property other_path is not set"); + } } } diff --git a/server/sonar-process/src/test/java/org/sonar/process/StopWatcherTest.java b/server/sonar-process/src/test/java/org/sonar/process/StopWatcherTest.java new file mode 100644 index 00000000000..8a6545e5819 --- /dev/null +++ b/server/sonar-process/src/test/java/org/sonar/process/StopWatcherTest.java @@ -0,0 +1,59 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.TemporaryFolder; + +import static org.mockito.Mockito.*; + +public class StopWatcherTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Test(timeout = 1000L) + public void stop_if_receive_command() throws Exception { + ProcessCommands commands = mock(ProcessCommands.class); + when(commands.askedForStop()).thenReturn(false).thenReturn(true); + Stoppable stoppable = mock(Stoppable.class); + + StopWatcher watcher = new StopWatcher(commands, stoppable, 10L); + watcher.start(); + watcher.join(); + + verify(stoppable).stopAsync(); + } + + @Test(timeout = 1000L) + public void stop_watching_on_interruption() throws Exception { + ProcessCommands commands = mock(ProcessCommands.class); + when(commands.askedForStop()).thenReturn(false); + Stoppable stoppable = mock(Stoppable.class); + + StopWatcher watcher = new StopWatcher(commands, stoppable, 1000L); + watcher.start(); + Thread.sleep(50L); + watcher.interrupt(); + + verify(stoppable, never()).stopAsync(); + } +} diff --git a/server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java b/server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java index e1eed0548aa..494457134a8 100644 --- a/server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java +++ b/server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java @@ -25,55 +25,47 @@ import org.junit.rules.TemporaryFolder; import org.mockito.invocation.InvocationOnMock; import org.mockito.stubbing.Answer; -import java.io.File; - -import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Mockito.doAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.*; public class StopperThreadTest { + @Rule public TemporaryFolder temp = new TemporaryFolder(); - @Test(timeout = 3000L) public void stop_in_a_timely_fashion() throws Exception { -// File dir = temp.newFile(); -// ProcessCommands commands = new ProcessCommands(dir, "foo"); -// assertThat(dir).exists(); -// Monitored monitored = mock(Monitored.class); -// -// // max stop timeout is 5 seconds, but test fails after 3 seconds -// // -> guarantees that stop is immediate -// StopperThread stopper = new StopperThread(monitored, commands, 5000L); -// stopper.start(); -// stopper.join(); -// -// verify(monitored).stop(); -// assertThat(dir).doesNotExist(); + ProcessCommands commands = mock(ProcessCommands.class); + Monitored monitored = mock(Monitored.class); + + // max stop timeout is 5 seconds, but test fails after 3 seconds + // -> guarantees that stop is immediate + StopperThread stopper = new StopperThread(monitored, commands, 5000L); + stopper.start(); + stopper.join(); + + verify(monitored).stop(); + verify(commands).endWatch(); } @Test(timeout = 3000L) public void stop_timeout() throws Exception { -// File file = temp.newFile(); -// ProcessCommands commands = new ProcessCommands(file); -// assertThat(file).exists(); -// Monitored monitored = mock(Monitored.class); -// doAnswer(new Answer() { -// @Override -// public Object answer(InvocationOnMock invocationOnMock) throws Throwable { -// Thread.sleep(10000L); -// return null; -// } -// }).when(monitored).stop(); -// -// // max stop timeout is 10 milliseconds -// StopperThread stopper = new StopperThread(monitored, commands, 10L); -// stopper.start(); -// stopper.join(); -// -// verify(monitored).stop(); -// assertThat(file).doesNotExist(); + ProcessCommands commands = mock(ProcessCommands.class); + Monitored monitored = mock(Monitored.class); + doAnswer(new Answer() { + @Override + public Object answer(InvocationOnMock invocationOnMock) throws Throwable { + Thread.sleep(10000L); + return null; + } + }).when(monitored).stop(); + + // max stop timeout is 50 milliseconds + StopperThread stopper = new StopperThread(monitored, commands, 50L); + stopper.start(); + stopper.join(); + + verify(monitored).stop(); + // even if stopper was interrupted, stop watching process + verify(commands).endWatch(); } } diff --git a/sonar-testing-harness/src/main/java/org/sonar/test/TestUtils.java b/sonar-testing-harness/src/main/java/org/sonar/test/TestUtils.java index e537466d262..0a5d8fcaef0 100644 --- a/sonar-testing-harness/src/main/java/org/sonar/test/TestUtils.java +++ b/sonar-testing-harness/src/main/java/org/sonar/test/TestUtils.java @@ -23,8 +23,13 @@ import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; import java.io.File; +import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; import java.net.URL; +import static org.fest.assertions.Assertions.assertThat; +import static org.fest.assertions.Fail.fail; + /** * Utilities for unit tests * @@ -67,4 +72,15 @@ public final class TestUtils { resourcePath += path; return getResource(resourcePath); } + + public static void assertPrivateConstructor(Class clazz) { + try { + Constructor constructor = clazz.getDeclaredConstructor(); + assertThat(Modifier.isPrivate(constructor.getModifiers())).isTrue(); + constructor.setAccessible(true); + constructor.newInstance(); + } catch (Exception e) { + fail("Fail to instantiate " + clazz, e); + } + } }