]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7100 Disable WS cache by default in issues mode
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 2 Dec 2015 13:10:44 +0000 (14:10 +0100)
committerJulien HENRY <julien.henry@sonarsource.com>
Thu, 3 Dec 2015 08:27:58 +0000 (09:27 +0100)
it/it-tests/src/test/java/it/analysis/IssuesModeTest.java
sonar-batch/src/main/java/org/sonar/batch/analysis/AnalysisWSLoaderProvider.java
sonar-batch/src/test/java/org/sonar/batch/analysis/AnalysisWSLoaderProviderTest.java

index 14749d888fd28cdef60e4695280d3c5e75208fec..bb0b6d10b31f64513f04c0bbc69a06d61ea014ea 100644 (file)
@@ -5,8 +5,6 @@
  */
 package it.analysis;
 
-import org.apache.commons.io.FileUtils;
-import org.sonar.wsclient.issue.IssueClient;
 import com.google.common.collect.Maps;
 import com.sonar.orchestrator.Orchestrator;
 import com.sonar.orchestrator.build.BuildFailureException;
@@ -17,7 +15,6 @@ import com.sonar.orchestrator.config.FileSystem;
 import com.sonar.orchestrator.locator.FileLocation;
 import com.sonar.orchestrator.version.Version;
 import it.Category3Suite;
-
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.StandardCharsets;
@@ -29,7 +26,8 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
-
+import javax.annotation.Nullable;
+import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.ObjectUtils;
 import org.json.simple.JSONArray;
 import org.json.simple.JSONObject;
@@ -41,12 +39,14 @@ import org.junit.rules.ExpectedException;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.wsclient.SonarClient;
 import org.sonar.wsclient.issue.Issue;
+import org.sonar.wsclient.issue.IssueClient;
 import org.sonar.wsclient.issue.IssueQuery;
 import org.sonar.wsclient.issue.Issues;
 import org.sonar.wsclient.services.Resource;
 import org.sonar.wsclient.services.ResourceQuery;
 import org.sonar.wsclient.user.UserParameters;
 import util.ItUtils;
+
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.Assert.fail;
 
@@ -71,7 +71,7 @@ public class IssuesModeTest {
     restoreProfile("one-issue-per-line.xml");
     orchestrator.getServer().provisionProject("sample", "xoo-sample");
     orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line");
-    SonarRunner runner = configureRunnerIssues("shared/xoo-sample", "sonar.verbose", "true");
+    SonarRunner runner = configureRunnerIssues("shared/xoo-sample", null, "sonar.verbose", "true");
     BuildResult result = orchestrator.executeBuild(runner);
     assertThat(ItUtils.countIssuesInJsonReport(result, true)).isEqualTo(17);
   }
@@ -122,7 +122,7 @@ public class IssuesModeTest {
     orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "with-many-rules");
 
     // do it again, scanning nothing (all files should be unchanged)
