]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11244 Record warning when SCM provider cannot be detected
authorJanos Gyerik <janos.gyerik@sonarsource.com>
Thu, 20 Sep 2018 16:03:32 +0000 (18:03 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 10 Oct 2018 07:23:05 +0000 (09:23 +0200)
sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java [new file with mode: 0644]

index 56957d3befd0b53d3e82496fa175f748a0f24a36..b8bced98aa3eaaa07951feab6bd332305f460087 100644 (file)
@@ -35,11 +35,14 @@ import org.sonar.api.batch.ScannerSide;
 import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
 import org.sonar.api.batch.scm.ScmProvider;
 import org.sonar.api.config.Configuration;
+import org.sonar.api.notifications.AnalysisWarnings;
 import org.sonar.api.utils.MessageException;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.core.config.ScannerProperties;
 
+import static org.sonar.api.CoreProperties.SCM_PROVIDER_KEY;
+
 @Properties({
   @Property(
     key = ScmConfiguration.FORCE_RELOAD_KEY,
@@ -59,24 +62,28 @@ public class ScmConfiguration implements Startable {
 
   public static final String FORCE_RELOAD_KEY = "sonar.scm.forceReloadAll";
 
+  static final String MESSAGE_SCM_STEP_IS_DISABLED_BY_CONFIGURATION = "SCM Step is disabled by configuration";
+
   private final Configuration settings;
+  private final AnalysisWarnings analysisWarnings;
   private final Map<String, ScmProvider> providerPerKey = new LinkedHashMap<>();
   private final AnalysisMode analysisMode;
   private final InputModuleHierarchy moduleHierarchy;
 
   private ScmProvider provider;
 
-  public ScmConfiguration(InputModuleHierarchy moduleHierarchy, AnalysisMode analysisMode, Configuration settings, ScmProvider... providers) {
+  public ScmConfiguration(InputModuleHierarchy moduleHierarchy, AnalysisMode analysisMode, Configuration settings, AnalysisWarnings analysisWarnings, ScmProvider... providers) {
     this.moduleHierarchy = moduleHierarchy;
     this.analysisMode = analysisMode;
     this.settings = settings;
+    this.analysisWarnings = analysisWarnings;
     for (ScmProvider scmProvider : providers) {
       providerPerKey.put(scmProvider.key(), scmProvider);
     }
   }
 
-  public ScmConfiguration(InputModuleHierarchy moduleHierarchy, AnalysisMode analysisMode, Configuration settings) {
-    this(moduleHierarchy, analysisMode, settings, new ScmProvider[0]);
+  public ScmConfiguration(InputModuleHierarchy moduleHierarchy, AnalysisMode analysisMode, Configuration settings, AnalysisWarnings analysisWarnings) {
+    this(moduleHierarchy, analysisMode, settings, analysisWarnings, new ScmProvider[0]);
   }
 
   @Override
@@ -85,19 +92,21 @@ public class ScmConfiguration implements Startable {
       return;
     }
     if (isDisabled()) {
-      LOG.debug("SCM Step is disabled by configuration");
+      LOG.debug(MESSAGE_SCM_STEP_IS_DISABLED_BY_CONFIGURATION);
       return;
     }
-    if (settings.hasKey(CoreProperties.SCM_PROVIDER_KEY)) {
-      settings.get(CoreProperties.SCM_PROVIDER_KEY).ifPresent(this::setProviderIfSupported);
+    if (settings.hasKey(SCM_PROVIDER_KEY)) {
+      settings.get(SCM_PROVIDER_KEY).ifPresent(this::setProviderIfSupported);
     } else {
       autodetection();
       if (this.provider == null) {
         considerOldScmUrl();
       }
       if (this.provider == null) {
-        LOG.warn("SCM provider autodetection failed. No SCM provider claims to support this project. Please use " + CoreProperties.SCM_PROVIDER_KEY
-          + " to define SCM of your project.");
+        String message = "SCM provider autodetection failed. Please use \"" + SCM_PROVIDER_KEY + "\" to define SCM of " +
+          "your project, or disable the SCM Sensor in the project settings.";
+        LOG.warn(message);
+        analysisWarnings.addUnique(message);
       }
     }
   }
@@ -130,7 +139,7 @@ public class ScmConfiguration implements Startable {
           this.provider = installedProvider;
         } else {
           throw MessageException.of("SCM provider autodetection failed. Both " + this.provider.key() + " and " + installedProvider.key()
-            + " claim to support this project. Please use " + CoreProperties.SCM_PROVIDER_KEY + " to define SCM of your project.");
+            + " claim to support this project. Please use \"" + SCM_PROVIDER_KEY + "\" to define SCM of your project.");
         }
       }
     }
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmConfigurationTest.java
new file mode 100644 (file)
index 0000000..c4fbeac
--- /dev/null
@@ -0,0 +1,181 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * 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  02110-1301, USA.
+ */
+package org.sonar.scanner.scm;
+
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import java.util.Optional;
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.mockito.Answers;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.AnalysisMode;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
+import org.sonar.api.batch.scm.ScmProvider;
+import org.sonar.api.config.Configuration;
+import org.sonar.api.notifications.AnalysisWarnings;
+import org.sonar.api.utils.MessageException;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.core.config.ScannerProperties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+import static org.sonar.scanner.scm.ScmConfiguration.MESSAGE_SCM_STEP_IS_DISABLED_BY_CONFIGURATION;
+
+@RunWith(DataProviderRunner.class)
+public class ScmConfigurationTest {
+
+  private final InputModuleHierarchy inputModuleHierarchy = mock(InputModuleHierarchy.class, withSettings().defaultAnswer(Answers.RETURNS_MOCKS));
+  private final AnalysisMode analysisMode = mock(AnalysisMode.class);
+  private final AnalysisWarnings analysisWarnings = mock(AnalysisWarnings.class);
+  private final Configuration settings = mock(Configuration.class);
+
+  private final String scmProviderKey = "dummyScmProviderKey";
+  private final ScmProvider scmProvider = mock(ScmProvider.class);
+
+  private final ScmConfiguration underTest;
+
+  @Rule
+  public LogTester logTester = new LogTester();
+
+  @Rule
+  public ExpectedException thrown = ExpectedException.none();
+
+  public ScmConfigurationTest() {
+    when(analysisMode.isIssues()).thenReturn(false);
+    when(scmProvider.key()).thenReturn(scmProviderKey);
+
+    underTest = new ScmConfiguration(inputModuleHierarchy, analysisMode, settings, analysisWarnings, scmProvider);
+  }
+
+  @Test
+  public void do_not_register_warning_when_success_to_autodetect_scm_provider() {
+    when(scmProvider.supports(any())).thenReturn(true);
+
+    underTest.start();
+
+    assertThat(underTest.provider()).isNotNull();
+    verifyZeroInteractions(analysisWarnings);
+  }
+
+  @Test
+  public void register_warning_when_fail_to_detect_scm_provider() {
+    underTest.start();
+
+    assertThat(underTest.provider()).isNull();
+    verify(analysisWarnings).addUnique(anyString());
+  }
+
+  @Test
+  public void log_when_disabled() {
+    when(settings.getBoolean(CoreProperties.SCM_DISABLED_KEY)).thenReturn(Optional.of(true));
+
+    underTest.start();
+
+    assertThat(logTester.logs()).contains(MESSAGE_SCM_STEP_IS_DISABLED_BY_CONFIGURATION);
+  }
+
+  @Test
+  public void return_early_from_start_in_issues_mode() {
+    // return early = doesn't reach the logging when disabled
+    when(settings.getBoolean(CoreProperties.SCM_DISABLED_KEY)).thenReturn(Optional.of(true));
+    when(analysisMode.isIssues()).thenReturn(true);
+
+    underTest.start();
+
+    assertThat(logTester.logs()).isEmpty();
+  }
+
+  @Test
+  public void fail_when_multiple_scm_providers_claim_support() {
+    when(scmProvider.supports(any())).thenReturn(true);
+    when(scmProvider.key()).thenReturn("key1", "key2");
+
+    ScmProvider[] providers = {scmProvider, scmProvider};
+    ScmConfiguration underTest = new ScmConfiguration(inputModuleHierarchy, analysisMode, settings, analysisWarnings, providers);
+
+    thrown.expect(MessageException.class);
+    thrown.expectMessage(
+      new BaseMatcher<String>() {
+        @Override
+        public void describeTo(Description description) {
+
+        }
+
+        @Override
+        public boolean matches(Object item) {
+          return ((String) item).matches("SCM provider autodetection failed. "
+            + "Both .* and .* claim to support this project. "
+            + "Please use \"sonar.scm.provider\" to define SCM of your project.");
+        }
+      });
+
+    underTest.start();
+  }
+
+  @Test
+  public void fail_when_considerOldScmUrl_finds_invalid_provider_in_link() {
+    when(settings.get(ScannerProperties.LINKS_SOURCES_DEV)).thenReturn(Optional.of("scm:invalid"));
+
+    thrown.expect(IllegalArgumentException.class);
+    thrown.expectMessage("no SCM provider found for this key");
+
+    underTest.start();
+  }
+
+  @Test
+  public void set_provider_from_valid_link() {
+    when(settings.get(ScannerProperties.LINKS_SOURCES_DEV)).thenReturn(Optional.of("scm:" + scmProviderKey));
+
+    underTest.start();
+
+    assertThat(underTest.provider()).isSameAs(scmProvider);
+  }
+
+  @Test
+  @UseDataProvider("malformedScmLinks")
+  public void dont_set_provider_from_links_if_malformed(String link) {
+    when(settings.get(ScannerProperties.LINKS_SOURCES_DEV)).thenReturn(Optional.of(link));
+
+    underTest.start();
+
+    assertThat(underTest.provider()).isNull();
+  }
+
+  @DataProvider
+  public static Object[][] malformedScmLinks() {
+    return new Object[][] {
+      {"invalid prefix"},
+      {"scm"},
+      {"scm:"}
+    };
+  }
+}