Browse Source

SONARPLUGINS-2217 Move Sonar Batch Bootstrapper classes from Sonar to Sonar Runner

tags/2.5-rc1
Fabrice Bellingard 11 years ago
parent
commit
80971d59f5

+ 0
- 6
pom.xml View File

@@ -60,12 +60,6 @@
</properties>

<dependencies>
<!-- Would be embedded in final JAR -->
<dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-batch-bootstrapper</artifactId>
<version>${sonar.buildVersion}</version>
</dependency>
<!-- Would be available after bootstrapping -->
<dependency>
<groupId>ch.qos.logback</groupId>

+ 1
- 1
src/main/assembly/bin/sonar-runner View File

@@ -22,7 +22,7 @@ else
fi

JAVA_CMD="`which java`"
JAVA_CLASSPATH="${SONAR_RUNNER_HOME}"/lib/sonar-runner.jar:"${SONAR_RUNNER_HOME}"/lib/sonar-batch-bootstrapper.jar
JAVA_CLASSPATH="${SONAR_RUNNER_HOME}"/lib/sonar-runner.jar
PROJECT_HOME=`pwd`

#echo "Info: Using sonar-runner at $SONAR_RUNNER_HOME"

+ 1
- 1
src/main/assembly/bin/sonar-runner.bat View File

@@ -70,7 +70,7 @@ echo %SONAR_RUNNER_HOME%

set PROJECT_HOME=%CD%

%JAVA_EXEC% %SONAR_RUNNER_OPTS% -classpath "%SONAR_RUNNER_HOME%\lib\sonar-runner.jar";"%SONAR_RUNNER_HOME%\lib\sonar-batch-bootstrapper.jar" "-Drunner.home=%SONAR_RUNNER_HOME%" "-Dproject.home=%PROJECT_HOME%" org.sonar.runner.Main %*
%JAVA_EXEC% %SONAR_RUNNER_OPTS% -classpath "%SONAR_RUNNER_HOME%\lib\sonar-runner.jar" "-Drunner.home=%SONAR_RUNNER_HOME%" "-Dproject.home=%PROJECT_HOME%" org.sonar.runner.Main %*




+ 18
- 10
src/main/java/org/sonar/runner/Launcher.java View File

@@ -23,6 +23,7 @@ package org.sonar.runner;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
import com.google.common.annotations.VisibleForTesting;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.EnvironmentConfiguration;
@@ -37,29 +38,28 @@ import org.sonar.batch.Batch;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
import org.sonar.runner.model.SonarProjectBuilder;

import java.io.File;
import java.io.InputStream;
import java.util.Properties;

