Skip to content

Commit

Permalink
SCAN4NET-23: Exclude coverage files manually (#2161)
Browse files Browse the repository at this point in the history
  • Loading branch information
gregory-paidis-sonarsource committed Aug 30, 2024
1 parent 7048356 commit d6a9a59
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,105 @@ public void GenerateFile_JavaExePath_Cases(string setByUser, string resolved, st
config.JavaExePath.Should().Be(expected);
}

[TestMethod]
public void GenerateFile_ExcludeCoverage_ScanAllDisabled_Ignored()
{
var analysisDir = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
var settings = BuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir);
Directory.CreateDirectory(settings.SonarConfigDirectory);
var commandLineArguments = new ListPropertiesProvider([
new Property("sonar.cs.vscoveragexml.reportsPaths", "coverage1.xml"),
new Property("sonar.cs.dotcover.reportsPaths", "coverage2.xml"),
new Property("sonar.cs.opencover.reportsPaths", "coverage3.xml"),
new Property("sonar.exclusions", "foo.js"),
new Property(SonarProperties.ScanAllAnalysis, "false"),
]);
var args = CreateProcessedArgs(commandLineArguments, EmptyPropertyProvider.Instance, Substitute.For<ILogger>());

var config = AnalysisConfigGenerator.GenerateFile(args, settings, [], EmptyProperties, [], "1.2.3.4", string.Empty);

config.LocalSettings
.Should().ContainSingle(x => x.Id == "sonar.exclusions")
.Which.Value.Should().Be("foo.js");
}

[TestMethod]
public void GenerateFile_ExcludeCoverage_NotSpecified_ExclusionsUnchanged()
{
var analysisDir = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
var settings = BuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir);
Directory.CreateDirectory(settings.SonarConfigDirectory);
var commandLineArguments = new ListPropertiesProvider([new Property("sonar.exclusions", "foo.js")]);
var args = CreateProcessedArgs(commandLineArguments, EmptyPropertyProvider.Instance, Substitute.For<ILogger>());

var config = AnalysisConfigGenerator.GenerateFile(args, settings, [], EmptyProperties, [], "1.2.3.4", string.Empty);

config.LocalSettings
.Should().ContainSingle(x => x.Id == "sonar.exclusions")
.Which.Value.Should().Be("foo.js");
}

[DataTestMethod]
[DataRow("sonar.cs.vscoveragexml.reportsPaths")]
[DataRow("sonar.cs.dotcover.reportsPaths")]
[DataRow("sonar.cs.opencover.reportsPaths")]
public void GenerateFile_ExcludeCoverage_Exclusions_Exist_Cases(string propertyName)
{
var analysisDir = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
var settings = BuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir);
Directory.CreateDirectory(settings.SonarConfigDirectory);
var commandLineArguments = new ListPropertiesProvider([
new Property("sonar.exclusions", "foo.js"),
new Property(propertyName, "coverage.xml")
]);
var args = CreateProcessedArgs(commandLineArguments, EmptyPropertyProvider.Instance, Substitute.For<ILogger>());

var config = AnalysisConfigGenerator.GenerateFile(args, settings, [], EmptyProperties, [], "1.2.3.4", string.Empty);

config.LocalSettings
.Should().ContainSingle(x => x.Id == "sonar.exclusions")
.Which.Value.Should().Be("foo.js,coverage.xml");
}

[DataTestMethod]
[DataRow("sonar.cs.vscoveragexml.reportsPaths")]
[DataRow("sonar.cs.dotcover.reportsPaths")]
[DataRow("sonar.cs.opencover.reportsPaths")]
public void GenerateFile_ExcludeCoverage_Exclusions_DoesNotExist_Cases(string propertyName)
{
var analysisDir = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
var settings = BuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir);
Directory.CreateDirectory(settings.SonarConfigDirectory);
var commandLineArguments = new ListPropertiesProvider([new Property(propertyName, "coverage.xml")]);
var args = CreateProcessedArgs(commandLineArguments, EmptyPropertyProvider.Instance, Substitute.For<ILogger>());

var config = AnalysisConfigGenerator.GenerateFile(args, settings, [], EmptyProperties, [], "1.2.3.4", string.Empty);

config.LocalSettings
.Should().ContainSingle(x => x.Id == "sonar.exclusions")
.Which.Value.Should().Be("coverage.xml");
}

[TestMethod]
public void GenerateFile_ExcludeCoverage_Exclusions_MultipleSpecified()
{
var analysisDir = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
var settings = BuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir);
Directory.CreateDirectory(settings.SonarConfigDirectory);
var commandLineArguments = new ListPropertiesProvider([
new Property("sonar.cs.vscoveragexml.reportsPaths", "coverage1.xml"),
new Property("sonar.cs.dotcover.reportsPaths", "coverage2.xml,coverage3.xml"),
new Property("sonar.cs.opencover.reportsPaths", "coverage4.xml"),
]);
var args = CreateProcessedArgs(commandLineArguments, EmptyPropertyProvider.Instance, Substitute.For<ILogger>());

var config = AnalysisConfigGenerator.GenerateFile(args, settings, [], EmptyProperties, [], "1.2.3.4", string.Empty);

config.LocalSettings
.Should().ContainSingle(x => x.Id == "sonar.exclusions")
.Which.Value.Should().Be("coverage1.xml,coverage2.xml,coverage3.xml,coverage4.xml");
}

private void AssertConfigFileExists(AnalysisConfig config)
{
config.Should().NotBeNull("Supplied config should not be null");
Expand Down
34 changes: 33 additions & 1 deletion src/SonarScanner.MSBuild.PreProcessor/AnalysisConfigGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public static AnalysisConfig GenerateFile(ProcessedArgs localSettings,
{
AddSetting(config.ServerSettings, property.Key, property.Value);
}
foreach (var property in localSettings.CmdLineProperties.GetAllProperties()) // Only those from command line
foreach (var property in GetCommandLineProperties(localSettings)) // Only those from command line
{
AddSetting(config.LocalSettings, property.Id, property.Value);
}
Expand All @@ -108,4 +108,36 @@ private static void AddSetting(AnalysisProperties properties, string id, string
properties.Add(new(id, value));
}
}

// See https://sonarsource.atlassian.net/browse/SCAN4NET-29
// This method is a hack and should be removed when we properly support excluding coverage files in the scanner-engine.
// Instead, it should be replaced at the call site by "localSettings.CmdLineProperties.GetAllProperties()".
// The idea is that we are manually adding the coverage paths to the exclusions, so that they do not appear on the analysis.
private static List<Property> GetCommandLineProperties(ProcessedArgs localSettings)
{
HashSet<string> coveragePropertyNames =
[
"sonar.cs.vscoveragexml.reportsPaths",
"sonar.cs.dotcover.reportsPaths",
"sonar.cs.opencover.reportsPaths",
];
var allProperties = localSettings.CmdLineProperties.GetAllProperties().ToList();
var coveragePaths = string.Join(",", allProperties.Where(x => coveragePropertyNames.Contains(x.Id)).Select(x => x.Value));
if (!localSettings.ScanAllAnalysis // if scanAll analysis is disabled, we will not pick up the coverage files anyways
|| coveragePaths.Length == 0) // if there are no coverage files, there is nothing to exclude
{
return allProperties;
}

if (allProperties.Find(x => x.Id == "sonar.exclusions") is { } exclusionsProperty)
{
exclusionsProperty.Value = exclusionsProperty.Value + "," + coveragePaths;
}
else
{
allProperties.Add(new("sonar.exclusions", coveragePaths));
}

return allProperties;
}
}

0 comments on commit d6a9a59

Please sign in to comment.