diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-07-28 23:07:45 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2014-07-28 23:07:45 +0200 |
commit | a570bd8448809fd4cf4ef9a86dfdd2dfcce33e6d (patch) | |
tree | cc3e376781aa842aed482a1e46bb328f8d5fe011 /sonar-application/src | |
parent | 2702b09f74bfbbf78bfadcd48d6ce3ef3ff42f4c (diff) | |
download | sonarqube-a570bd8448809fd4cf4ef9a86dfdd2dfcce33e6d.tar.gz sonarqube-a570bd8448809fd4cf4ef9a86dfdd2dfcce33e6d.zip |
SONAR-4898 add missing tests, fix loading of default settings and check Java6+
Diffstat (limited to 'sonar-application/src')
7 files changed, 318 insertions, 53 deletions
diff --git a/sonar-application/src/main/java/org/sonar/application/App.java b/sonar-application/src/main/java/org/sonar/application/App.java index 71e84c4e585..fea8916ccbe 100644 --- a/sonar-application/src/main/java/org/sonar/application/App.java +++ b/sonar-application/src/main/java/org/sonar/application/App.java @@ -82,7 +82,7 @@ public class App implements ProcessMXBean { .addJavaOpts(String.format("-Djava.io.tmpdir=%s", installation.tempDir().getAbsolutePath())) .addJavaOpts(String.format("-D%s=%s", DefaultSettings.PATH_LOGS_KEY, installation.logsDir().getAbsolutePath())) .setClassName("org.sonar.search.ElasticSearch") - .setProperties(installation.props().cryptedProperties()) + .setProperties(installation.props().encryptedProperties()) .addClasspath(installation.starPath("lib/common")) .addClasspath(installation.starPath("lib/search")) .execute(); @@ -98,7 +98,7 @@ public class App implements ProcessMXBean { .addJavaOpts(String.format("-Djava.io.tmpdir=%s", installation.tempDir().getAbsolutePath())) .addJavaOpts(String.format("-D%s=%s", DefaultSettings.PATH_LOGS_KEY, installation.logsDir().getAbsolutePath())) .setClassName("org.sonar.server.app.ServerProcess") - .setProperties(installation.props().cryptedProperties()) + .setProperties(installation.props().encryptedProperties()) .addClasspath(installation.starPath("extensions/jdbc-driver/mysql")) .addClasspath(installation.starPath("extensions/jdbc-driver/mssql")) .addClasspath(installation.starPath("extensions/jdbc-driver/oracle")) diff --git a/sonar-application/src/main/java/org/sonar/application/Installation.java b/sonar-application/src/main/java/org/sonar/application/Installation.java index ddba3465361..a55dc7325d0 100644 --- a/sonar-application/src/main/java/org/sonar/application/Installation.java +++ b/sonar-application/src/main/java/org/sonar/application/Installation.java @@ -34,15 +34,26 @@ import java.net.URISyntaxException; import java.util.Properties; public class Installation { - private final File homeDir; - private final File tempDir, logsDir; - private final Props props; + private File homeDir, tempDir, logsDir; + private Props props; public Installation() throws URISyntaxException, IOException { - // home dir guessed with location of lib/sonar-application.jar - homeDir = detectHomeDir(); + Properties systemProperties = new Properties(); + systemProperties.putAll(System.getenv()); + systemProperties.putAll(System.getProperties()); - props = initProps(homeDir); + init(new SystemChecks(), detectHomeDir(), systemProperties); + } + + Installation(SystemChecks systemChecks, File homeDir, Properties systemProperties) throws URISyntaxException, IOException { + init(systemChecks, homeDir, systemProperties); + } + + void init(SystemChecks systemChecks, File homeDir, Properties systemProperties) throws URISyntaxException, IOException { + systemChecks.checkJavaVersion(); + + this.homeDir = homeDir; + props = initProps(homeDir, systemProperties); DefaultSettings.initDefaults(props); // init file system @@ -52,7 +63,7 @@ public class Installation { this.logsDir = initExistingDir("sonar.path.logs", "logs"); } - public File detectHomeDir() throws URISyntaxException { + private File detectHomeDir() throws URISyntaxException { File appJar = new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI()); return appJar.getParentFile().getParentFile(); } @@ -60,7 +71,7 @@ public class Installation { /** * Load conf/sonar.properties */ - private static Props initProps(File homeDir) throws IOException { + private static Props initProps(File homeDir, Properties systemProperties) throws IOException { Properties p = new Properties(); File propsFile = new File(homeDir, "conf/sonar.properties"); if (propsFile.exists()) { @@ -71,8 +82,7 @@ public class Installation { IOUtils.closeQuietly(reader); } } - p.putAll(System.getenv()); - p.putAll(System.getProperties()); + p.putAll(systemProperties); p.setProperty("sonar.path.home", homeDir.getAbsolutePath()); return new Props(p); } @@ -109,10 +119,12 @@ public class Installation { private File initExistingDir(String propKey, String defaultRelativePath) throws IOException { File dir = configuredDir(propKey, defaultRelativePath); if (!dir.exists()) { - throw new IllegalStateException(String.format("Directory does not exist: %s. Please check property %s", dir.getAbsolutePath(), propKey)); + throw new IllegalStateException(String.format("Property '%s' is not valid, directory does not exist: %s", + propKey, dir.getAbsolutePath())); } if (!dir.isDirectory()) { - throw new IllegalStateException(String.format("Not a directory: %s. Please check property %s", dir.getAbsolutePath(), propKey)); + throw new IllegalStateException(String.format("Property '%s' is not valid, not a directory: %s", + propKey, dir.getAbsolutePath())); } return dir; } diff --git a/sonar-application/src/main/java/org/sonar/application/SystemChecks.java b/sonar-application/src/main/java/org/sonar/application/SystemChecks.java new file mode 100644 index 00000000000..7a7bd7b95b1 --- /dev/null +++ b/sonar-application/src/main/java/org/sonar/application/SystemChecks.java @@ -0,0 +1,35 @@ +/* + * 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.application; + +class SystemChecks { + + void checkJavaVersion() { + String javaVersion = System.getProperty("java.version"); + checkJavaVersion(javaVersion); + } + + void checkJavaVersion(String javaVersion) { + if (javaVersion.startsWith("1.3") || javaVersion.startsWith("1.4") || javaVersion.startsWith("1.5")) { + // still better than "java.lang.UnsupportedClassVersionError: Unsupported major.minor version 49.0 + throw new IllegalStateException("Minimal required Java version if 1.6. Got: " + javaVersion); + } + } +} diff --git a/sonar-application/src/test/java/org/sonar/application/AppTest.java b/sonar-application/src/test/java/org/sonar/application/AppTest.java index fcb06697985..de1eb77584c 100644 --- a/sonar-application/src/test/java/org/sonar/application/AppTest.java +++ b/sonar-application/src/test/java/org/sonar/application/AppTest.java @@ -57,43 +57,43 @@ public class AppTest { sonarHome.delete(); } - @Test - @Ignore - public void should_register_mbean() throws Exception { - Installation installation = mock(Installation.class); - when(installation.detectHomeDir()).thenReturn(sonarHome.getRoot()); - - MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); - - App server = new App(installation); - - // 0 Can have a valid ObjectName - assertThat(server).isNotNull(); - - // 1 assert that process MBean is registered - ObjectName serverObjectName = Process.objectNameFor(App.PROCESS_NAME); - assertThat(mbeanServer.isRegistered(serverObjectName)).isTrue(); - - // 2 assert that we can remotely call ping - Long now = System.currentTimeMillis(); - Long ping = (Long) mbeanServer.invoke(serverObjectName, ProcessMXBean.PING, null, null); - assertThat(ping).isNotNull(); - assertThat(ping - now).isLessThanOrEqualTo(3000L); - - // 3 assert that we can remotely call isReady - //TODO this method is for some reason not available... -// Boolean isReady = (Boolean) mbeanServer.invoke(serverObjectName, ProcessMXBean.IS_READY, null, null); -// assertThat(isReady).isFalse(); - - // 4 assert that we can remotely call terminate - mbeanServer.invoke(serverObjectName, ProcessMXBean.TERMINATE, null, null); - - // 5 assert that we can remotely call terminate - try { - mbeanServer.invoke(serverObjectName, "xoxo", null, null); - fail(); - } catch (Exception e) { - assertThat(e.getMessage()).isEqualTo("No such operation: xoxo"); - } - } +// @Test +// @Ignore +// public void should_register_mbean() throws Exception { +// Installation installation = mock(Installation.class); +// when(installation.detectHomeDir()).thenReturn(sonarHome.getRoot()); +// +// MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer(); +// +// App server = new App(installation); +// +// // 0 Can have a valid ObjectName +// assertThat(server).isNotNull(); +// +// // 1 assert that process MBean is registered +// ObjectName serverObjectName = Process.objectNameFor(App.PROCESS_NAME); +// assertThat(mbeanServer.isRegistered(serverObjectName)).isTrue(); +// +// // 2 assert that we can remotely call ping +// Long now = System.currentTimeMillis(); +// Long ping = (Long) mbeanServer.invoke(serverObjectName, ProcessMXBean.PING, null, null); +// assertThat(ping).isNotNull(); +// assertThat(ping - now).isLessThanOrEqualTo(3000L); +// +// // 3 assert that we can remotely call isReady +// //TODO this method is for some reason not available... +//// Boolean isReady = (Boolean) mbeanServer.invoke(serverObjectName, ProcessMXBean.IS_READY, null, null); +//// assertThat(isReady).isFalse(); +// +// // 4 assert that we can remotely call terminate +// mbeanServer.invoke(serverObjectName, ProcessMXBean.TERMINATE, null, null); +// +// // 5 assert that we can remotely call terminate +// try { +// mbeanServer.invoke(serverObjectName, "xoxo", null, null); +// fail(); +// } catch (Exception e) { +// assertThat(e.getMessage()).isEqualTo("No such operation: xoxo"); +// } +// } } diff --git a/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java b/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java new file mode 100644 index 00000000000..3229d251c9e --- /dev/null +++ b/sonar-application/src/test/java/org/sonar/application/DefaultSettingsTest.java @@ -0,0 +1,61 @@ +/* + * 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.application; + +import org.junit.Test; +import org.sonar.process.Props; + +import java.util.Properties; + +import static org.fest.assertions.Assertions.assertThat; + +public class DefaultSettingsTest { + + @Test + public void initDefaults() throws Exception { + Props props = new Props(new Properties()); + DefaultSettings.initDefaults(props); + + assertThat(props.of("sonar.search.javaOpts")).contains("-Xmx"); + assertThat(props.intOf("sonar.web.jmxPort")).isEqualTo(9003); + assertThat(props.intOf("sonar.search.jmxPort")).isEqualTo(9002); + assertThat(props.of("sonar.jdbc.username")).isEqualTo("sonar"); + } + + @Test + public void do_not_override_existing_properties() throws Exception { + Properties p = new Properties(); + p.setProperty("sonar.jdbc.username", "angela"); + Props props = new Props(p); + DefaultSettings.initDefaults(props); + + assertThat(props.of("sonar.jdbc.username")).isEqualTo("angela"); + } + + @Test + public void use_random_port_if_zero() throws Exception { + Properties p = new Properties(); + p.setProperty("sonar.search.jmxPort", "0"); + Props props = new Props(p); + + DefaultSettings.initDefaults(props); + assertThat(props.intOf("sonar.web.jmxPort")).isGreaterThan(0); + } +} diff --git a/sonar-application/src/test/java/org/sonar/application/InstallationTest.java b/sonar-application/src/test/java/org/sonar/application/InstallationTest.java new file mode 100644 index 00000000000..a2a2373606f --- /dev/null +++ b/sonar-application/src/test/java/org/sonar/application/InstallationTest.java @@ -0,0 +1,113 @@ +/* + * 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.application; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.junit.Before; +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; +import static org.fest.assertions.Fail.fail; + +public class InstallationTest { + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + File homeDir, dataDir, webDir, logsDir; + + @Before + public void before() throws IOException { + homeDir = temp.newFolder(); + dataDir = new File(homeDir, "data"); + webDir = new File(homeDir, "web"); + logsDir = new File(homeDir, "logs"); + } + + @Test + public void check_minimum_viable_environment() throws Exception { + FileUtils.forceMkdir(dataDir); + FileUtils.forceMkdir(webDir); + FileUtils.forceMkdir(logsDir); + + Properties initialProps = new Properties(); + initialProps.setProperty("foo", "bar"); + Installation installation = new Installation(new SystemChecks(), homeDir, initialProps); + assertThat(installation.logsDir()).isEqualTo(logsDir); + assertThat(installation.homeDir()).isEqualTo(homeDir); + + // create <HOME>/temp + assertThat(installation.tempDir()).isDirectory().exists(); + assertThat(installation.tempDir().getName()).isEqualTo("temp"); + assertThat(installation.tempDir().getParentFile()).isEqualTo(homeDir); + + String startPath = installation.starPath("lib/search"); + assertThat(FilenameUtils.normalize(startPath, true)) + .endsWith("*") + .startsWith(FilenameUtils.normalize(homeDir.getAbsolutePath(), true)); + + assertThat(installation.props()).isNotNull(); + assertThat(installation.prop("foo")).isEqualTo("bar"); + assertThat(installation.prop("unknown")).isNull(); + assertThat(installation.prop("default", "value")).isEqualTo("value"); + assertThat(installation.prop("sonar.path.home")).isEqualTo(homeDir.getAbsolutePath()); + } + + @Test + public void fail_if_missing_required_directory() throws Exception { + // <home>/data is missing + FileUtils.forceMkdir(webDir); + FileUtils.forceMkdir(logsDir); + + File dataDir = new File(homeDir, "data"); + try { + new Installation(new SystemChecks(), homeDir, new Properties()); + fail(); + } catch (IllegalStateException e) { + assertThat(e.getMessage()).startsWith("Property 'sonar.path.data' is not valid, directory does not exist: " + dataDir.getAbsolutePath()); + } + + try { + FileUtils.touch(dataDir); + new Installation(new SystemChecks(), homeDir, new Properties()); + fail(); + } catch (IllegalStateException e) { + assertThat(e.getMessage()).startsWith("Property 'sonar.path.data' is not valid, not a directory: " + dataDir.getAbsolutePath()); + } + } + + @Test + public void load_properties_file_if_exists() throws Exception { + FileUtils.write(new File(homeDir, "conf/sonar.properties"), "sonar.jdbc.username=angela"); + FileUtils.forceMkdir(dataDir); + FileUtils.forceMkdir(webDir); + FileUtils.forceMkdir(logsDir); + + Installation installation = new Installation(new SystemChecks(), homeDir, new Properties()); + assertThat(installation.prop("sonar.jdbc.username")).isEqualTo("angela"); + } +} diff --git a/sonar-application/src/test/java/org/sonar/application/SystemChecksTest.java b/sonar-application/src/test/java/org/sonar/application/SystemChecksTest.java new file mode 100644 index 00000000000..e0c7dd15b5f --- /dev/null +++ b/sonar-application/src/test/java/org/sonar/application/SystemChecksTest.java @@ -0,0 +1,44 @@ +/* + * 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.application; + +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; +import static org.fest.assertions.Fail.fail; + +public class SystemChecksTest { + + @Test + public void checkJavaVersion() throws Exception { + SystemChecks checks = new SystemChecks(); + + // yes, sources are compiled with a supported Java version! + checks.checkJavaVersion(); + + checks.checkJavaVersion("1.6.1_b2"); + try { + checks.checkJavaVersion("1.5.2"); + fail(); + } catch (IllegalStateException e) { + assertThat(e).hasMessage("Minimal required Java version if 1.6. Got: 1.5.2"); + } + } +} |