aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJenkins CI <ci@sonarsource.com>2014-09-25 23:43:35 +0200
committerJenkins CI <ci@sonarsource.com>2014-09-25 23:43:35 +0200
commitb685462248789067942332c9bc584c21544756ff (patch)
tree777ae9e54e582066e48afc1fbbcd1256ab935520
parent48d48e90931782cc1e94768a83ada71275476ceb (diff)
parentea1ac3789b9128e394284d82dfeaeab32dd441d8 (diff)
downloadsonarqube-b685462248789067942332c9bc584c21544756ff.tar.gz
sonarqube-b685462248789067942332c9bc584c21544756ff.zip
Automatic merge from branch-4.5
* origin/branch-4.5: SONAR-4898 add missing tests SONAR-4898 add missing tests Use correct temp dir for Ruby on Rails app Fail server startup if can not connect to DB
-rw-r--r--server/sonar-process/pom.xml14
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java1
-rw-r--r--server/sonar-process/src/main/java/org/sonar/process/StopWatcher.java12
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/ConfigurationUtilsTest.java6
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/LoopbackAddressTest.java6
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/NetworkUtilsTest.java19
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java39
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/ProcessUtilsTest.java31
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/PropsTest.java36
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/StopWatcherTest.java59
-rw-r--r--server/sonar-process/src/test/java/org/sonar/process/StopperThreadTest.java70
-rw-r--r--server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb2
-rw-r--r--sonar-application/pom.xml14
-rw-r--r--sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java6
-rw-r--r--sonar-core/src/main/java/org/sonar/core/persistence/DefaultDatabase.java4
-rw-r--r--sonar-testing-harness/src/main/java/org/sonar/test/TestUtils.java16
16 files changed, 243 insertions, 92 deletions
diff --git a/server/sonar-process/pom.xml b/server/sonar-process/pom.xml
index 25916e9ae41..387e5ecc519 100644
--- a/server/sonar-process/pom.xml
+++ b/server/sonar-process/pom.xml
@@ -41,13 +41,8 @@
</dependency>
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.easytesting</groupId>
- <artifactId>fest-assert</artifactId>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-testing-harness</artifactId>
<scope>test</scope>
</dependency>
<dependency>
@@ -56,11 +51,6 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-all</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>test</scope>
diff --git a/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java b/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java
index d79f0f92899..1c7af0c004e 100644
--- a/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java
+++ b/server/sonar-process/src/main/java/org/sonar/process/ProcessCommands.java
@@ -52,6 +52,7 @@ public class ProcessCommands {
this.stopFile = new File(directory, processKey + ".stop");
}
+ // visible for tests
ProcessCommands(File readyFile, File stopFile) {
this.readyFile = readyFile;
this.stopFile = stopFile;
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
+ * &lt;process_key&gt;.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/ProcessCommandsTest.java b/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java
index e81a537e2ee..984fbed74f7 100644
--- a/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java
+++ b/server/sonar-process/src/test/java/org/sonar/process/ProcessCommandsTest.java
@@ -37,7 +37,20 @@ public class ProcessCommandsTest {
public TemporaryFolder temp = new TemporaryFolder();
@Test
- public void delete_files_on_monitor_startup() throws Exception {
+ public void fail_to_init_if_dir_does_not_exist() throws Exception {
+ File dir = temp.newFolder();
+ FileUtils.deleteQuietly(dir);
+
+ try {
+ new ProcessCommands(dir, "web");
+ fail();
+ } catch (IllegalArgumentException e) {
+ assertThat(e).hasMessage("Not a valid directory: " + dir.getAbsolutePath());
+ }
+ }
+
+ @Test
+ public void delete_files_on_prepare() throws Exception {
File dir = temp.newFolder();
assertThat(dir).exists();
FileUtils.touch(new File(dir, "web.ready"));
@@ -67,18 +80,32 @@ public class ProcessCommandsTest {
@Test
public void child_process_create_file_when_ready() throws Exception {
- File readyFile = temp.newFile();
+ File dir = temp.newFolder();
- ProcessCommands commands = new ProcessCommands(readyFile, temp.newFile());
+ ProcessCommands commands = new ProcessCommands(dir, "web");
commands.prepare();
assertThat(commands.isReady()).isFalse();
- assertThat(readyFile).doesNotExist();
+ assertThat(commands.getReadyFile()).doesNotExist();
commands.setReady();
assertThat(commands.isReady()).isTrue();
- assertThat(readyFile).exists();
+ assertThat(commands.getReadyFile()).exists().isFile();
commands.endWatch();
- assertThat(readyFile).doesNotExist();
+ assertThat(commands.getReadyFile()).doesNotExist();
+ }
+
+ @Test
+ public void ask_for_stop() throws Exception {
+ File dir = temp.newFolder();
+
+ ProcessCommands commands = new ProcessCommands(dir, "web");
+ assertThat(commands.askedForStop()).isFalse();
+ assertThat(commands.getStopFile()).doesNotExist();
+
+ commands.askForStop();
+ assertThat(commands.askedForStop()).isTrue();
+ assertThat(commands.getStopFile()).exists().isFile();
+ assertThat(commands.getStopFile().getName()).isEqualTo("web.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
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/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb b/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb
index 986137d1976..81f897e66a3 100644
--- a/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb
+++ b/server/sonar-web/src/main/webapp/WEB-INF/config/environment.rb
@@ -72,7 +72,7 @@ Rails::Initializer.run do |config|
# The development mode (real-time edition of ruby code) can be enabled on an app by replacing the
# following line by :
# config.plugin_paths << '/absolute/path/to/myproject/src/main/resources/org/sonar/ror'
- config.plugin_paths << "#{Java::OrgSonarServerUi::JRubyFacade.getInstance().getServerHome()}/temp/ror"
+ config.plugin_paths << "#{Java::JavaLang::System.getProperty("java.io.tmpdir")}/ror"
# Force all environments to use the same logger level
# (by default production uses :info, the others :debug)
diff --git a/sonar-application/pom.xml b/sonar-application/pom.xml
index 547bff09e2d..b054c0bd128 100644
--- a/sonar-application/pom.xml
+++ b/sonar-application/pom.xml
@@ -154,18 +154,8 @@
<!-- unit tests -->
<dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.hamcrest</groupId>
- <artifactId>hamcrest-all</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.easytesting</groupId>
- <artifactId>fest-assert</artifactId>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-testing-harness</artifactId>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java b/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java
index 11bcb2f5631..49a66bc590c 100644
--- a/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java
+++ b/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java
@@ -21,6 +21,7 @@ package org.sonar.application;
import org.junit.Test;
import org.sonar.process.Props;
+import org.sonar.test.TestUtils;
import java.util.Properties;
@@ -56,4 +57,9 @@ public class DefaultSettingsTest {
DefaultSettings.init(props);
assertThat(props.valueAsInt("sonar.search.port")).isGreaterThan(0);
}
+
+ @Test
+ public void private_constructor() throws Exception {
+ TestUtils.assertPrivateConstructor(DefaultSettings.class);
+ }
}
diff --git a/sonar-core/src/main/java/org/sonar/core/persistence/DefaultDatabase.java b/sonar-core/src/main/java/org/sonar/core/persistence/DefaultDatabase.java
index d8a0dadc24b..50e7a54790a 100644
--- a/sonar-core/src/main/java/org/sonar/core/persistence/DefaultDatabase.java
+++ b/sonar-core/src/main/java/org/sonar/core/persistence/DefaultDatabase.java
@@ -111,8 +111,8 @@ public class DefaultDatabase implements Database {
try {
LOG.debug("Testing JDBC connection");
connection = datasource.getConnection();
- } catch (Exception e) {
- LOG.error("Can not connect to database. Please check connectivity and settings (see the properties prefixed by 'sonar.jdbc.').", e);
+ } catch (SQLException e) {
+ throw new IllegalStateException("Can not connect to database. Please check connectivity and settings (see the properties prefixed by 'sonar.jdbc.').", e);
} finally {
DbUtils.closeQuietly(connection);
}
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);
+ }
+ }
}