/* | |||||
* Sonar Standalone Runner | |||||
* Copyright (C) 2011 SonarSource | |||||
* dev@sonar.codehaus.org | |||||
* | |||||
* 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 02 | |||||
*/ | |||||
package org.sonar.runner; | |||||
class Logs { | |||||
private Logs() { | |||||
} | |||||
static void info(String message) { | |||||
System.out.println(message); // NOSONAR | |||||
} | |||||
} |
} | } | ||||
private void execute(String[] args) { | private void execute(String[] args) { | ||||
long startTime = System.currentTimeMillis(); | |||||
Stats stats = new Stats().start(); | |||||
try { | try { | ||||
Properties props = loadProperties(args); | Properties props = loadProperties(args); | ||||
Runner runner = Runner.create(props); | Runner runner = Runner.create(props); | ||||
log("Runner version: " + SonarRunnerVersion.getVersion()); | |||||
log("Java version: " + System.getProperty("java.version", "<unknown java version>") | |||||
+ ", vendor: " + System.getProperty("java.vendor", "<unknown vendor>")); | |||||
log("OS name: \"" + System.getProperty("os.name") + "\", version: \"" + System.getProperty("os.version") + "\", arch: \"" + System.getProperty("os.arch") + "\""); | |||||
Logs.info("Runner version: " + SonarRunnerVersion.getVersion()); | |||||
Logs.info("Java version: " + System.getProperty("java.version", "<unknown>") | |||||
+ ", vendor: " + System.getProperty("java.vendor", "<unknown>")); | |||||
Logs.info("OS name: \"" + System.getProperty("os.name") + "\", version: \"" + System.getProperty("os.version") + "\", arch: \"" + System.getProperty("os.arch") + "\""); | |||||
if (debugMode) { | if (debugMode) { | ||||
log("Other system properties:"); | |||||
log(" - sun.arch.data.model: \"" + System.getProperty("sun.arch.data.model") + "\""); | |||||
Logs.info("Other system properties:"); | |||||
Logs.info(" - sun.arch.data.model: \"" + System.getProperty("sun.arch.data.model") + "\""); | |||||
} | } | ||||
log("Server: " + runner.getSonarServerURL()); | |||||
Logs.info("Server: " + runner.getSonarServerURL()); | |||||
try { | try { | ||||
log("Work directory: " + runner.getWorkDir().getCanonicalPath()); | |||||
Logs.info("Work directory: " + runner.getWorkDir().getCanonicalPath()); | |||||
} catch (IOException e) { | } catch (IOException e) { | ||||
throw new RunnerException(e); | throw new RunnerException(e); | ||||
} | } | ||||
runner.execute(); | runner.execute(); | ||||
} finally { | } finally { | ||||
printStats(startTime); | |||||
stats.stop(); | |||||
} | } | ||||
} | } | ||||
private void printStats(long startTime) { | |||||
long time = System.currentTimeMillis() - startTime; | |||||
log("Total time: " + formatTime(time)); | |||||
System.gc(); | |||||
Runtime r = Runtime.getRuntime(); | |||||
long mb = 1024L * 1024; | |||||
log("Final Memory: " + (r.totalMemory() - r.freeMemory()) / mb + "M/" + r.totalMemory() / mb + "M"); | |||||
} | |||||
@VisibleForTesting | |||||
static String formatTime(long time) { | |||||
long h = time / (60 * 60 * 1000); | |||||
long m = (time - h * 60 * 60 * 1000) / (60 * 1000); | |||||
long s = (time - h * 60 * 60 * 1000 - m * 60 * 1000) / 1000; | |||||
long ms = time % 1000; | |||||
final String format; | |||||
if (h > 0) { | |||||
format = "%1$d:%2$02d:%3$02d.%4$03ds"; | |||||
} else if (m > 0) { | |||||
format = "%2$d:%3$02d.%4$03ds"; | |||||
} else { | |||||
format = "%3$d.%4$03ds"; | |||||
} | |||||
return String.format(format, h, m, s, ms); | |||||
} | |||||
@VisibleForTesting | @VisibleForTesting | ||||
Properties loadProperties(String[] args) { | Properties loadProperties(String[] args) { | ||||
Properties commandLineProps = new Properties(); | Properties commandLineProps = new Properties(); | ||||
Properties loadRunnerProperties(Properties props) { | Properties loadRunnerProperties(Properties props) { | ||||
File settingsFile = locatePropertiesFile(props, RUNNER_HOME, "conf/sonar-runner.properties", RUNNER_SETTINGS); | File settingsFile = locatePropertiesFile(props, RUNNER_HOME, "conf/sonar-runner.properties", RUNNER_SETTINGS); | ||||
if (settingsFile != null && settingsFile.isFile() && settingsFile.exists()) { | if (settingsFile != null && settingsFile.isFile() && settingsFile.exists()) { | ||||
log("Runner configuration file: " + settingsFile.getAbsolutePath()); | |||||
Logs.info("Runner configuration file: " + settingsFile.getAbsolutePath()); | |||||
return toProperties(settingsFile); | return toProperties(settingsFile); | ||||
} else { | |||||
log("Runner configuration file: NONE"); | |||||
} | } | ||||
Logs.info("Runner configuration file: NONE"); | |||||
return new Properties(); | return new Properties(); | ||||
} | } | ||||
private Properties loadProjectProperties(Properties props) { | private Properties loadProjectProperties(Properties props) { | ||||
File settingsFile = locatePropertiesFile(props, PROJECT_HOME, "sonar-project.properties", PROJECT_SETTINGS); | File settingsFile = locatePropertiesFile(props, PROJECT_HOME, "sonar-project.properties", PROJECT_SETTINGS); | ||||
if (settingsFile != null && settingsFile.isFile() && settingsFile.exists()) { | if (settingsFile != null && settingsFile.isFile() && settingsFile.exists()) { | ||||
log("Project configuration file: " + settingsFile.getAbsolutePath()); | |||||
Logs.info("Project configuration file: " + settingsFile.getAbsolutePath()); | |||||
return toProperties(settingsFile); | return toProperties(settingsFile); | ||||
} else { | |||||
log("Project configuration file: NONE"); | |||||
} | } | ||||
Logs.info("Project configuration file: NONE"); | |||||
return new Properties(); | return new Properties(); | ||||
} | } | ||||
printError("Missing argument for option --define"); | printError("Missing argument for option --define"); | ||||
} | } | ||||
arg = args[i]; | arg = args[i]; | ||||
parseProperty(arg, props); | |||||
appendPropertyTo(arg, props); | |||||
} else if (arg.startsWith("-D")) { | } else if (arg.startsWith("-D")) { | ||||
arg = arg.substring(2); | arg = arg.substring(2); | ||||
parseProperty(arg, props); | |||||
appendPropertyTo(arg, props); | |||||
} else { | } else { | ||||
printError("Unrecognized option: " + arg); | printError("Unrecognized option: " + arg); | ||||
} | } | ||||
return props; | return props; | ||||
} | } | ||||
private void parseProperty(String arg, Properties props) { | |||||
private void appendPropertyTo(String arg, Properties props) { | |||||
final String key, value; | final String key, value; | ||||
int j = arg.indexOf('='); | int j = arg.indexOf('='); | ||||
if (j == -1) { | if (j == -1) { | ||||
props.setProperty(key, value); | props.setProperty(key, value); | ||||
} | } | ||||
private void printUsage() { | |||||
log(""); | |||||
log("usage: sonar-runner [options]"); | |||||
log(""); | |||||
log("Options:"); | |||||
log(" -h,--help Display help information"); | |||||
log(" -X,--debug Produce execution debug output"); | |||||
log(" -D,--define <arg> Define property"); | |||||
System.exit(0); // NOSONAR | |||||
} | |||||
private void printError(String message) { | private void printError(String message) { | ||||
log(""); | |||||
log(message); | |||||
Logs.info(""); | |||||
Logs.info(message); | |||||
printUsage(); | printUsage(); | ||||
} | } | ||||
private void log(String message) { | |||||
System.out.println(message); // NOSONAR | |||||
private void printUsage() { | |||||
Logs.info(""); | |||||
Logs.info("usage: sonar-runner [options]"); | |||||
Logs.info(""); | |||||
Logs.info("Options:"); | |||||
Logs.info(" -h,--help Display help information"); | |||||
Logs.info(" -X,--debug Produce execution debug output"); | |||||
Logs.info(" -D,--define <arg> Define property"); | |||||
System.exit(0); // NOSONAR | |||||
} | } | ||||
} | } |
/* | |||||
* Sonar Standalone Runner | |||||
* Copyright (C) 2011 SonarSource | |||||
* dev@sonar.codehaus.org | |||||
* | |||||
* 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 02 | |||||
*/ | |||||
package org.sonar.runner; | |||||
import com.google.common.annotations.VisibleForTesting; | |||||
class Stats { | |||||
private long startTime; | |||||
Stats() { | |||||
} | |||||
Stats start() { | |||||
startTime = System.currentTimeMillis(); | |||||
return this; | |||||
} | |||||
Stats stop() { | |||||
long stopTime = System.currentTimeMillis() - startTime; | |||||
Logs.info("Total time: " + formatTime(stopTime)); | |||||
System.gc(); | |||||
Runtime r = Runtime.getRuntime(); | |||||
long mb = 1024L * 1024; | |||||
Logs.info("Final Memory: " + (r.totalMemory() - r.freeMemory()) / mb + "M/" + r.totalMemory() / mb + "M"); | |||||
return this; | |||||
} | |||||
@VisibleForTesting | |||||
static String formatTime(long time) { | |||||
long h = time / (60 * 60 * 1000); | |||||
long m = (time - h * 60 * 60 * 1000) / (60 * 1000); | |||||
long s = (time - h * 60 * 60 * 1000 - m * 60 * 1000) / 1000; | |||||
long ms = time % 1000; | |||||
final String format; | |||||
if (h > 0) { | |||||
format = "%1$d:%2$02d:%3$02d.%4$03ds"; | |||||
} else if (m > 0) { | |||||
format = "%2$d:%3$02d.%4$03ds"; | |||||
} else { | |||||
format = "%3$d.%4$03ds"; | |||||
} | |||||
return String.format(format, h, m, s, ms); | |||||
} | |||||
} |
import java.io.File; | import java.io.File; | ||||
import java.util.Properties; | import java.util.Properties; | ||||
import static org.hamcrest.CoreMatchers.nullValue; | |||||
import static org.hamcrest.Matchers.is; | |||||
import static org.junit.Assert.assertThat; | |||||
import static org.fest.assertions.Assertions.assertThat; | |||||
public class MainTest { | public class MainTest { | ||||
@Test | @Test | ||||
public void shouldParseEmptyArguments() { | public void shouldParseEmptyArguments() { | ||||
Properties props = new Main().parseArguments(new String[] {}); | |||||
assertThat(props.isEmpty(), is(true)); | |||||
Properties props = new Main().parseArguments(new String[]{}); | |||||
assertThat(props).isEmpty(); | |||||
} | } | ||||
@Test | @Test | ||||
public void shouldParseArguments() { | public void shouldParseArguments() { | ||||
Properties props = new Main().parseArguments(new String[] {"-D", "foo=bar", "--define", "hello=world", "-Dboolean"}); | |||||
assertThat(props.size(), is(3)); | |||||
assertThat(props.getProperty("foo"), is("bar")); | |||||
assertThat(props.getProperty("hello"), is("world")); | |||||
assertThat(props.getProperty("boolean"), is("true")); | |||||
Properties props = new Main().parseArguments(new String[]{"-D", "foo=bar", "--define", "hello=world", "-Dboolean"}); | |||||
assertThat(props).hasSize(3); | |||||
assertThat(props.getProperty("foo")).isEqualTo("bar"); | |||||
assertThat(props.getProperty("hello")).isEqualTo("world"); | |||||
assertThat(props.getProperty("boolean")).isEqualTo("true"); | |||||
} | } | ||||
@Test | @Test | ||||
public void shouldEnableDebugMode() { | public void shouldEnableDebugMode() { | ||||
Properties props = new Main().parseArguments(new String[]{"-X"}); | Properties props = new Main().parseArguments(new String[]{"-X"}); | ||||
assertThat(props.getProperty(Runner.PROPERTY_VERBOSE), is("true")); | |||||
assertThat(props.getProperty(Runner.PROPERTY_VERBOSE)).isEqualTo("true"); | |||||
} | } | ||||
@Test | @Test | ||||
public void shouldDisableDebugModeByDefault() { | public void shouldDisableDebugModeByDefault() { | ||||
Properties props = new Main().parseArguments(new String[]{}); | Properties props = new Main().parseArguments(new String[]{}); | ||||
assertThat(props.getProperty(Runner.PROPERTY_VERBOSE), nullValue()); | |||||
assertThat(props.getProperty(Runner.PROPERTY_VERBOSE)).isNull(); | |||||
} | } | ||||
@Test | @Test | ||||
Properties props = new Main().loadRunnerProperties(args); | Properties props = new Main().loadRunnerProperties(args); | ||||
assertThat(props.getProperty("sonar.host.url"), is("http://moon/sonar")); | |||||
assertThat(props.getProperty("sonar.host.url")).isEqualTo("http://moon/sonar"); | |||||
} | } | ||||
@Test | @Test | ||||
Properties args = new Properties(); | Properties args = new Properties(); | ||||
Properties props = new Main().loadRunnerProperties(args); | Properties props = new Main().loadRunnerProperties(args); | ||||
assertThat(props.isEmpty(), is(true)); | |||||
assertThat(props).isEmpty(); | |||||
} | } | ||||
@Test | @Test | ||||
args.setProperty("runner.settings", settings.getCanonicalPath()); | args.setProperty("runner.settings", settings.getCanonicalPath()); | ||||
Properties props = new Main().loadRunnerProperties(args); | Properties props = new Main().loadRunnerProperties(args); | ||||
assertThat(props.getProperty("sonar.host.url"), is("http://other/sonar")); | |||||
assertThat(props.getProperty("sonar.host.url")).isEqualTo("http://other/sonar"); | |||||
} | } | ||||
@Test | @Test | ||||
"-D", "project.home=" + projectHome.getCanonicalPath() | "-D", "project.home=" + projectHome.getCanonicalPath() | ||||
}); | }); | ||||
assertThat(props.getProperty("project.prop"), is("foo")); | |||||
assertThat(props.getProperty("overridden.prop"), is("project scope")); | |||||
assertThat(props.getProperty("global.prop"), is("jdbc:mysql:localhost/sonar")); | |||||
assertThat(props.getProperty("project.prop")).isEqualTo("foo"); | |||||
assertThat(props.getProperty("overridden.prop")).isEqualTo("project scope"); | |||||
assertThat(props.getProperty("global.prop")).isEqualTo("jdbc:mysql:localhost/sonar"); | |||||
} | } | ||||
@Test | |||||
public void shouldFormatTime() { | |||||
assertThat(Main.formatTime(1 * 60 * 60 * 1000 + 2 * 60 * 1000 + 3 * 1000 + 400), is("1:02:03.400s")); | |||||
assertThat(Main.formatTime(2 * 60 * 1000 + 3 * 1000 + 400), is("2:03.400s")); | |||||
assertThat(Main.formatTime(3 * 1000 + 400), is("3.400s")); | |||||
assertThat(Main.formatTime(400), is("0.400s")); | |||||
} | |||||
} | } |
/* | |||||
* Sonar Standalone Runner | |||||
* Copyright (C) 2011 SonarSource | |||||
* dev@sonar.codehaus.org | |||||
* | |||||
* 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 02 | |||||
*/ | |||||
package org.sonar.runner; | |||||
import org.junit.Test; | |||||
import static org.fest.assertions.Assertions.assertThat; | |||||
public class StatsTest { | |||||
@Test | |||||
public void shouldPrintStats() { | |||||
new Stats().start().stop(); | |||||
//TODO mock Logs | |||||
} | |||||
@Test | |||||
public void shouldFormatTime() { | |||||
assertThat(Stats.formatTime(1 * 60 * 60 * 1000 + 2 * 60 * 1000 + 3 * 1000 + 400)).isEqualTo("1:02:03.400s"); | |||||
assertThat(Stats.formatTime(2 * 60 * 1000 + 3 * 1000 + 400)).isEqualTo("2:03.400s"); | |||||
assertThat(Stats.formatTime(3 * 1000 + 400)).isEqualTo("3.400s"); | |||||
assertThat(Stats.formatTime(400)).isEqualTo("0.400s"); | |||||
} | |||||
} |