/**
* Contrary to {@link org.sonar.runner.Runner}, this class is executed within the classloader
* provided by the server. It contains the installed plugins and the same version of sonar-batch as the server.
*
* TODO : instead of depending on Runner, that is not in the same classloader, we could simply use Properties :
* sonar.runner.version, sonar.runner.debug, sonar.runner.projectDir, sonar.runner.workDir and all the
* other properties.
*/
public class Launcher {

private Runner runner;
private Properties propertiesFromRunner;

public Launcher(Runner runner) {
this.runner = runner;
public Launcher(Properties properties) {
this.propertiesFromRunner = properties;
}

/**
* This method invoked from {@link Main}. Do not rename it.
*/
public void execute() {
ProjectDefinition project = SonarProjectBuilder.create(runner.getProjectDir(), runner.getProperties()).generateProjectDefinition();
File baseDir = new File(propertiesFromRunner.getProperty(Runner.PROPERTY_PROJECT_DIR));
ProjectDefinition project = SonarProjectBuilder.create(baseDir, propertiesFromRunner).generateProjectDefinition();
Configuration initialConfiguration = getInitialConfiguration(project);
initLogging(initialConfiguration);
executeBatch(project, initialConfiguration);
@@ -67,7 +67,8 @@ public class Launcher {

private void executeBatch(ProjectDefinition project, Configuration initialConfiguration) {
ProjectReactor reactor = new ProjectReactor(project);
Batch batch = Batch.create(reactor, initialConfiguration, new EnvironmentInformation("Runner", runner.getRunnerVersion()));
String runnerVersion = propertiesFromRunner.getProperty(Runner.PROPERTY_RUNNER_VERSION);
Batch batch = Batch.create(reactor, initialConfiguration, new EnvironmentInformation("Runner", runnerVersion));
batch.execute();
}

@@ -77,7 +78,7 @@ public class Launcher {
jc.setContext(context);
context.reset();
InputStream input = Batch.class.getResourceAsStream("/org/sonar/batch/logback.xml");
System.setProperty("ROOT_LOGGER_LEVEL", runner.isDebug() ? "DEBUG" : "INFO");
System.setProperty("ROOT_LOGGER_LEVEL", isDebug() ? "DEBUG" : "INFO");
context.putProperty("SQL_LOGGER_LEVEL", getSqlLevel(initialConfiguration));// since 2.14. Ignored on previous versions.
context.putProperty("SQL_RESULTS_LOGGER_LEVEL", getSqlResultsLevel(initialConfiguration));// since 2.14. Ignored on previous versions.
try {
@@ -91,11 +92,18 @@ public class Launcher {
}
}

@VisibleForTesting
protected boolean isDebug() {
return Boolean.parseBoolean(propertiesFromRunner.getProperty(Runner.PROPERTY_VERBOSE, propertiesFromRunner.getProperty(Runner.PROPERTY_OLD_DEBUG_MODE, "false")));
}

@VisibleForTesting
protected static String getSqlLevel(Configuration config) {
boolean showSql = config.getBoolean("sonar.showSql", false);
return showSql ? "DEBUG" : "WARN";
}

@VisibleForTesting
protected static String getSqlResultsLevel(Configuration config) {
boolean showSql = config.getBoolean("sonar.showSqlResults", false);
return showSql ? "DEBUG" : "WARN";

+ 2
- 2
src/main/java/org/sonar/runner/Main.java View File

@@ -20,8 +20,8 @@

package org.sonar.runner;

import org.sonar.batch.bootstrapper.BootstrapException;
import org.sonar.batch.bootstrapper.BootstrapperIOUtils;
import org.sonar.runner.bootstrapper.BootstrapException;
import org.sonar.runner.bootstrapper.BootstrapperIOUtils;

import java.io.File;
import java.io.FileInputStream;

+ 13
- 15
src/main/java/org/sonar/runner/Runner.java View File

@@ -19,10 +19,10 @@
*/
package org.sonar.runner;

import org.sonar.batch.bootstrapper.BootstrapClassLoader;
import org.sonar.batch.bootstrapper.BootstrapException;
import org.sonar.batch.bootstrapper.Bootstrapper;
import org.sonar.batch.bootstrapper.BootstrapperIOUtils;
import org.sonar.runner.bootstrapper.BootstrapClassLoader;
import org.sonar.runner.bootstrapper.BootstrapException;
import org.sonar.runner.bootstrapper.Bootstrapper;
import org.sonar.runner.bootstrapper.BootstrapperIOUtils;

import java.io.File;
import java.io.IOException;
@@ -37,11 +37,15 @@ import java.util.Properties;
* @since 1.1
*/
public final class Runner {

public static final String PROPERTY_PROJECT_DIR = "sonar.runner.projectDir";
public static final String PROPERTY_RUNNER_VERSION = "sonar.runner.version";

/**
* @deprecated Replaced by sonar.verbose since 1.2
*/
@Deprecated
public static final String DEBUG_MODE = "runner.debug";
public static final String PROPERTY_OLD_DEBUG_MODE = "runner.debug";

/**
* @since 1.2
@@ -109,6 +113,8 @@ public final class Runner {
if (!projectDir.isDirectory() || !projectDir.exists()) {
throw new IllegalArgumentException("Project home must be an existing directory: " + path);
}
// project home exist, add its absolute path as "sonar.runner.projectDir" property
properties.put(PROPERTY_PROJECT_DIR, projectDir.getAbsolutePath());
workDir = initWorkDir();
}

@@ -145,10 +151,6 @@ public final class Runner {
return properties;
}

public boolean isDebug() {
return Boolean.parseBoolean(properties.getProperty(PROPERTY_VERBOSE, properties.getProperty(DEBUG_MODE, "false")));
}

public String getRunnerVersion() {
InputStream in = null;
try {
@@ -201,12 +203,8 @@ public final class Runner {
try {
Thread.currentThread().setContextClassLoader(sonarClassLoader);
Class<?> launcherClass = sonarClassLoader.findClass("org.sonar.runner.Launcher");
// TODO: hack to instantiate SonarProjectBuilder in this classloader otherwise it will be found in the parent one, where no deps are
// available
sonarClassLoader.findClass("org.sonar.runner.model.SonarProjectBuilder");
// END of hack
Constructor<?> constructor = launcherClass.getConstructor(Runner.class);
Object launcher = constructor.newInstance(this);
Constructor<?> constructor = launcherClass.getConstructor(Properties.class);
Object launcher = constructor.newInstance(getProperties());
Method method = launcherClass.getMethod("execute");
method.invoke(launcher);
} catch (InvocationTargetException e) {

+ 121
- 0
src/main/java/org/sonar/runner/bootstrapper/BootstrapClassLoader.java View File

@@ -0,0 +1,121 @@
/*
* 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.bootstrapper;

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;

/**
* Special {@link URLClassLoader} to execute Sonar, which restricts loading from parent.
*/
public class BootstrapClassLoader extends URLClassLoader {

private final String[] unmaskedPackages;

public BootstrapClassLoader(ClassLoader parent, String... unmaskedPackages) {
super(new URL[0], parent);
this.unmaskedPackages = unmaskedPackages;
}

/**
* {@inheritDoc} Visibility of a method has been relaxed to public.
*/
@Override
public void addURL(URL url) {
super.addURL(url);
}

/**
* {@inheritDoc} Visibility of a method has been relaxed to public.
*/
@Override
public Class<?> findClass(String name) throws ClassNotFoundException {
return super.findClass(name);
}

/**
* @return true, if class can be loaded from parent ClassLoader
*/
boolean canLoadFromParent(String name) {
for (String pkg : unmaskedPackages) {
if (name.startsWith(pkg + ".")) {
return true;
}
}
return false;
}

/**
* Same behavior as in {@link URLClassLoader#loadClass(String, boolean)}, except loading from parent.
*/
@Override
protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
// First, check if the class has already been loaded
Class<?> c = findLoadedClass(name);
if (c == null) {
try {
// Load from parent
if (getParent() != null && canLoadFromParent(name)) {
c = getParent().loadClass(name);
} else {
// Load from system

// I don't know for other vendors, but for Oracle JVM :
// - ClassLoader.getSystemClassLoader() is sun.misc.Launcher$AppClassLoader. It contains app classpath.
// - ClassLoader.getSystemClassLoader().getParent() is sun.misc.Launcher$ExtClassLoader. It contains core JVM
ClassLoader systemClassLoader = getSystemClassLoader();
if (systemClassLoader.getParent() != null) {
systemClassLoader = systemClassLoader.getParent();
}
c = systemClassLoader.loadClass(name);
}
} catch (ClassNotFoundException e) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}

/**
* Unlike {@link URLClassLoader#getResource(String)} don't return resource from parent.
* See http://jira.codehaus.org/browse/SONAR-2276
*/
@Override
public URL getResource(String name) {
return findResource(name);
}

/**
* Unlike {@link URLClassLoader#getResources(String)} don't return resources from parent.
* See http://jira.codehaus.org/browse/SONAR-2276
*/
@Override
public Enumeration<URL> getResources(String name) throws IOException {
return findResources(name);
}

}

+ 36
- 0
src/main/java/org/sonar/runner/bootstrapper/BootstrapException.java View File

@@ -0,0 +1,36 @@
/*
* 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.bootstrapper;

public class BootstrapException extends RuntimeException {

public BootstrapException(String message) {
super(message);
}

public BootstrapException(Throwable cause) {
super(cause);
}

public BootstrapException(String message, Throwable cause) {
super(message, cause);
}

}

+ 167
- 0
src/main/java/org/sonar/runner/bootstrapper/Bootstrapper.java View File

@@ -0,0 +1,167 @@
/*
* 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.bootstrapper;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class Bootstrapper {

private static final String VERSION_PATH = "/api/server/version";
private static final String BATCH_PATH = "/batch/";

public static final int CONNECT_TIMEOUT_MILLISECONDS = 30000;
public static final int READ_TIMEOUT_MILLISECONDS = 60000;

private File bootDir;
private String serverUrl;
private String productToken;
private String serverVersion;

/**
* @param productToken part of User-Agent request-header field - see http://tools.ietf.org/html/rfc1945#section-10.15
*/
public Bootstrapper(String productToken, String serverUrl, File workDir) {
this.productToken = productToken;
bootDir = new File(workDir, "batch");
bootDir.mkdirs();
if (serverUrl.endsWith("/")) {
this.serverUrl = serverUrl.substring(0, serverUrl.length() - 1);
} else {
this.serverUrl = serverUrl;
}
}

/**
* @return server url
*/
public String getServerUrl() {
return serverUrl;
}

/**
* @return server version
*/
public String getServerVersion() {
if (serverVersion == null) {
try {
serverVersion = remoteContent(VERSION_PATH);
} catch (IOException e) {
throw new BootstrapException(e.getMessage(), e);
}
}
return serverVersion;
}

/**
* Download batch files from server and creates {@link BootstrapClassLoader}.
* To use this method version of Sonar should be at least 2.6.
*
* @param urls additional URLs for loading classes and resources
* @param parent parent ClassLoader
* @param unmaskedPackages only classes and resources from those packages would be available for loading from parent
*/
public BootstrapClassLoader createClassLoader(URL[] urls, ClassLoader parent, String... unmaskedPackages) {
BootstrapClassLoader classLoader = new BootstrapClassLoader(parent, unmaskedPackages);
List<File> files = downloadBatchFiles();
for (URL url : urls) {
classLoader.addURL(url);
}
for (File file : files) {
try {
classLoader.addURL(file.toURI().toURL());
} catch (MalformedURLException e) {
throw new BootstrapException(e);
}
}
return classLoader;
}

private void remoteContentToFile(String path, File toFile) {
InputStream input = null;
FileOutputStream output = null;
String fullUrl = serverUrl + path;
try {
HttpURLConnection connection = newHttpConnection(new URL(fullUrl));
output = new FileOutputStream(toFile, false);
input = connection.getInputStream();
BootstrapperIOUtils.copyLarge(input, output);
} catch (IOException e) {
BootstrapperIOUtils.closeQuietly(output);
BootstrapperIOUtils.deleteFileQuietly(toFile);
throw new BootstrapException("Fail to download the file: " + fullUrl, e);
} finally {
BootstrapperIOUtils.closeQuietly(input);
BootstrapperIOUtils.closeQuietly(output);
}
}

String remoteContent(String path) throws IOException {
String fullUrl = serverUrl + path;
HttpURLConnection conn = newHttpConnection(new URL(fullUrl));
Reader reader = new InputStreamReader((InputStream) conn.getContent());
try {
int statusCode = conn.getResponseCode();
if (statusCode != HttpURLConnection.HTTP_OK) {
throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode);
}
return BootstrapperIOUtils.toString(reader);
} finally {
BootstrapperIOUtils.closeQuietly(reader);
conn.disconnect();
}
}

/**
* By convention, the product tokens are listed in order of their significance for identifying the application.
*/
String getUserAgent() {
return "sonar-bootstrapper/" + BootstrapperVersion.getVersion() + " " + productToken;
}

HttpURLConnection newHttpConnection(URL url) throws IOException {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(CONNECT_TIMEOUT_MILLISECONDS);
connection.setReadTimeout(READ_TIMEOUT_MILLISECONDS);
connection.setInstanceFollowRedirects(true);
connection.setRequestMethod("GET");
connection.setRequestProperty("User-Agent", getUserAgent());
return connection;
}

private List<File> downloadBatchFiles() {
try {
List<File> files = new ArrayList<File>();
String libs = remoteContent(BATCH_PATH);
for (String lib : libs.split(",")) {
File file = new File(bootDir, lib);
remoteContentToFile(BATCH_PATH + lib, file);
files.add(file);
}
return files;
} catch (Exception e) {
throw new BootstrapException(e);
}
}
}

+ 98
- 0
src/main/java/org/sonar/runner/bootstrapper/BootstrapperIOUtils.java View File

@@ -0,0 +1,98 @@
/*
* 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.bootstrapper;

import java.io.*;

public final class BootstrapperIOUtils {

private BootstrapperIOUtils() {
// only static methods
}

/**
* The default buffer size to use.
*/
private static final int DEFAULT_BUFFER_SIZE = 1024 * 4;

/**
* Unconditionally close a <code>Closeable</code>.
*/
public static void closeQuietly(Closeable closeable) {
try {
if (closeable != null) {
closeable.close();
}
} catch (IOException ioe) { // NOSONAR
}
}

/**
* Get the contents of a <code>Reader</code> as a String.
*/
public static String toString(Reader input) throws IOException {
StringWriter sw = new StringWriter();
copyLarge(input, sw);
return sw.toString();
}

/**
* Copy bytes from an <code>InputStream</code> to an <code>OutputStream</code>.
*/
public static long copyLarge(InputStream input, OutputStream output) throws IOException {
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}

/**
* Copy chars from a <code>Reader</code> to a <code>Writer</code>.
*/
public static long copyLarge(Reader input, Writer output) throws IOException {
char[] buffer = new char[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}

/**
* Deletes a file (not a directory).
*/
public static boolean deleteFileQuietly(File file) {
if (file == null) {
return false;
}
try {
return file.delete();
} catch (Exception e) {
return false;
}
}

}

+ 52
- 0
src/main/java/org/sonar/runner/bootstrapper/BootstrapperVersion.java View File

@@ -0,0 +1,52 @@
/*
* 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.bootstrapper;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public enum BootstrapperVersion {

INSTANCE;

private static final String PROPERTIES_PATH = "/org/sonar/runner/version.txt";
private String version;

public static String getVersion() {
return INSTANCE.version;
}

private BootstrapperVersion() {
InputStream input = getClass().getResourceAsStream(PROPERTIES_PATH);
try {
Properties properties = new Properties();
properties.load(input);
this.version = properties.getProperty("version");

} catch (IOException e) {
// Can not load the version
this.version = "";

} finally {
BootstrapperIOUtils.closeQuietly(input);
}
}
}

+ 23
- 0
src/main/java/org/sonar/runner/bootstrapper/package-info.java View File

@@ -0,0 +1,23 @@
/*
* 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
*/
/**
* Provides API to bootstrap Sonar Batch.
*/
package org.sonar.runner.bootstrapper;

+ 19
- 0
src/test/java/org/sonar/runner/LauncherTest.java View File

@@ -23,6 +23,8 @@ import org.apache.commons.configuration.BaseConfiguration;
import org.apache.commons.configuration.Configuration;
import org.junit.Test;

import java.util.Properties;

import static org.fest.assertions.Assertions.assertThat;

public class LauncherTest {
@@ -53,4 +55,21 @@ public class LauncherTest {
assertThat(Launcher.getSqlResultsLevel(conf)).isEqualTo("WARN");
}

@Test
public void shouldDetermineVerboseMode() {
Properties properties = new Properties();
Launcher launcher = new Launcher(properties);
assertThat(launcher.isDebug()).isFalse();
properties.setProperty(Runner.PROPERTY_VERBOSE, "true");
assertThat(launcher.isDebug()).isTrue();
}

@Test
public void shouldSupportDeprecatedDebugProperty() {
Properties properties = new Properties();
Launcher launcher = new Launcher(properties);
properties.setProperty(Runner.PROPERTY_OLD_DEBUG_MODE, "true");
assertThat(launcher.isDebug()).isTrue();
}

}

+ 2
- 19
src/test/java/org/sonar/runner/RunnerTest.java View File

@@ -22,8 +22,8 @@ package org.sonar.runner;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.batch.bootstrapper.BootstrapException;
import org.sonar.batch.bootstrapper.Bootstrapper;
import org.sonar.runner.bootstrapper.BootstrapException;
import org.sonar.runner.bootstrapper.Bootstrapper;

import java.io.File;
import java.util.Properties;
@@ -95,23 +95,6 @@ public class RunnerTest {
assertThat(runner.getServerURL()).isEqualTo("foo");
}

@Test
public void shouldDetermineVerboseMode() {
Properties properties = new Properties();
Runner runner = Runner.create(properties);
assertThat(runner.isDebug()).isFalse();
properties.setProperty(Runner.PROPERTY_VERBOSE, "true");
assertThat(runner.isDebug()).isTrue();
}

@Test
public void shouldSupportDeprecatedDebugProperty() {
Properties properties = new Properties();
Runner runner = Runner.create(properties);
properties.setProperty(Runner.DEBUG_MODE, "true");
assertThat(runner.isDebug()).isTrue();
}

@Test
public void shouldInitDirs() throws Exception {
Properties props = new Properties();

+ 61
- 0
src/test/java/org/sonar/runner/bootstrapper/BootstrapClassLoaderTest.java View File

@@ -0,0 +1,61 @@
/*
* 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.bootstrapper;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.runner.bootstrapper.BootstrapClassLoader;

import static org.fest.assertions.Assertions.assertThat;

public class BootstrapClassLoaderTest {

@Rule
public ExpectedException thrown = ExpectedException.none();

@Test
public void shouldRestrictLoadingFromParent() throws Exception {
BootstrapClassLoader classLoader = new BootstrapClassLoader(getClass().getClassLoader(), "org.sonar.ant");
assertThat(classLoader.canLoadFromParent("org.sonar.ant.Launcher")).isTrue();
assertThat(classLoader.canLoadFromParent("org.objectweb.asm.ClassVisitor")).isFalse();
}

@Test
public void use_isolated_system_classloader_when_parent_is_excluded() throws ClassNotFoundException {
thrown.expect(ClassNotFoundException.class);
thrown.expectMessage("org.junit.Test");
ClassLoader parent = getClass().getClassLoader();
BootstrapClassLoader classLoader = new BootstrapClassLoader(parent);

// JUnit is available in the parent classloader (classpath used to execute this test) but not in the core JVM
assertThat(classLoader.loadClass("java.lang.String", false)).isNotNull();
classLoader.loadClass("org.junit.Test", false);
}

@Test
public void find_in_parent_when_matches_unmasked_packages() throws ClassNotFoundException {
ClassLoader parent = getClass().getClassLoader();
BootstrapClassLoader classLoader = new BootstrapClassLoader(parent, "org.junit");

// JUnit is available in the parent classloader (classpath used to execute this test) but not in the core JVM
assertThat(classLoader.loadClass("org.junit.Test", false)).isNotNull();
}
}

+ 65
- 0
src/test/java/org/sonar/runner/bootstrapper/BootstrapperTest.java View File

@@ -0,0 +1,65 @@
/*
* 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.bootstrapper;

import org.junit.Test;
import org.sonar.runner.bootstrapper.Bootstrapper;

import java.io.File;
import java.io.IOException;

import static org.fest.assertions.Assertions.assertThat;

public class BootstrapperTest {

@Test
public void shouldRemoveLastUrlSlash() {
Bootstrapper bootstrapper = new Bootstrapper("", "http://test/", new File("target"));
assertThat(bootstrapper.getServerUrl()).isEqualTo("http://test");
}

@Test(expected = Exception.class)
public void shouldFailIfCanNotConnectServer() {
Bootstrapper bootstrapper = new Bootstrapper("", "http://unknown.foo", new File("target"));
bootstrapper.getServerVersion();
}

@Test
public void shouldReturnUserAgent() {
Bootstrapper bootstrapper = new Bootstrapper("test/0.1", "http://unknown.foo", new File("target"));
String userAgent = bootstrapper.getUserAgent();

assertThat(userAgent.length()).isGreaterThan(0);
assertThat(userAgent).startsWith("sonar-bootstrapper/");
assertThat(userAgent).endsWith(" test/0.1");
}

@Test
public void shouldReturnValidVersion() {
Bootstrapper bootstrapper = new Bootstrapper("", "http://test", new File("target")) {
@Override
String remoteContent(String path) throws IOException {
return "2.6";
}
};
assertThat(bootstrapper.getServerVersion()).isEqualTo("2.6");
}

}

+ 36
- 0
src/test/java/org/sonar/runner/bootstrapper/BootstrapperVersionTest.java View File

@@ -0,0 +1,36 @@
/*
* 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.bootstrapper;

import org.junit.Test;
import org.sonar.runner.bootstrapper.BootstrapperVersion;

import static org.fest.assertions.Assertions.assertThat;

public class BootstrapperVersionTest {

@Test
public void shouldLoadVersion() {
String version = BootstrapperVersion.getVersion();
assertThat(version).contains(".");
assertThat(version).doesNotContain("$");
}

}

Loading…
Cancel
Save