aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-scanner-engine/src
diff options
context:
space:
mode:
Diffstat (limited to 'sonar-scanner-engine/src')
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java1
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java4
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java6
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java14
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactory.java7
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFiles.java43
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java73
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java9
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java5
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactoryTest.java3
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java40
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java125
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesTest.java54
13 files changed, 361 insertions, 23 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
index b9c7d779257..14e403f2a01 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
@@ -119,7 +119,6 @@ public class ModuleScanContainer extends ComponentContainer {
ExclusionFilters.class,
new MetadataGeneratorProvider(),
FileMetadata.class,
- StatusDetectionFactory.class,
LanguageDetection.class,
FileIndexer.class,
InputFileBuilder.class,
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
index 7deb3166880..fc34c441582 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ProjectScanContainer.java
@@ -93,9 +93,11 @@ import org.sonar.scanner.scan.branch.BranchType;
import org.sonar.scanner.scan.branch.ProjectBranchesProvider;
import org.sonar.scanner.scan.filesystem.BatchIdGenerator;
import org.sonar.scanner.scan.filesystem.InputComponentStoreProvider;
+import org.sonar.scanner.scan.filesystem.StatusDetectionFactory;
import org.sonar.scanner.scan.measure.DefaultMetricFinder;
import org.sonar.scanner.scan.measure.DeprecatedMetricFinder;
import org.sonar.scanner.scan.measure.MeasureCache;
+import org.sonar.scanner.scm.ScmChangedFilesProvider;
import org.sonar.scanner.storage.Storages;
public class ProjectScanContainer extends ComponentContainer {
@@ -157,6 +159,8 @@ public class ProjectScanContainer extends ComponentContainer {
new InputModuleHierarchyProvider(),
DefaultComponentTree.class,
BatchIdGenerator.class,
+ new ScmChangedFilesProvider(),
+ StatusDetectionFactory.class,
// rules
new ActiveRulesProvider(),
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
index f0bfe220d08..3ad3c9960ad 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java
@@ -62,15 +62,15 @@ class MetadataGenerator {
if (charsetDetector.run()) {
charset = charsetDetector.charset();
} else {
- LOG.debug("Failed to detect a valid charset for file '{}'. Using default charset.", inputFile.relativePath());
+ LOG.debug("Failed to detect a valid charset for file '{}'. Using default charset.", inputFile);
charset = defaultEncoding;
}
InputStream is = charsetDetector.inputStream();
inputFile.setCharset(charset);
Metadata metadata = fileMetadata.readMetadata(is, charset, inputFile.absolutePath(), exclusionsScanner.createCharHandlerFor(inputFile.key()));
inputFile.setMetadata(metadata);
- inputFile.setStatus(statusDetection.status(inputModule.definition().getKeyWithBranch(), inputFile.relativePath(), metadata.hash()));
- LOG.debug("'{}' generated metadata {} with charset '{}'", inputFile.relativePath(), inputFile.type() == Type.TEST ? "as test " : "", charset);
+ inputFile.setStatus(statusDetection.status(inputModule.definition().getKeyWithBranch(), inputFile, metadata.hash()));
+ LOG.debug("'{}' generated metadata {} with charset '{}'", inputFile, inputFile.type() == Type.TEST ? "as test " : "", charset);
} catch (Exception e) {
throw new IllegalStateException(e);
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java
index 79f3576e67b..b91a8165734 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetection.java
@@ -20,23 +20,26 @@
package org.sonar.scanner.scan.filesystem;
import javax.annotation.concurrent.Immutable;
-
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.scanner.repository.FileData;
import org.sonar.scanner.repository.ProjectRepositories;
+import org.sonar.scanner.scm.ScmChangedFiles;
@Immutable
class StatusDetection {
private final ProjectRepositories projectRepositories;
+ private final ScmChangedFiles scmChangedFiles;
- StatusDetection(ProjectRepositories projectSettings) {
+ StatusDetection(ProjectRepositories projectSettings, ScmChangedFiles scmChangedFiles) {
this.projectRepositories = projectSettings;
+ this.scmChangedFiles = scmChangedFiles;
}
- InputFile.Status status(String projectKeyWithBranch, String relativePath, String hash) {
- FileData fileDataPerPath = projectRepositories.fileData(projectKeyWithBranch, relativePath);
+ InputFile.Status status(String projectKeyWithBranch, DefaultInputFile inputFile, String hash) {
+ FileData fileDataPerPath = projectRepositories.fileData(projectKeyWithBranch, inputFile.relativePath());
if (fileDataPerPath == null) {
return InputFile.Status.ADDED;
}
@@ -47,6 +50,9 @@ class StatusDetection {
if (StringUtils.isEmpty(previousHash)) {
return InputFile.Status.ADDED;
}
+ if (!scmChangedFiles.confirmChanged(inputFile.path())) {
+ return InputFile.Status.SAME;
+ }
return InputFile.Status.CHANGED;
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactory.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactory.java
index e4eabe778d4..b1cdf614e6b 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactory.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactory.java
@@ -21,17 +21,20 @@ package org.sonar.scanner.scan.filesystem;
import org.sonar.api.batch.ScannerSide;
import org.sonar.scanner.repository.ProjectRepositories;
+import org.sonar.scanner.scm.ScmChangedFiles;
@ScannerSide
public class StatusDetectionFactory {
private final ProjectRepositories projectReferentials;
+ private final ScmChangedFiles scmChangedFiles;
- public StatusDetectionFactory(ProjectRepositories projectReferentials) {
+ public StatusDetectionFactory(ProjectRepositories projectReferentials, ScmChangedFiles scmChangedFiles) {
this.projectReferentials = projectReferentials;
+ this.scmChangedFiles = scmChangedFiles;
}
StatusDetection create() {
- return new StatusDetection(projectReferentials);
+ return new StatusDetection(projectReferentials, scmChangedFiles);
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFiles.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFiles.java
new file mode 100644
index 00000000000..d4dcdd9ac00
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFiles.java
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 java.nio.file.Path;
+import java.util.Collection;
+import javax.annotation.Nullable;
+import javax.annotation.concurrent.Immutable;
+
+@Immutable
+public class ScmChangedFiles {
+ @Nullable
+ private final Collection<Path> fileCollection;
+
+ public ScmChangedFiles(@Nullable Collection<Path> changedFiles) {
+ this.fileCollection = changedFiles;
+ }
+
+ public boolean verifyChanged(Path file) {
+ return fileCollection == null || fileCollection.contains(file);
+ }
+
+ Collection<Path> get() {
+ return fileCollection;
+ }
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java
new file mode 100644
index 00000000000..60b87a1fc0a
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmChangedFilesProvider.java
@@ -0,0 +1,73 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 java.nio.file.Path;
+import java.util.Collection;
+import javax.annotation.CheckForNull;
+import org.picocontainer.annotations.Nullable;
+import org.picocontainer.injectors.ProviderAdapter;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
+import org.sonar.api.batch.scm.ScmBranchProvider;
+import org.sonar.api.batch.scm.ScmProvider;
+import org.sonar.scanner.scan.branch.BranchConfiguration;
+
+public class ScmChangedFilesProvider extends ProviderAdapter {
+ private static final Logger LOG = LoggerFactory.getLogger(ScmChangedFilesProvider.class);
+
+ private ScmChangedFiles scmBranchChangedFiles;
+
+ /*
+ * ScmConfiguration is not available in issues mode
+ */
+ public ScmChangedFiles provide(@Nullable ScmConfiguration scmConfiguration, BranchConfiguration branchConfiguration, InputModuleHierarchy inputModuleHierarchy) {
+ if (scmBranchChangedFiles == null) {
+ if (scmConfiguration == null) {
+ scmBranchChangedFiles = new ScmChangedFiles(null);
+ } else {
+ Path rootBaseDir = inputModuleHierarchy.root().getBaseDir();
+ Collection<Path> changedFiles = loadChangedFilesIfNeeded(scmConfiguration, branchConfiguration, rootBaseDir);
+ scmBranchChangedFiles = new ScmChangedFiles(changedFiles);
+ }
+ }
+ return scmBranchChangedFiles;
+ }
+
+ @CheckForNull
+ private static Collection<Path> loadChangedFilesIfNeeded(ScmConfiguration scmConfiguration, BranchConfiguration branchConfiguration, Path rootBaseDir) {
+ if (branchConfiguration.isShortLivingBranch()) {
+ ScmProvider scmProvider = scmConfiguration.provider();
+ if (scmProvider != null && (scmProvider instanceof ScmBranchProvider)) {
+ ScmBranchProvider scmBranchProvider = (ScmBranchProvider) scmProvider;
+ Collection<Path> changedFiles = scmBranchProvider.branchChangedFiles(branchConfiguration.branchTarget(), rootBaseDir);
+ if (changedFiles != null) {
+ LOG.debug("SCM reported {} files changed in the branch", changedFiles.size());
+ return changedFiles;
+ }
+ }
+
+ LOG.debug("SCM information about changed files in the branch is not available");
+ }
+ return null;
+ }
+
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java
index ef380a0c74e..f34abc0eba6 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scm/ScmConfiguration.java
@@ -19,9 +19,10 @@
*/
package org.sonar.scanner.scm;
-import com.google.common.base.Joiner;
import java.util.LinkedHashMap;
import java.util.Map;
+import java.util.stream.Collectors;
+import javax.annotation.CheckForNull;
import org.apache.commons.lang.StringUtils;
import org.picocontainer.Startable;
import org.sonar.api.CoreProperties;
@@ -51,7 +52,7 @@ import org.sonar.api.utils.log.Loggers;
})
@InstantiationStrategy(InstantiationStrategy.PER_BATCH)
@ScannerSide
-public final class ScmConfiguration implements Startable {
+public class ScmConfiguration implements Startable {
private static final Logger LOG = Loggers.get(ScmConfiguration.class);
public static final String FORCE_RELOAD_KEY = "sonar.scm.forceReloadAll";
@@ -103,7 +104,8 @@ public final class ScmConfiguration implements Startable {
if (providerPerKey.containsKey(forcedProviderKey)) {
this.provider = providerPerKey.get(forcedProviderKey);
} else {
- String supportedProviders = providerPerKey.isEmpty() ? "No SCM provider installed" : ("Supported SCM providers are " + Joiner.on(",").join(providerPerKey.keySet()));
+ String supportedProviders = providerPerKey.isEmpty() ? "No SCM provider installed"
+ : ("Supported SCM providers are " + providerPerKey.keySet().stream().collect(Collectors.joining(",")));
throw new IllegalArgumentException("SCM provider was set to \"" + forcedProviderKey + "\" but no SCM provider found for this key. " + supportedProviders);
}
}
@@ -132,6 +134,7 @@ public final class ScmConfiguration implements Startable {
}
}
+ @CheckForNull
public ScmProvider provider() {
return provider;
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
index 27fa5362f54..2dd1961963c 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java
@@ -140,11 +140,10 @@ public class MetadataGeneratorTest {
FileUtils.write(srcFile.toFile(), "single line");
// status
- when(statusDetection.status("foo", "src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a"))
+ DefaultInputFile inputFile = createInputFileWithMetadata(baseDir, "src/main/java/foo/Bar.java");
+ when(statusDetection.status("foo", inputFile, "6c1d64c0b3555892fe7273e954f6fb5a"))
.thenReturn(InputFile.Status.ADDED);
- InputFile inputFile = createInputFileWithMetadata(baseDir, "src/main/java/foo/Bar.java");
-
assertThat(inputFile.type()).isEqualTo(InputFile.Type.MAIN);
assertThat(inputFile.file()).isEqualTo(srcFile.toFile());
assertThat(inputFile.absolutePath()).isEqualTo(PathUtils.sanitize(srcFile.toAbsolutePath().toString()));
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactoryTest.java
index 160580763f0..259b5e5a653 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactoryTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionFactoryTest.java
@@ -21,6 +21,7 @@ package org.sonar.scanner.scan.filesystem;
import org.junit.Test;
import org.sonar.scanner.repository.ProjectRepositories;
+import org.sonar.scanner.scm.ScmChangedFiles;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -28,7 +29,7 @@ import static org.mockito.Mockito.mock;
public class StatusDetectionFactoryTest {
@Test
public void testCreate() throws Exception {
- StatusDetectionFactory factory = new StatusDetectionFactory(mock(ProjectRepositories.class));
+ StatusDetectionFactory factory = new StatusDetectionFactory(mock(ProjectRepositories.class), mock(ScmChangedFiles.class));
StatusDetection detection = factory.create();
assertThat(detection).isNotNull();
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java
index a295fdc08be..bcf70eb65d7 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/StatusDetectionTest.java
@@ -22,23 +22,47 @@ package org.sonar.scanner.scan.filesystem;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.ImmutableTable;
import com.google.common.collect.Table;
+import java.nio.file.Paths;
+import java.util.Collections;
import org.junit.Test;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.scanner.repository.FileData;
import org.sonar.scanner.repository.ProjectRepositories;
+import org.sonar.scanner.scm.ScmChangedFiles;
import static org.assertj.core.api.Assertions.assertThat;
public class StatusDetectionTest {
@Test
public void detect_status() {
- Table<String, String, String> t = ImmutableTable.of();
- ProjectRepositories ref = new ProjectRepositories(t, createTable(), null);
- StatusDetection statusDetection = new StatusDetection(ref);
+ ProjectRepositories ref = new ProjectRepositories(ImmutableTable.of(), createTable(), null);
+ ScmChangedFiles changedFiles = new ScmChangedFiles(null);
+ StatusDetection statusDetection = new StatusDetection(ref, changedFiles);
- assertThat(statusDetection.status("foo", "src/Foo.java", "ABCDE")).isEqualTo(InputFile.Status.SAME);
- assertThat(statusDetection.status("foo", "src/Foo.java", "XXXXX")).isEqualTo(InputFile.Status.CHANGED);
- assertThat(statusDetection.status("foo", "src/Other.java", "QWERT")).isEqualTo(InputFile.Status.ADDED);
+ assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "ABCDE")).isEqualTo(InputFile.Status.SAME);
+ assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "XXXXX")).isEqualTo(InputFile.Status.CHANGED);
+ assertThat(statusDetection.status("foo", createFile("src/Other.java"), "QWERT")).isEqualTo(InputFile.Status.ADDED);
+ }
+
+ @Test
+ public void detect_status_branches_exclude() {
+ ProjectRepositories ref = new ProjectRepositories(ImmutableTable.of(), createTable(), null);
+ ScmChangedFiles changedFiles = new ScmChangedFiles(Collections.emptyList());
+ StatusDetection statusDetection = new StatusDetection(ref, changedFiles);
+
+ // normally changed
+ assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "XXXXX")).isEqualTo(InputFile.Status.SAME);
+ }
+
+ @Test
+ public void detect_status_branches_confirm() {
+ ProjectRepositories ref = new ProjectRepositories(ImmutableTable.of(), createTable(), null);
+ ScmChangedFiles changedFiles = new ScmChangedFiles(Collections.singletonList(Paths.get("module", "src", "Foo.java")));
+ StatusDetection statusDetection = new StatusDetection(ref, changedFiles);
+
+ assertThat(statusDetection.status("foo", createFile("src/Foo.java"), "XXXXX")).isEqualTo(InputFile.Status.CHANGED);
}
private static Table<String, String, FileData> createTable() {
@@ -49,4 +73,8 @@ public class StatusDetectionTest {
return t;
}
+
+ private static DefaultInputFile createFile(String relativePath) {
+ return new TestInputFileBuilder("module", relativePath).build();
+ }
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java
new file mode 100644
index 00000000000..6777aaa7333
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesProviderTest.java
@@ -0,0 +1,125 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
+import org.sonar.api.batch.scm.ScmBranchProvider;
+import org.sonar.api.batch.scm.ScmProvider;
+import org.sonar.scanner.scan.branch.BranchConfiguration;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
+
+public class ScmChangedFilesProviderTest {
+ @Mock
+ private ScmConfiguration scmConfiguration;
+ @Mock
+ private BranchConfiguration branchConfiguration;
+ @Mock
+ private InputModuleHierarchy inputModuleHierarchy;
+ @Mock
+ private ScmBranchProvider scmProvider;
+
+ private Path rootBaseDir = Paths.get("root");
+ private ScmChangedFilesProvider provider;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ DefaultInputModule root = mock(DefaultInputModule.class);
+ when(root.getBaseDir()).thenReturn(rootBaseDir);
+ when(inputModuleHierarchy.root()).thenReturn(root);
+ provider = new ScmChangedFilesProvider();
+ }
+
+ @Test
+ public void testNoScmProvider() {
+ when(branchConfiguration.isShortLivingBranch()).thenReturn(true);
+ ScmChangedFiles scmChangedFiles = provider.provide(scmConfiguration, branchConfiguration, inputModuleHierarchy);
+
+ assertThat(scmChangedFiles.get()).isNull();
+ verify(scmConfiguration).provider();
+ }
+
+ @Test
+ public void testProviderDoesntSupport() {
+ when(branchConfiguration.branchTarget()).thenReturn("target");
+ when(branchConfiguration.isShortLivingBranch()).thenReturn(true);
+ when(scmConfiguration.provider()).thenReturn(scmProvider);
+ when(scmProvider.branchChangedFiles("target", rootBaseDir)).thenReturn(null);
+ ScmChangedFiles scmChangedFiles = provider.provide(scmConfiguration, branchConfiguration, inputModuleHierarchy);
+
+ assertThat(scmChangedFiles.get()).isNull();
+ verify(scmProvider).branchChangedFiles("target", rootBaseDir);
+ }
+
+ @Test
+ public void testNoOpInNonShortLivedBranch() {
+ when(branchConfiguration.isShortLivingBranch()).thenReturn(false);
+ ScmChangedFiles scmChangedFiles = provider.provide(scmConfiguration, branchConfiguration, inputModuleHierarchy);
+
+ assertThat(scmChangedFiles.get()).isNull();
+ verifyZeroInteractions(scmConfiguration);
+ }
+
+ @Test
+ public void testLegacyScmProvider() {
+ ScmProvider legacy = mock(ScmProvider.class);
+ when(scmConfiguration.provider()).thenReturn(legacy);
+ when(branchConfiguration.isShortLivingBranch()).thenReturn(true);
+
+ ScmChangedFiles scmChangedFiles = provider.provide(scmConfiguration, branchConfiguration, inputModuleHierarchy);
+
+ assertThat(scmChangedFiles.get()).isNull();
+ verify(scmConfiguration).provider();
+ verifyZeroInteractions(legacy);
+ }
+
+ @Test
+ public void testReturnChangedFiles() {
+ when(branchConfiguration.branchTarget()).thenReturn("target");
+ when(branchConfiguration.isShortLivingBranch()).thenReturn(true);
+ when(scmConfiguration.provider()).thenReturn(scmProvider);
+ when(scmProvider.branchChangedFiles("target", rootBaseDir)).thenReturn(Collections.singletonList(Paths.get("changedFile")));
+ ScmChangedFiles scmChangedFiles = provider.provide(scmConfiguration, branchConfiguration, inputModuleHierarchy);
+
+ assertThat(scmChangedFiles.get()).containsOnly(Paths.get("changedFile"));
+ verify(scmProvider).branchChangedFiles("target", rootBaseDir);
+ }
+
+ @Test
+ public void testCacheObject() {
+ provider.provide(scmConfiguration, branchConfiguration, inputModuleHierarchy);
+ provider.provide(scmConfiguration, branchConfiguration, inputModuleHierarchy);
+ verify(branchConfiguration).isShortLivingBranch();
+ }
+
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesTest.java
new file mode 100644
index 00000000000..ec1ce40a091
--- /dev/null
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/ScmChangedFilesTest.java
@@ -0,0 +1,54 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 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 java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.Collections;
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class ScmChangedFilesTest {
+ private ScmChangedFiles scmChangedFiles;
+
+ @Test
+ public void testGetter() {
+ Collection<Path> files = Collections.singletonList(Paths.get("files"));
+ scmChangedFiles = new ScmChangedFiles(files);
+ assertThat(scmChangedFiles.get()).containsOnly(Paths.get("files"));
+ }
+
+ @Test
+ public void testNullable() {
+ scmChangedFiles = new ScmChangedFiles(null);
+ assertThat(scmChangedFiles.get()).isNull();
+ assertThat(scmChangedFiles.verifyChanged(Paths.get("files2"))).isTrue();
+ }
+
+ @Test
+ public void testConfirm() {
+ Collection<Path> files = Collections.singletonList(Paths.get("files"));
+ scmChangedFiles = new ScmChangedFiles(files);
+ assertThat(scmChangedFiles.verifyChanged(Paths.get("files"))).isTrue();
+ assertThat(scmChangedFiles.verifyChanged(Paths.get("files2"))).isFalse();
+ }
+}