-    runner = configureRunnerIssues("shared/xoo-sample",
+    runner = configureRunnerIssues("shared/xoo-sample", null,
       "sonar.verbose", "true");
     result = orchestrator.executeBuild(runner);
     assertThat(result.getLogs()).contains("Scanning only changed files");
@@ -151,7 +151,7 @@ public class IssuesModeTest {
     issueClient.doTransition(serverIssues.get(1).key(), "wontfix");
 
     // do it again, scanning nothing (all files should be unchanged)
-    runner = configureRunnerIssues("shared/xoo-sample",
+    runner = configureRunnerIssues("shared/xoo-sample", null,
       "sonar.verbose", "true");
     result = orchestrator.executeBuild(runner);
     assertThat(result.getLogs()).contains("Scanning only changed files");
@@ -197,7 +197,7 @@ public class IssuesModeTest {
   public void non_associated_mode() throws IOException {
     restoreProfile("one-issue-per-line.xml");
     setDefaultQualityProfile("xoo", "one-issue-per-line");
-    SonarRunner runner = configureRunnerIssues("shared/xoo-sample-non-associated");
+    SonarRunner runner = configureRunnerIssues("shared/xoo-sample-non-associated", null);
     BuildResult result = orchestrator.executeBuild(runner);
 
     assertThat(result.getLogs()).contains("Local analysis");
@@ -220,7 +220,7 @@ public class IssuesModeTest {
     BuildResult result = orchestrator.executeBuild(runner);
     assertThat(getResource("sample:my sources/main/xoo/sample/My Sample.xoo")).isNotNull();
 
-    runner = configureRunnerIssues("analysis/xoo-sample-with-spaces/v2");
+    runner = configureRunnerIssues("analysis/xoo-sample-with-spaces/v2", null);
     result = orchestrator.executeBuild(runner);
     // Analysis is not persisted in database
     Resource project = getResource("com.sonarsource.it.samples:simple-sample");
@@ -246,7 +246,7 @@ public class IssuesModeTest {
     assertThat(getResource("sample:src/main/xoo/sample/ClassAdded.xoo")).isNull();
 
     // Re-add ClassAdded.xoo in local workspace
-    runner = configureRunnerIssues("shared/xoo-history-v2");
+    runner = configureRunnerIssues("shared/xoo-history-v2", null);
     result = orchestrator.executeBuild(runner);
 
     assertThat(getResource("sample:src/main/xoo/sample/ClassAdded.xoo")).isNull();
@@ -257,7 +257,7 @@ public class IssuesModeTest {
   @Test
   public void should_fail_if_plugin_access_secured_properties() throws IOException {
     // Test access from task (ie BatchSettings)
-    SonarRunner runner = configureRunnerIssues("shared/xoo-sample",
+    SonarRunner runner = configureRunnerIssues("shared/xoo-sample", null,
       "accessSecuredFromTask", "true");
     BuildResult result = orchestrator.executeBuildQuietly(runner);
 
@@ -265,7 +265,7 @@ public class IssuesModeTest {
       + "The SonarQube plugin which requires this property must be deactivated in issues mode.");
 
     // Test access from sensor (ie ModuleSettings)
-    runner = configureRunnerIssues("shared/xoo-sample",
+    runner = configureRunnerIssues("shared/xoo-sample", null,
       "accessSecuredFromSensor", "true");
     result = orchestrator.executeBuildQuietly(runner);
 
@@ -275,74 +275,31 @@ public class IssuesModeTest {
 
   // SONAR-4602
   @Test
-  public void no_issues_mode_cache_after_new_analysis() throws Exception {
-    restoreProfile("one-issue-per-line.xml");
-    restoreProfile("empty.xml");
-    orchestrator.getServer().provisionProject("sample", "xoo-sample");
-
-    // First run (publish mode)
-    orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "empty");
-    SonarRunner runner = configureRunner("shared/xoo-sample");
-    orchestrator.executeBuild(runner);
+  public void no_issues_mode_cache_by_default() throws Exception {
+    File homeDir = runFirstAnalysisAndFlagIssueAsWontFix();
 
-    // First run issues mode
-    orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line");
-    runner = configureRunnerIssues("shared/xoo-sample",
-      "sonar.scanAllFiles", "true");
+    // Second issues mode using same cache dir but cache disabled by default
+    SonarRunner runner = configureRunnerIssues("shared/xoo-sample", homeDir);
     BuildResult result = orchestrator.executeBuild(runner);
 
-    // As many new issue as lines
-    assertThat(ItUtils.countIssuesInJsonReport(result, true)).isEqualTo(17);
-
-    // Second run (publish mode) should invalidate cache
-    runner = configureRunner("shared/xoo-sample");
-    orchestrator.executeBuild(runner);
-
-    // Second run issues mode
-    runner = configureRunnerIssues("shared/xoo-sample",
-      "sonar.report.export.path", "sonar-report.json",
-      "sonar.scanAllFiles", "true");
-    result = orchestrator.executeBuild(runner);
-
-    // No new issue this time
-    assertThat(ItUtils.countIssuesInJsonReport(result, true)).isEqualTo(0);
+    // False positive is not returned
+    assertThat(ItUtils.countIssuesInJsonReport(result, false)).isEqualTo(16);
   }
 
-  // SONAR-4602
+  // SONAR-7100
   @Test
-  public void no_issues_mode_cache_after_profile_change() throws Exception {
-    restoreProfile("one-issue-per-line-empty.xml");
-    orchestrator.getServer().provisionProject("sample", "xoo-sample");
-    orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line");
-
-    // First run (publish mode)
-    SonarRunner runner = configureRunner("shared/xoo-sample");
-    orchestrator.executeBuild(runner);
+  public void enable_issues_cache() throws Exception {
+    File homeDir = runFirstAnalysisAndFlagIssueAsWontFix();
 
-    // First issues mode
-    runner = configureRunnerIssues("shared/xoo-sample",
-      "sonar.scanAllFiles", "true");
+    // Second issues mode using same cache dir and enable cache
+    SonarRunner runner = configureRunnerIssues("shared/xoo-sample", homeDir, "sonar.useWsCache", "true");
     BuildResult result = orchestrator.executeBuild(runner);
 
-    // No new issues
-    assertThat(ItUtils.countIssuesInJsonReport(result, true)).isEqualTo(0);
-
-    // Modification of QP should invalidate cache
-    restoreProfile("/one-issue-per-line.xml");
-
-    // Second issues mode
-    runner = configureRunnerIssues("shared/xoo-sample",
-      "sonar.report.export.path", "sonar-report.json",
-      "sonar.scanAllFiles", "true");
-    result = orchestrator.executeBuild(runner);
-
-    // As many new issue as lines
-    assertThat(ItUtils.countIssuesInJsonReport(result, true)).isEqualTo(17);
+    // False positive is still visible since we are using cached issues
+    assertThat(ItUtils.countIssuesInJsonReport(result, false)).isEqualTo(17);
   }
 
-  // SONAR-4602
-  @Test
-  public void no_issues_mode_cache_after_issue_change() throws Exception {
+  private File runFirstAnalysisAndFlagIssueAsWontFix() throws IOException {
     restoreProfile("one-issue-per-line.xml");
     orchestrator.getServer().provisionProject("sample", "xoo-sample");
     orchestrator.getServer().associateProjectToQualityProfile("sample", "xoo", "one-issue-per-line");
@@ -352,7 +309,8 @@ public class IssuesModeTest {
     orchestrator.executeBuild(runner);
 
     // First issues mode
-    runner = configureRunnerIssues("shared/xoo-sample");
+    File homeDir = temp.newFolder();
+    runner = configureRunnerIssues("shared/xoo-sample", homeDir);
     BuildResult result = orchestrator.executeBuild(runner);
 
     // 17 issues
@@ -362,13 +320,7 @@ public class IssuesModeTest {
     JSONObject obj = ItUtils.getJSONReport(result);
     String key = ((JSONObject) ((JSONArray) obj.get("issues")).get(0)).get("key").toString();
     orchestrator.getServer().adminWsClient().issueClient().doTransition(key, "falsepositive");
-
-    // Second issues mode
-    runner = configureRunnerIssues("shared/xoo-sample");
-    result = orchestrator.executeBuild(runner);
-
-    // False positive is not returned
-    assertThat(ItUtils.countIssuesInJsonReport(result, false)).isEqualTo(16);
+    return homeDir;
   }
 
   // SONAR-6522
@@ -395,7 +347,7 @@ public class IssuesModeTest {
     client.issueClient().assign(issue.key(), "julien");
 
     // Issues
-    runner = configureRunnerIssues("shared/xoo-sample");
+    runner = configureRunnerIssues("shared/xoo-sample", null);
     BuildResult result = orchestrator.executeBuild(runner);
 
     JSONObject obj = ItUtils.getJSONReport(result);
@@ -433,18 +385,19 @@ public class IssuesModeTest {
     runConcurrentIssues();
   }
 
-  private void runConcurrentIssues() throws InterruptedException, ExecutionException {
+  private void runConcurrentIssues() throws Exception {
     // Install sonar-runner in advance to avoid concurrent unzip issues
     FileSystem fileSystem = orchestrator.getConfiguration().fileSystem();
     new SonarRunnerInstaller(fileSystem).install(Version.create(SonarRunner.DEFAULT_RUNNER_VERSION), fileSystem.workspace());
     final int nThreads = 3;
     ExecutorService executorService = Executors.newFixedThreadPool(nThreads);
     List<Callable<BuildResult>> tasks = new ArrayList<>();
+    final File homeDir = temp.newFolder();
     for (int i = 0; i < nThreads; i++) {
       tasks.add(new Callable<BuildResult>() {
 
         public BuildResult call() throws Exception {
-          SonarRunner runner = configureRunnerIssues("shared/xoo-sample");
+          SonarRunner runner = configureRunnerIssues("shared/xoo-sample", homeDir);
           return orchestrator.executeBuild(runner);
         }
       });
@@ -475,12 +428,16 @@ public class IssuesModeTest {
     return orchestrator.getServer().getWsClient().find(ResourceQuery.createForMetrics(key, "lines"));
   }
 
-  private SonarRunner configureRunnerIssues(String projectDir, String... props) throws IOException {
+  private SonarRunner configureRunnerIssues(String projectDir, @Nullable File homeDir, String... props) throws IOException {
     SonarRunner runner = SonarRunner.create(ItUtils.projectDir(projectDir),
       "sonar.working.directory", temp.newFolder().getAbsolutePath(),
       "sonar.analysis.mode", "issues",
-      "sonar.report.export.path", "sonar-report.json",
-      "sonar.userHome", temp.newFolder().getAbsolutePath());
+      "sonar.report.export.path", "sonar-report.json");
+    if (homeDir != null) {
+      runner.setProperty("sonar.userHome", homeDir.getAbsolutePath());
+    } else {
+      runner.setProperty("sonar.userHome", temp.newFolder().getAbsolutePath());
+    }
     runner.setProperties(props);
     return runner;
   }
index 7ca47ae787a51bb6d5a8d175be3a3ca0f76ba820..fc3482a2006bc1f134b80fbdef326cbda00e3429 100644 (file)
@@ -27,19 +27,20 @@ import org.sonar.batch.cache.WSLoader.LoadStrategy;
 import org.sonar.home.cache.PersistentCache;
 
 public class AnalysisWSLoaderProvider extends ProviderAdapter {
+  static final String SONAR_USE_WS_CACHE = "sonar.useWsCache";
   private WSLoader wsLoader;
 
-  public WSLoader provide(AnalysisMode mode, PersistentCache cache, BatchWsClient client) {
+  public WSLoader provide(AnalysisMode mode, PersistentCache cache, BatchWsClient client, AnalysisProperties props) {
     if (wsLoader == null) {
       // recreate cache directory if needed for this analysis
       cache.reconfigure();
-      wsLoader = new WSLoader(getStrategy(mode), cache, client);
+      wsLoader = new WSLoader(getStrategy(mode, props), cache, client);
     }
     return wsLoader;
   }
 
-  private static LoadStrategy getStrategy(AnalysisMode mode) {
-    if (mode.isIssues()) {
+  private static LoadStrategy getStrategy(AnalysisMode mode, AnalysisProperties props) {
+    if (mode.isIssues() && "true".equals(props.property(SONAR_USE_WS_CACHE))) {
       return LoadStrategy.CACHE_ONLY;
     }
 
index b175faa6bc67464dd98e20d9edbf4bf0a556db27..5aa31bd64d503b860b95f7a32977d1640259e643 100644 (file)
@@ -19,6 +19,8 @@
  */
 package org.sonar.batch.analysis;
 
+import com.google.common.collect.ImmutableMap;
+import org.assertj.core.util.Maps;
 import org.junit.Test;
 import org.sonar.api.batch.AnalysisMode;
 import org.sonar.batch.bootstrap.BatchWsClient;
@@ -28,6 +30,7 @@ import org.sonar.home.cache.PersistentCache;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 public class AnalysisWSLoaderProviderTest {
 
@@ -39,7 +42,21 @@ public class AnalysisWSLoaderProviderTest {
 
   @Test
   public void testDefault() {
-    WSLoader loader = underTest.provide(mode, cache, wsClient);
+    WSLoader loader = underTest.provide(mode, cache, wsClient, new AnalysisProperties(Maps.<String, String>newHashMap()));
     assertThat(loader.getDefaultStrategy()).isEqualTo(LoadStrategy.SERVER_ONLY);
   }
+
+  @Test
+  public void no_cache_by_default_in_issues_mode() {
+    when(mode.isIssues()).thenReturn(true);
+    WSLoader loader = underTest.provide(mode, cache, wsClient, new AnalysisProperties(Maps.<String, String>newHashMap()));
+    assertThat(loader.getDefaultStrategy()).isEqualTo(LoadStrategy.SERVER_ONLY);
+  }
+
+  @Test
+  public void enable_cache_in_issues_mode() {
+    when(mode.isIssues()).thenReturn(true);
+    WSLoader loader = underTest.provide(mode, cache, wsClient, new AnalysisProperties(ImmutableMap.of(AnalysisWSLoaderProvider.SONAR_USE_WS_CACHE, "true")));
+    assertThat(loader.getDefaultStrategy()).isEqualTo(LoadStrategy.CACHE_ONLY);
+  }
 }