]> source.dussan.org Git - sonar-scanner-cli.git/commitdiff
Add unit tests
authorSimon Brandhof <simon.brandhof@gmail.com>
Sat, 6 Apr 2013 13:23:31 +0000 (15:23 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Sat, 6 Apr 2013 13:23:31 +0000 (15:23 +0200)
16 files changed:
sonar-runner-impl/pom.xml
sonar-runner-impl/src/main/java/org/sonar/runner/impl/BatchLauncher.java
sonar-runner-impl/src/main/java/org/sonar/runner/impl/BatchLauncherMain.java
sonar-runner-impl/src/main/java/org/sonar/runner/impl/FileDownloader.java [deleted file]
sonar-runner-impl/src/main/java/org/sonar/runner/impl/JarDownloader.java [new file with mode: 0644]
sonar-runner-impl/src/main/java/org/sonar/runner/impl/Jars30.java
sonar-runner-impl/src/main/java/org/sonar/runner/impl/Jars35.java
sonar-runner-impl/src/main/java/org/sonar/runner/impl/RunnerException.java
sonar-runner-impl/src/main/java/org/sonar/runner/impl/ServerConnection.java [new file with mode: 0644]
sonar-runner-impl/src/main/java/org/sonar/runner/impl/ServerVersion.java
sonar-runner-impl/src/test/java/org/sonar/runner/impl/BatchLauncherMainTest.java [new file with mode: 0644]
sonar-runner-impl/src/test/java/org/sonar/runner/impl/BatchLauncherTest.java [new file with mode: 0644]
sonar-runner-impl/src/test/java/org/sonar/runner/impl/JarDownloaderTest.java [new file with mode: 0644]
sonar-runner-impl/src/test/java/org/sonar/runner/impl/JarExtractorTest.java
sonar-runner-impl/src/test/java/org/sonar/runner/impl/ServerVersionTest.java [new file with mode: 0644]
sonar-runner-impl/src/test/resources/org/sonar/runner/impl/BatchLauncherMainTest/props.properties [new file with mode: 0644]

index 8f77e3917e877cd3e6cb898e75d40f24047fd7f5..77aca5de4c62d75270df1aefefd98e4e59c5aeab 100644 (file)
       <artifactId>fest-assert</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-all</artifactId>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
   <build>
index 949af5e07b64145b868bc2a3368f834f13dec205..1d3cdb8b09b386d4417b94563fa872876f9b2c98 100644 (file)
@@ -26,35 +26,46 @@ import java.util.List;
 import java.util.Properties;
 
 public class BatchLauncher {
+  final String isolatedLauncherClass;
 
-  public void execute(Properties properties, List<Object> extensions) {
-    FileDownloader fileDownloader = FileDownloader.create(properties);
-    ServerVersion serverVersion = new ServerVersion(fileDownloader);
-    List<File> jarFiles;
-    if (serverVersion.is35Compatible()) {
-      jarFiles = new Jars35(fileDownloader, new JarExtractor()).download();
-    } else if (serverVersion.is30Compatible()) {
-      String workDir = properties.getProperty("sonar.working.directory");
-      jarFiles = new Jars30(fileDownloader).download(new File(workDir), new JarExtractor());
-    } else {
-      throw new IllegalStateException("Sonar " + serverVersion.version()
-        + " is not supported. Please upgrade Sonar to version 3.0 or more.");
-    }
+  /**
+   * For unit tests
+   */
+  BatchLauncher(String isolatedLauncherClass) {
+    this.isolatedLauncherClass = isolatedLauncherClass;
+  }
+
+  public BatchLauncher() {
+    this.isolatedLauncherClass = "org.sonar.runner.batch.IsolatedLauncher";
+  }
+
+  public void execute(Properties props, List<Object> extensions) {
+    ServerConnection serverConnection = ServerConnection.create(props);
+    ServerVersion serverVersion = new ServerVersion(serverConnection);
+    JarDownloader jarDownloader = new JarDownloader(props, serverConnection, serverVersion);
+    doExecute(jarDownloader, props, extensions);
+  }
 
-    String unmaskedPackages = properties.getProperty(InternalProperties.RUNNER_UNMASKED_PACKAGES, "");
+  /**
+   * @return the {@link IsolatedLauncher} instance for unit tests
+   */
+  Object doExecute(JarDownloader jarDownloader, Properties props, List<Object> extensions) {
+    List<File> jarFiles = jarDownloader.download();
+    String unmaskedPackages = props.getProperty(InternalProperties.RUNNER_UNMASKED_PACKAGES, "");
     IsolatedClassloader classloader = new IsolatedClassloader(getClass().getClassLoader(), unmaskedPackages.split(":"));
     classloader.addFiles(jarFiles);
-    delegateExecution(classloader, properties, extensions);
+    return delegateExecution(classloader, props, extensions);
   }
 
-  private void delegateExecution(IsolatedClassloader classloader, Properties properties, List<Object> extensions) {
+  private Object delegateExecution(IsolatedClassloader classloader, Properties properties, List<Object> extensions) {
     ClassLoader initialContextClassLoader = Thread.currentThread().getContextClassLoader();
     try {
       Thread.currentThread().setContextClassLoader(classloader);
-      Class<?> launcherClass = classloader.findClass("org.sonar.runner.batch.IsolatedLauncher");
+      Class<?> launcherClass = classloader.loadClass(isolatedLauncherClass);
       Method executeMethod = launcherClass.getMethod("execute", Properties.class, List.class);
       Object launcher = launcherClass.newInstance();
       executeMethod.invoke(launcher, properties, extensions);
+      return launcher;
     } catch (InvocationTargetException e) {
       // Unwrap original exception
       throw new RunnerException("Unable to execute Sonar", e.getTargetException());
index afeb99335758fe43ab2956900ff54206797dffc8..0c8591ae16b233b439ef880add6217bfd6aeb0cc 100644 (file)
@@ -27,15 +27,21 @@ import java.util.Collections;
 import java.util.Properties;
 
 public class BatchLauncherMain {
-  public static void main(String[] args) throws IOException {
+  private final BatchLauncher launcher;
+
+  BatchLauncherMain(BatchLauncher l) {
+    this.launcher = l;
+  }
+
+  void execute(String[] args) throws IOException {
     if (args.length == 0) {
       throw new IllegalArgumentException("Missing path to properties file");
     }
     Properties props = loadProperties(args[0]);
-    new BatchLauncher().execute(props, Collections.emptyList());
+    launcher.execute(props, Collections.emptyList());
   }
 
-  private static Properties loadProperties(String arg) throws IOException {
+  private Properties loadProperties(String arg) throws IOException {
     Properties props = new Properties();
     FileInputStream input = new FileInputStream(arg);
     try {
@@ -49,4 +55,7 @@ public class BatchLauncherMain {
     return props;
   }
 
+  public static void main(String[] args) throws IOException {
+    new BatchLauncherMain(new BatchLauncher()).execute(args);
+  }
 }
diff --git a/sonar-runner-impl/src/main/java/org/sonar/runner/impl/FileDownloader.java b/sonar-runner-impl/src/main/java/org/sonar/runner/impl/FileDownloader.java
deleted file mode 100644 (file)
index 3597f92..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Sonar Runner - Implementation
- * 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.impl;
-
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.net.ConnectException;
-import java.net.HttpURLConnection;
-import java.net.URL;
-import java.net.UnknownHostException;
-import java.util.Properties;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-class FileDownloader {
-
-
-  static final int CONNECT_TIMEOUT_MILLISECONDS = 30000;
-  static final int READ_TIMEOUT_MILLISECONDS = 60000;
-  private static final Pattern CHARSET_PATTERN = Pattern.compile("(?i)\\bcharset=\\s*\"?([^\\s;\"]*)");
-
-  private final String serverUrl;
-  private final String userAgent;
-
-  private FileDownloader(String serverUrl, String app, String appVersion) {
-    this.serverUrl = serverUrl;
-    this.userAgent = app + "/" + appVersion;
-  }
-
-  static FileDownloader create(Properties properties) {
-    String serverUrl = properties.getProperty("sonar.host.url");
-    String app = properties.getProperty(InternalProperties.RUNNER_APP);
-    String appVersion = properties.getProperty(InternalProperties.RUNNER_APP_VERSION);
-    return new FileDownloader(serverUrl, app, appVersion);
-  }
-
-  void download(String path, File toFile) {
-    InputStream input = null;
-    FileOutputStream output = null;
-    String fullUrl = serverUrl + path;
-    try {
-      if (Logs.isDebugEnabled()) {
-        Logs.debug("Download " + fullUrl + " to " + toFile.getAbsolutePath());
-      }
-      HttpURLConnection connection = newHttpConnection(new URL(fullUrl));
-      int statusCode = connection.getResponseCode();
-      if (statusCode != HttpURLConnection.HTTP_OK) {
-        throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode);
-      }
-      output = new FileOutputStream(toFile, false);
-      input = connection.getInputStream();
-      IOUtils.copyLarge(input, output);
-
-    } catch (Exception e) {
-      if (e instanceof ConnectException || e instanceof  UnknownHostException) {
-        Logs.error("Sonar server '" + serverUrl + "' can not be reached");
-      }
-      IOUtils.closeQuietly(output);
-      FileUtils.deleteQuietly(toFile);
-      throw new IllegalStateException("Fail to download: " + fullUrl, e);
-
-    } finally {
-      IOUtils.closeQuietly(input);
-      IOUtils.closeQuietly(output);
-    }
-  }
-
-  String downloadString(String path) throws IOException {
-    String fullUrl = serverUrl + path;
-    HttpURLConnection conn = newHttpConnection(new URL(fullUrl));
-    String charset = getCharsetFromContentType(conn.getContentType());
-    if (charset == null || "".equals(charset)) {
-      charset = "UTF-8";
-    }
-    Reader reader = null;
-    try {
-      int statusCode = conn.getResponseCode();
-      if (statusCode != HttpURLConnection.HTTP_OK) {
-        throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode);
-      }
-      reader = new InputStreamReader(conn.getInputStream(), charset);
-      return IOUtils.toString(reader);
-    } catch (IOException e) {
-      if (e instanceof ConnectException || e instanceof  UnknownHostException) {
-        Logs.error("Sonar server '" + serverUrl + "' can not be reached");
-      }
-      throw e;
-
-    } finally {
-      IOUtils.closeQuietly(reader);
-      conn.disconnect();
-    }
-  }
-
-  private HttpURLConnection newHttpConnection(URL url) throws IOException {
-    //TODO send credentials
-    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", userAgent);
-    return connection;
-  }
-
-  /**
-   * Parse out a charset from a content type header.
-   *
-   * @param contentType e.g. "text/html; charset=EUC-JP"
-   * @return "EUC-JP", or null if not found. Charset is trimmed and upper-cased.
-   */
-  static String getCharsetFromContentType(String contentType) {
-    if (contentType == null) {
-      return null;
-    }
-
-    Matcher m = CHARSET_PATTERN.matcher(contentType);
-    if (m.find()) {
-      return m.group(1).trim().toUpperCase();
-    }
-    return null;
-  }
-}
diff --git a/sonar-runner-impl/src/main/java/org/sonar/runner/impl/JarDownloader.java b/sonar-runner-impl/src/main/java/org/sonar/runner/impl/JarDownloader.java
new file mode 100644 (file)
index 0000000..7517f7b
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Sonar Runner - Implementation
+ * 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.impl;
+
+import java.io.File;
+import java.util.List;
+import java.util.Properties;
+
+class JarDownloader {
+  private final ServerConnection serverConnection;
+  private final ServerVersion serverVersion;
+  private final Properties props;
+
+  JarDownloader(Properties props, ServerConnection conn, ServerVersion version) {
+    this.props = props;
+    this.serverConnection = conn;
+    this.serverVersion = version;
+  }
+
+  List<File> download() {
+    List<File> jarFiles;
+    if (serverVersion.is35Compatible()) {
+      jarFiles = download35();
+    } else if (serverVersion.is30Compatible()) {
+      jarFiles = download30();
+    } else {
+      throw new IllegalStateException("Sonar " + serverVersion.version()
+          + " is not supported. Please upgrade Sonar to version 3.0 or more.");
+    }
+    return jarFiles;
+  }
+
+  List<File> download30() {
+    String workDir = props.getProperty("sonar.working.directory");
+    return new Jars30(serverConnection).download(new File(workDir), new JarExtractor());
+  }
+
+  List<File> download35() {
+    return new Jars35(serverConnection, new JarExtractor()).download();
+  }
+}
index b12536a71098d87bfc733fd91de05b157560c8f0..3ea1c7ec73397c097a54e67062c4c4df7a53149d 100644 (file)
@@ -27,9 +27,9 @@ import java.util.List;
 
 class Jars30 {
   private static final String BATCH_PATH = "/batch/";
-  private final FileDownloader downloader;
+  private final ServerConnection downloader;
 
-  Jars30(FileDownloader downloader) {
+  Jars30(ServerConnection downloader) {
     this.downloader = downloader;
   }
 
index eca7a9972c1cfadce95ee550b2412459a5766ce2..b36bd385a01327f4d231c9cd11e4a47cc01d8dc5 100644 (file)
@@ -34,10 +34,10 @@ class Jars35 {
   static final String BATCH_PATH = "/batch/";
 
   private final FileCache fileCache;
-  private final FileDownloader downloader;
+  private final ServerConnection downloader;
   private final JarExtractor jarExtractor;
 
-  Jars35(FileDownloader downloader, JarExtractor jarExtractor) {
+  Jars35(ServerConnection downloader, JarExtractor jarExtractor) {
     this.fileCache = new FileCacheBuilder().setLog(new StandardLog()).build();
     this.downloader = downloader;
     this.jarExtractor = jarExtractor;
@@ -72,9 +72,9 @@ class Jars35 {
   }
 
   private static class JarDownloader implements FileCache.Downloader {
-    private final FileDownloader downloader;
+    private final ServerConnection downloader;
 
-    private JarDownloader(FileDownloader downloader) {
+    private JarDownloader(ServerConnection downloader) {
       this.downloader = downloader;
     }
 
index 718ee4c6792bd5af7a6390d6ab45021c67b4153b..facbe7b6b2c764292a5573dd8c56a56d74a43f49 100644 (file)
  * 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.impl;
 
-/**
- * Exception thrown by the Sonar Runner when something bad happens.
- * 
- * @since 1.2
- */
 public class RunnerException extends RuntimeException {
 
-  private static final long serialVersionUID = 4810407777585753030L;
-
-  /**
-   * See {@link RuntimeException}
-   */
-  public RunnerException(String message) {
-    super(message);
-  }
-
-  /**
-   * See {@link RuntimeException}
-   */
-  public RunnerException(Throwable cause) {
-    super(cause);
-  }
-
-  /**
-   * See {@link RuntimeException}
-   */
   public RunnerException(String message, Throwable cause) {
     super(message, cause);
   }
diff --git a/sonar-runner-impl/src/main/java/org/sonar/runner/impl/ServerConnection.java b/sonar-runner-impl/src/main/java/org/sonar/runner/impl/ServerConnection.java
new file mode 100644 (file)
index 0000000..ec3510a
--- /dev/null
@@ -0,0 +1,146 @@
+/*
+ * Sonar Runner - Implementation
+ * 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.impl;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.io.IOUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.ConnectException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.util.Properties;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+class ServerConnection {
+
+  static final int CONNECT_TIMEOUT_MILLISECONDS = 30000;
+  static final int READ_TIMEOUT_MILLISECONDS = 60000;
+  private static final Pattern CHARSET_PATTERN = Pattern.compile("(?i)\\bcharset=\\s*\"?([^\\s;\"]*)");
+
+  private final String serverUrl;
+  private final String userAgent;
+
+  private ServerConnection(String serverUrl, String app, String appVersion) {
+    this.serverUrl = serverUrl;
+    this.userAgent = app + "/" + appVersion;
+  }
+
+  static ServerConnection create(Properties properties) {
+    String serverUrl = properties.getProperty("sonar.host.url");
+    String app = properties.getProperty(InternalProperties.RUNNER_APP);
+    String appVersion = properties.getProperty(InternalProperties.RUNNER_APP_VERSION);
+    return new ServerConnection(serverUrl, app, appVersion);
+  }
+
+  void download(String path, File toFile) {
+    InputStream input = null;
+    FileOutputStream output = null;
+    String fullUrl = serverUrl + path;
+    try {
+      if (Logs.isDebugEnabled()) {
+        Logs.debug("Download " + fullUrl + " to " + toFile.getAbsolutePath());
+      }
+      HttpURLConnection connection = newHttpConnection(new URL(fullUrl));
+      int statusCode = connection.getResponseCode();
+      if (statusCode != HttpURLConnection.HTTP_OK) {
+        throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode);
+      }
+      output = new FileOutputStream(toFile, false);
+      input = connection.getInputStream();
+      IOUtils.copyLarge(input, output);
+
+    } catch (Exception e) {
+      if (e instanceof ConnectException || e instanceof  UnknownHostException) {
+        Logs.error("Sonar server '" + serverUrl + "' can not be reached");
+      }
+      IOUtils.closeQuietly(output);
+      FileUtils.deleteQuietly(toFile);
+      throw new IllegalStateException("Fail to download: " + fullUrl, e);
+
+    } finally {
+      IOUtils.closeQuietly(input);
+      IOUtils.closeQuietly(output);
+    }
+  }
+
+  String downloadString(String path) throws IOException {
+    String fullUrl = serverUrl + path;
+    HttpURLConnection conn = newHttpConnection(new URL(fullUrl));
+    String charset = getCharsetFromContentType(conn.getContentType());
+    if (charset == null || "".equals(charset)) {
+      charset = "UTF-8";
+    }
+    Reader reader = null;
+    try {
+      int statusCode = conn.getResponseCode();
+      if (statusCode != HttpURLConnection.HTTP_OK) {
+        throw new IOException("Status returned by url : '" + fullUrl + "' is invalid : " + statusCode);
+      }
+      reader = new InputStreamReader(conn.getInputStream(), charset);
+      return IOUtils.toString(reader);
+    } catch (IOException e) {
+      if (e instanceof ConnectException || e instanceof  UnknownHostException) {
+        Logs.error("Sonar server '" + serverUrl + "' can not be reached");
+      }
+      throw e;
+
+    } finally {
+      IOUtils.closeQuietly(reader);
+      conn.disconnect();
+    }
+  }
+
+  private HttpURLConnection newHttpConnection(URL url) throws IOException {
+    //TODO send credentials
+    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", userAgent);
+    return connection;
+  }
+
+  /**
+   * Parse out a charset from a content type header.
+   *
+   * @param contentType e.g. "text/html; charset=EUC-JP"
+   * @return "EUC-JP", or null if not found. Charset is trimmed and upper-cased.
+   */
+  static String getCharsetFromContentType(String contentType) {
+    if (contentType == null) {
+      return null;
+    }
+
+    Matcher m = CHARSET_PATTERN.matcher(contentType);
+    if (m.find()) {
+      return m.group(1).trim().toUpperCase();
+    }
+    return null;
+  }
+}
index 8f5af45d1c395679ab3d090d1c9ffd62f75f0128..423fde10ab78a4102dc4d3520cd45938a219459a 100644 (file)
@@ -27,11 +27,11 @@ class ServerVersion {
   private static final String[] LESS_THAN_3_0 = {"0", "1", "2"};
   private static final String[] LESS_THAN_3_5 = {"0", "1", "2", "3.0", "3.1", "3.2", "3.3", "3.4"};
 
-  private final FileDownloader fileDownloader;
+  private final ServerConnection serverConnection;
   private String version;
 
-  ServerVersion(FileDownloader fileDownloader) {
-    this.fileDownloader = fileDownloader;
+  ServerVersion(ServerConnection serverConnection) {
+    this.serverConnection = serverConnection;
   }
 
   String version() {
@@ -46,7 +46,7 @@ class ServerVersion {
   private String downloadVersion() {
     String result;
     try {
-      result = fileDownloader.downloadString("/api/server/version");
+      result = serverConnection.downloadString("/api/server/version");
     } catch (IOException e) {
       throw new IllegalStateException("Fail to request server version", e);
     }
diff --git a/sonar-runner-impl/src/test/java/org/sonar/runner/impl/BatchLauncherMainTest.java b/sonar-runner-impl/src/test/java/org/sonar/runner/impl/BatchLauncherMainTest.java
new file mode 100644 (file)
index 0000000..d72d8b8
--- /dev/null
@@ -0,0 +1,80 @@
+/*
+ * Sonar Runner - Implementation
+ * 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.impl;
+
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+import java.util.Properties;
+
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class BatchLauncherMainTest {
+
+  BatchLauncher launcher = mock(BatchLauncher.class);
+
+  @Test
+  public void should_load_properties_and_execute() throws Exception {
+    URL url = getClass().getResource("/org/sonar/runner/impl/BatchLauncherMainTest/props.properties");
+    BatchLauncherMain main = new BatchLauncherMain(launcher);
+    main.execute(new String[]{new File(url.toURI()).getAbsolutePath()});
+
+    verify(launcher).execute(argThat(new ArgumentMatcher<Properties>() {
+      @Override
+      public boolean matches(Object o) {
+        return ((Properties) o).get("sonar.login").equals("foo");
+      }
+    }), argThat(new ArgumentMatcher<List<Object>>() {
+      @Override
+      public boolean matches(Object o) {
+        return ((List) o).isEmpty();
+      }
+    }));
+  }
+
+  @Test
+  public void should_fail_if_missing_path_to_properties_file() {
+    try {
+      BatchLauncherMain main = new BatchLauncherMain(launcher);
+      main.execute(new String[0]);
+      fail();
+    } catch (Exception e) {
+      // success
+    }
+  }
+
+  @Test
+  public void should_fail_if_properties_file_does_not_exist() {
+    try {
+      BatchLauncherMain main = new BatchLauncherMain(launcher);
+      main.execute(new String[]{"unknown/file.properties"});
+      fail();
+    } catch (Exception e) {
+      // success
+    }
+
+  }
+}
diff --git a/sonar-runner-impl/src/test/java/org/sonar/runner/impl/BatchLauncherTest.java b/sonar-runner-impl/src/test/java/org/sonar/runner/impl/BatchLauncherTest.java
new file mode 100644 (file)
index 0000000..2d8f2e7
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * Sonar Runner - Implementation
+ * 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.impl;
+
+import org.junit.Test;
+import org.sonar.runner.batch.IsolatedLauncher;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+public class BatchLauncherTest {
+
+  JarDownloader jarDownloader = mock(JarDownloader.class);
+
+  @Test
+  public void should_download_jars_and_execute_batch() {
+    BatchLauncher launcher = new BatchLauncher(FakeIsolatedLauncher.class.getName());
+    Properties props = new Properties();
+    props.put("foo", "bar");
+
+    // Unmask the current classloader in order to access FakeIsolatedLauncher
+    props.put(InternalProperties.RUNNER_UNMASKED_PACKAGES, "org.sonar.runner.impl");
+    List<Object> extensions = new ArrayList<Object>();
+
+    FakeIsolatedLauncher isolatedLauncher = (FakeIsolatedLauncher) launcher.doExecute(jarDownloader, props, extensions);
+    assertThat(isolatedLauncher.props.get("foo")).isEqualTo("bar");
+    assertThat(isolatedLauncher.extensions).isSameAs(extensions);
+    verify(jarDownloader).download();
+  }
+
+  @Test
+  public void should_use_isolated_classloader() {
+    BatchLauncher launcher = new BatchLauncher(FakeIsolatedLauncher.class.getName());
+    Properties props = new Properties();
+
+    // The current classloader in not available -> fail to load FakeIsolatedLauncher
+    props.put(InternalProperties.RUNNER_UNMASKED_PACKAGES, "");
+    try {
+      launcher.doExecute(jarDownloader, props, Collections.emptyList());
+      fail();
+    } catch (RunnerException e) {
+      // success
+    }
+  }
+
+  @Test
+  public void verify_isolated_classloader_name() {
+    // the class IsolatedLauncher should not be loaded in the classloader of BatchLauncher,
+    // that's why it's referenced by its name
+    assertThat(new BatchLauncher().isolatedLauncherClass).isEqualTo(IsolatedLauncher.class.getName());
+  }
+
+  @Test
+  public void test_real_execution() {
+    // verify the creation of dependent components
+    Properties props = new Properties();
+    List<Object> extensions = Collections.emptyList();
+    BatchLauncher launcher = spy(new BatchLauncher());
+    doReturn(new Object()).when(launcher).doExecute(any(JarDownloader.class), eq(props), eq(extensions));
+
+    launcher.execute(props, extensions);
+
+    verify(launcher).execute(props, extensions);
+  }
+
+  public static class FakeIsolatedLauncher {
+    public Properties props = null;
+    public List<Object> extensions = null;
+
+    public void execute(Properties props, List<Object> extensions) {
+      this.props = props;
+      this.extensions = extensions;
+    }
+  }
+}
diff --git a/sonar-runner-impl/src/test/java/org/sonar/runner/impl/JarDownloaderTest.java b/sonar-runner-impl/src/test/java/org/sonar/runner/impl/JarDownloaderTest.java
new file mode 100644 (file)
index 0000000..9e5ca80
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Sonar Runner - Implementation
+ * 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.impl;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+public class JarDownloaderTest {
+
+  ServerConnection serverConnection = mock(ServerConnection.class);
+  ServerVersion serverVersion = mock(ServerVersion.class);
+  Properties props = new Properties();
+  JarDownloader downloader = spy(new JarDownloader(props, serverConnection, serverVersion));
+
+  @Test
+  public void should_download_3_5_jar_files() {
+    when(serverVersion.is35Compatible()).thenReturn(true);
+    doReturn(new ArrayList()).when(downloader).download35();
+    List<File> jarFiles = downloader.download();
+    assertThat(jarFiles).isNotNull();
+  }
+
+  @Test
+  public void should_download_3_0_jar_files() {
+    when(serverVersion.is35Compatible()).thenReturn(false);
+    when(serverVersion.is30Compatible()).thenReturn(true);
+    doReturn(new ArrayList()).when(downloader).download30();
+    List<File> jarFiles = downloader.download();
+    assertThat(jarFiles).isNotNull();
+  }
+
+  @Test
+  public void should_fail_if_2_x() {
+    when(serverVersion.version()).thenReturn("2.10");
+    when(serverVersion.is30Compatible()).thenReturn(false);
+    when(serverVersion.is35Compatible()).thenReturn(false);
+    try {
+      downloader.download();
+      fail();
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessage("Sonar 2.10 is not supported. Please upgrade Sonar to version 3.0 or more.");
+    }
+  }
+}
index 0f81031f439a5f3daee92a245119bcf486be8ad9..3cc124749371c2e0a6375941912bba1aec3f9744 100644 (file)
@@ -25,6 +25,7 @@ import org.junit.Test;
 import java.io.File;
 
 import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
 
 public class JarExtractorTest {
   @Test
@@ -34,4 +35,14 @@ public class JarExtractorTest {
     assertThat(FileUtils.readFileToString(jarFile, "UTF-8")).isEqualTo("Fake jar for unit tests");
     assertThat(jarFile.toURI().toURL().toString()).doesNotContain("jar:file");
   }
+
+  @Test
+  public void should_fail_to_extract() throws Exception {
+    try {
+      new JarExtractor().extract("unknown");
+      fail();
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessage("Fail to extract unknown.jar");
+    }
+  }
 }
diff --git a/sonar-runner-impl/src/test/java/org/sonar/runner/impl/ServerVersionTest.java b/sonar-runner-impl/src/test/java/org/sonar/runner/impl/ServerVersionTest.java
new file mode 100644 (file)
index 0000000..5e58519
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * Sonar Runner - Implementation
+ * 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.impl;
+
+import org.junit.Test;
+
+import java.net.ConnectException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class ServerVersionTest {
+
+  ServerConnection connection = mock(ServerConnection.class);
+  ServerVersion version = new ServerVersion(connection);
+
+  @Test
+  public void should_fail_on_connection_error() throws Exception {
+    when(connection.downloadString("/api/server/version")).thenThrow(new ConnectException());
+    try {
+      version.version();
+      fail();
+    } catch (IllegalStateException e) {
+      // success
+    }
+  }
+
+  @Test
+  public void should_fail_if_bad_version() throws Exception {
+    when(connection.downloadString("/api/server/version")).thenReturn("");
+    try {
+      version.version();
+      fail();
+    } catch (IllegalStateException e) {
+      assertThat(e).hasMessage("Server version is not set");
+    }
+  }
+
+  @Test
+  public void test_2_x() throws Exception {
+    when(connection.downloadString("/api/server/version")).thenReturn("2.10");
+    assertThat(version.version()).isEqualTo("2.10");
+    assertThat(version.is30Compatible()).isFalse();
+    assertThat(version.is35Compatible()).isFalse();
+    verify(connection, times(1)).downloadString("/api/server/version");
+  }
+
+  @Test
+  public void test_3_0() throws Exception {
+    when(connection.downloadString("/api/server/version")).thenReturn("3.0");
+    assertThat(version.version()).isEqualTo("3.0");
+    assertThat(version.is30Compatible()).isTrue();
+    assertThat(version.is35Compatible()).isFalse();
+    verify(connection, times(1)).downloadString("/api/server/version");
+  }
+
+  @Test
+  public void test_3_1() throws Exception {
+    when(connection.downloadString("/api/server/version")).thenReturn("3.1");
+    assertThat(version.version()).isEqualTo("3.1");
+    assertThat(version.is30Compatible()).isTrue();
+    assertThat(version.is35Compatible()).isFalse();
+    verify(connection, times(1)).downloadString("/api/server/version");
+  }
+
+  @Test
+  public void test_3_5() throws Exception {
+    when(connection.downloadString("/api/server/version")).thenReturn("3.5");
+    assertThat(version.version()).isEqualTo("3.5");
+    assertThat(version.is30Compatible()).isTrue();
+    assertThat(version.is35Compatible()).isTrue();
+    verify(connection, times(1)).downloadString("/api/server/version");
+  }
+
+  @Test
+  public void test_3_5_1() throws Exception {
+    when(connection.downloadString("/api/server/version")).thenReturn("3.5.1");
+    assertThat(version.version()).isEqualTo("3.5.1");
+    assertThat(version.is30Compatible()).isTrue();
+    assertThat(version.is35Compatible()).isTrue();
+    verify(connection, times(1)).downloadString("/api/server/version");
+  }
+
+  @Test
+  public void test_3_6() throws Exception {
+    when(connection.downloadString("/api/server/version")).thenReturn("3.6");
+    assertThat(version.version()).isEqualTo("3.6");
+    assertThat(version.is30Compatible()).isTrue();
+    assertThat(version.is35Compatible()).isTrue();
+    verify(connection, times(1)).downloadString("/api/server/version");
+  }
+
+  @Test
+  public void test_4_0() throws Exception {
+    when(connection.downloadString("/api/server/version")).thenReturn("4.0");
+    assertThat(version.version()).isEqualTo("4.0");
+    assertThat(version.is30Compatible()).isTrue();
+    assertThat(version.is35Compatible()).isTrue();
+    verify(connection, times(1)).downloadString("/api/server/version");
+  }
+}
diff --git a/sonar-runner-impl/src/test/resources/org/sonar/runner/impl/BatchLauncherMainTest/props.properties b/sonar-runner-impl/src/test/resources/org/sonar/runner/impl/BatchLauncherMainTest/props.properties
new file mode 100644 (file)
index 0000000..82640ae
--- /dev/null
@@ -0,0 +1,2 @@
+sonar.login=foo
+sonar.password=bar
\ No newline at end of file