SONAR-4898 add missing tests

This commit is contained in:
Simon Brandhof 2014-09-25 23:29:55 +02:00
parent 4a5a256eef
commit 9654662b48
10 changed files with 198 additions and 71 deletions

View File

@ -41,13 +41,8 @@
</dependency> </dependency>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>org.codehaus.sonar</groupId>
<artifactId>junit</artifactId> <artifactId>sonar-testing-harness</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easytesting</groupId>
<artifactId>fest-assert</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -55,11 +50,6 @@
<artifactId>mockito-core</artifactId> <artifactId>mockito-core</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>com.google.guava</groupId> <groupId>com.google.guava</groupId>
<artifactId>guava</artifactId> <artifactId>guava</artifactId>

View File

@ -21,16 +21,26 @@ package org.sonar.process;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/**
* This watchdog asks for graceful termination of process when the file
* &lt;process_key&gt;.stop is created in temp directory.
*/
public class StopWatcher extends Thread { public class StopWatcher extends Thread {
private final Stoppable stoppable; private final Stoppable stoppable;
private final ProcessCommands commands; private final ProcessCommands commands;
private boolean watching = true; private boolean watching = true;
private final long delayMs;
public StopWatcher(ProcessCommands commands, Stoppable stoppable) { public StopWatcher(ProcessCommands commands, Stoppable stoppable) {
this(commands, stoppable, 500L);
}
StopWatcher(ProcessCommands commands, Stoppable stoppable, long delayMs) {
super("Stop Watcher"); super("Stop Watcher");
this.commands = commands; this.commands = commands;
this.stoppable = stoppable; this.stoppable = stoppable;
this.delayMs = delayMs;
} }
@Override @Override
@ -44,7 +54,7 @@ public class StopWatcher extends Thread {
watching = false; watching = false;
} else { } else {
try { try {
Thread.sleep(500L); Thread.sleep(delayMs);
} catch (InterruptedException ignored) { } catch (InterruptedException ignored) {
watching = false; watching = false;
} }

View File

@ -24,6 +24,7 @@ import org.apache.commons.io.FileUtils;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder; import org.junit.rules.TemporaryFolder;
import org.sonar.test.TestUtils;
import java.io.File; import java.io.File;
import java.util.Map; import java.util.Map;
@ -92,4 +93,9 @@ public class ConfigurationUtilsTest {
assertThat(e).hasMessage("Could not read properties from file: " + propsFile.getAbsolutePath()); assertThat(e).hasMessage("Could not read properties from file: " + propsFile.getAbsolutePath());
} }
} }
@Test
public void private_constructor() throws Exception {
TestUtils.assertPrivateConstructor(ConfigurationUtils.class);
}
} }

View File

@ -21,6 +21,7 @@ package org.sonar.process;
import com.google.common.collect.Iterators; import com.google.common.collect.Iterators;
import org.junit.Test; import org.junit.Test;
import org.sonar.test.TestUtils;
import java.net.NetworkInterface; import java.net.NetworkInterface;
import java.util.Collections; import java.util.Collections;
@ -48,4 +49,9 @@ public class LoopbackAddressTest {
assertThat(e).hasMessage("Impossible to get a IPv4 loopback address"); assertThat(e).hasMessage("Impossible to get a IPv4 loopback address");
} }
} }
@Test
public void private_constructor() throws Exception {
TestUtils.assertPrivateConstructor(LoopbackAddress.class);
}
} }

View File

@ -20,8 +20,7 @@
package org.sonar.process; package org.sonar.process;
import org.junit.Test; import org.junit.Test;
import org.sonar.test.TestUtils;
import java.net.ServerSocket;
import static org.fest.assertions.Assertions.assertThat; import static org.fest.assertions.Assertions.assertThat;
@ -38,23 +37,11 @@ public class NetworkUtilsTest {
int port1 = NetworkUtils.freePort(); int port1 = NetworkUtils.freePort();
int port2 = NetworkUtils.freePort(); int port2 = NetworkUtils.freePort();
assertThat(port1).isGreaterThan(1024);
assertThat(port2).isGreaterThan(1024);
assertThat(port1).isNotSameAs(port2); assertThat(port1).isNotSameAs(port2);
} }
@Test @Test
public void find_multiple_free_non_adjacent_port() throws Exception { public void private_constructor() throws Exception {
int port1 = NetworkUtils.freePort(); TestUtils.assertPrivateConstructor(NetworkUtils.class);
ServerSocket socket = new ServerSocket(port1 + 1);
int port2 = NetworkUtils.freePort();
assertThat(port1).isGreaterThan(1024);
assertThat(port2).isGreaterThan(1024);
assertThat(port1).isNotSameAs(port2);
} }
} }

View File

@ -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);
}
}

View File

@ -19,8 +19,12 @@
*/ */
package org.sonar.process; package org.sonar.process;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import java.io.File;
import java.io.IOException;
import java.util.Properties; import java.util.Properties;
import static org.fest.assertions.Assertions.assertThat; import static org.fest.assertions.Assertions.assertThat;
@ -28,8 +32,11 @@ import static org.fest.assertions.Fail.fail;
public class PropsTest { public class PropsTest {
@Rule
public TemporaryFolder temp = new TemporaryFolder();
@Test @Test
public void of() throws Exception { public void value() throws Exception {
Properties p = new Properties(); Properties p = new Properties();
p.setProperty("foo", "bar"); p.setProperty("foo", "bar");
Props props = new Props(p); Props props = new Props(p);
@ -38,10 +45,18 @@ public class PropsTest {
assertThat(props.value("foo", "default value")).isEqualTo("bar"); assertThat(props.value("foo", "default value")).isEqualTo("bar");
assertThat(props.value("unknown")).isNull(); assertThat(props.value("unknown")).isNull();
assertThat(props.value("unknown", "default value")).isEqualTo("default value"); 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 @Test
public void intOf() throws Exception { public void valueAsInt() throws Exception {
Properties p = new Properties(); Properties p = new Properties();
p.setProperty("foo", "33"); p.setProperty("foo", "33");
p.setProperty("blank", ""); p.setProperty("blank", "");
@ -56,7 +71,7 @@ public class PropsTest {
} }
@Test @Test
public void intOf_not_integer() throws Exception { public void valueAsInt_not_integer() throws Exception {
Properties p = new Properties(); Properties p = new Properties();
p.setProperty("foo", "bar"); p.setProperty("foo", "bar");
Props props = new Props(p); Props props = new Props(p);
@ -130,6 +145,21 @@ public class PropsTest {
// do not decrypt // do not decrypt
assertThat(props.rawProperties().get("encrypted_prop")).isEqualTo("{aes}abcde"); assertThat(props.rawProperties().get("encrypted_prop")).isEqualTo("{aes}abcde");
assertThat(props.rawProperties().get("clear_prop")).isEqualTo("foo"); 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");
}
} }
} }

View File

@ -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();
}
}

View File

@ -25,55 +25,47 @@ import org.junit.rules.TemporaryFolder;
import org.mockito.invocation.InvocationOnMock; import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer; import org.mockito.stubbing.Answer;
import java.io.File; import static org.mockito.Mockito.*;
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;
public class StopperThreadTest { public class StopperThreadTest {
@Rule @Rule
public TemporaryFolder temp = new TemporaryFolder(); public TemporaryFolder temp = new TemporaryFolder();
@Test(timeout = 3000L) @Test(timeout = 3000L)
public void stop_in_a_timely_fashion() throws Exception { public void stop_in_a_timely_fashion() throws Exception {
// File dir = temp.newFile(); ProcessCommands commands = mock(ProcessCommands.class);
// ProcessCommands commands = new ProcessCommands(dir, "foo"); Monitored monitored = mock(Monitored.class);
// 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
// // max stop timeout is 5 seconds, but test fails after 3 seconds StopperThread stopper = new StopperThread(monitored, commands, 5000L);
// // -> guarantees that stop is immediate stopper.start();
// StopperThread stopper = new StopperThread(monitored, commands, 5000L); stopper.join();
// stopper.start();
// stopper.join(); verify(monitored).stop();
// verify(commands).endWatch();
// verify(monitored).stop();
// assertThat(dir).doesNotExist();
} }
@Test(timeout = 3000L) @Test(timeout = 3000L)
public void stop_timeout() throws Exception { public void stop_timeout() throws Exception {
// File file = temp.newFile(); ProcessCommands commands = mock(ProcessCommands.class);
// ProcessCommands commands = new ProcessCommands(file); Monitored monitored = mock(Monitored.class);
// assertThat(file).exists(); doAnswer(new Answer() {
// Monitored monitored = mock(Monitored.class); @Override
// doAnswer(new Answer() { public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
// @Override Thread.sleep(10000L);
// public Object answer(InvocationOnMock invocationOnMock) throws Throwable { return null;
// Thread.sleep(10000L); }
// return null; }).when(monitored).stop();
// }
// }).when(monitored).stop(); // max stop timeout is 50 milliseconds
// StopperThread stopper = new StopperThread(monitored, commands, 50L);
// // max stop timeout is 10 milliseconds stopper.start();
// StopperThread stopper = new StopperThread(monitored, commands, 10L); stopper.join();
// stopper.start();
// stopper.join(); verify(monitored).stop();
// // even if stopper was interrupted, stop watching process
// verify(monitored).stop(); verify(commands).endWatch();
// assertThat(file).doesNotExist();
} }
} }

View File

@ -23,8 +23,13 @@ import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import java.io.File; import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.net.URL; import java.net.URL;
import static org.fest.assertions.Assertions.assertThat;
import static org.fest.assertions.Fail.fail;
/** /**
* Utilities for unit tests * Utilities for unit tests
* *
@ -67,4 +72,15 @@ public final class TestUtils {
resourcePath += path; resourcePath += path;
return getResource(resourcePath); 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);
}
}
} }