Skip to content

Commit a964dca

Browse files
SCAN4NET-929 Set UseSonarScannerCli when in TFS Legacy build (#2846)
Co-authored-by: Martin Strecker <martin.strecker@sonarsource.com>
1 parent 5efb931 commit a964dca

File tree

21 files changed

+211
-87
lines changed

21 files changed

+211
-87
lines changed

Tests/SonarScanner.MSBuild.PostProcessor.Test/PostProcessorTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public class PostProcessorTests
4949
public PostProcessorTests(TestContext testContext)
5050
{
5151
this.testContext = testContext;
52-
settings = BuildSettings.CreateNonTeamBuildSettingsForTesting(TestUtils.CreateTestSpecificFolderWithSubPaths(testContext));
52+
settings = BuildSettings.CreateSettingsForTesting(TestUtils.CreateTestSpecificFolderWithSubPaths(testContext));
5353
Directory.CreateDirectory(settings.SonarOutputDirectory);
5454
config = new()
5555
{

Tests/SonarScanner.MSBuild.PreProcessor.Test/AnalysisConfigProcessing/AnalysisConfigGeneratorTests.cs

Lines changed: 75 additions & 25 deletions
Large diffs are not rendered by default.

Tests/SonarScanner.MSBuild.PreProcessor.Test/AnalysisConfigProcessing/Processors/TruststorePropertiesProcessorTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,5 +482,6 @@ private static ProcessedArgs CreateProcessedArgs(IAnalysisPropertyProvider cmdLi
482482
cmdLineProvider ?? EmptyPropertyProvider.Instance,
483483
Substitute.For<IAnalysisPropertyProvider>(),
484484
EmptyPropertyProvider.Instance,
485+
null,
485486
new TestRuntime { File = fileWrapper ?? Substitute.For<IFileWrapper>() });
486487
}

Tests/SonarScanner.MSBuild.PreProcessor.Test/ArgumentProcessorTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public class ArgumentProcessorTests
3333

3434
[TestMethod]
3535
public void PreArgProc_NullRuntimeThrows() =>
36-
FluentActions.Invoking(() => ArgumentProcessor.TryProcessArgs(null, null)).Should().ThrowExactly<ArgumentNullException>().WithParameterName("runtime");
36+
FluentActions.Invoking(() => ArgumentProcessor.TryProcessArgs(null, null, null)).Should().ThrowExactly<ArgumentNullException>().WithParameterName("runtime");
3737

3838
[TestMethod]
3939
public void PreArgProc_RequiredArguments_ProcessingSucceeds()
@@ -945,7 +945,7 @@ private static TestRuntime CheckProcessingFails(params string[] commandLineArgs)
945945

946946
private static void CheckProcessingFails(TestRuntime runtime, params string[] commandLineArgs)
947947
{
948-
var result = ArgumentProcessor.TryProcessArgs(commandLineArgs, runtime);
948+
var result = ArgumentProcessor.TryProcessArgs(commandLineArgs, null, runtime);
949949

950950
result.Should().BeNull();
951951
runtime.Logger.Should().HaveErrors();
@@ -956,7 +956,7 @@ private static ProcessedArgs CheckProcessingSucceeds(params string[] commandLine
956956

957957
private static ProcessedArgs CheckProcessingSucceeds(TestRuntime runtime, params string[] commandLineArgs)
958958
{
959-
var result = ArgumentProcessor.TryProcessArgs(commandLineArgs, runtime);
959+
var result = ArgumentProcessor.TryProcessArgs(commandLineArgs, null, runtime);
960960
result.Should().NotBeNull();
961961
runtime.Logger.Should().HaveNoErrors();
962962
return result;

Tests/SonarScanner.MSBuild.PreProcessor.Test/CacheProcessorTests.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public void PullRequestCacheBasePath_ProjectBaseDir_HasPriority_IsAbsolute()
9696
{
9797
var workingDirectory = TestContext.ResultsDirectory;
9898
using var scope = new WorkingDirectoryScope(workingDirectory);
99-
var localSettings = ArgumentProcessor.TryProcessArgs(["/k:key", "/d:sonar.projectBaseDir=Custom"], new TestRuntime { Logger = logger });
99+
var localSettings = ArgumentProcessor.TryProcessArgs(["/k:key", "/d:sonar.projectBaseDir=Custom"], null, new TestRuntime { Logger = logger });
100100
var buildSettings = Substitute.For<IBuildSettings>();
101101
buildSettings.SourcesDirectory.Returns(@"C:\Sources\Directory");
102102
buildSettings.SonarScannerWorkingDirectory.Returns(@"C:\SonarScanner\WorkingDirectory");
@@ -271,7 +271,7 @@ private static ProcessedArgs CreateProcessedArgs(TestLogger logger, string comma
271271
{
272272
// When CI is run for a PR, AzureDevOps extension sets this to the actual PR analysis of S4NET project.
273273
using var scope = new EnvironmentVariableScope().SetVariable("SONARQUBE_SCANNER_PARAMS", null);
274-
var processedArgs = ArgumentProcessor.TryProcessArgs(commandLineArgs.Split(' '), new TestRuntime { Logger = logger });
274+
var processedArgs = ArgumentProcessor.TryProcessArgs(commandLineArgs.Split(' '), null, new TestRuntime { Logger = logger });
275275
processedArgs.Should().NotBeNull();
276276
return processedArgs;
277277
}

Tests/SonarScanner.MSBuild.PreProcessor.Test/JreResolution/JreResolverTests.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -411,18 +411,9 @@ public async Task Args_IsValid_Priority()
411411
}
412412
}
413413

414-
private ProcessedArgs Args()
414+
private static ProcessedArgs Args()
415415
{
416-
var args = Substitute.For<ProcessedArgs>(
417-
"valid.key",
418-
"valid.name",
419-
"1.0",
420-
"organization",
421-
false,
422-
provider,
423-
EmptyPropertyProvider.Instance,
424-
EmptyPropertyProvider.Instance,
425-
runtime with { Logger = new() }); // using a new logger to avoid message pollution
416+
var args = Substitute.For<ProcessedArgs>();
426417
args.OperatingSystem.Returns("os");
427418
args.Architecture.Returns("arch");
428419
return args;

Tests/SonarScanner.MSBuild.PreProcessor.Test/JreResolution/LocalJreTruststoreResolverTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,5 +323,6 @@ private static ProcessedArgs CreateProcessedArgs(TestRuntime runtime, IAnalysisP
323323
cmdLineProvider ?? EmptyPropertyProvider.Instance,
324324
Substitute.For<IAnalysisPropertyProvider>(),
325325
EmptyPropertyProvider.Instance,
326+
null,
326327
runtime with { Logger = new() }); // new logger to avoid log pollution
327328
}

Tests/SonarScanner.MSBuild.PreProcessor.Test/PreProcessorTests.cs

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public async Task Execute_EndToEnd_SuccessCase()
164164
(await context.Execute()).Should().BeTrue();
165165

166166
context.AssertDirectoriesCreated();
167-
context.AssertDownloadMethodsCalled(1, 1, 2, 2);
167+
context.AssertDownloadMethodsCalled(properties: 1, allLanguages: 1, qualityProfile: 2, rules: 2);
168168

169169
context.Factory.Runtime.Logger.Should().HaveInfos("Cache data is empty. A full analysis will be performed.")
170170
.And.HaveDebugs("Processing analysis cache");
@@ -195,7 +195,7 @@ public async Task Execute_CreateCustomTempCachePath_SuccessCase()
195195
(await context.Execute(args)).Should().BeTrue();
196196

197197
context.AssertDirectoriesCreated();
198-
context.AssertDownloadMethodsCalled(1, 1, 2, 2);
198+
context.AssertDownloadMethodsCalled(properties: 1, allLanguages: 1, qualityProfile: 2, rules: 2);
199199

200200
context.Factory.AssertMethodCalled(nameof(context.Factory.CreateRoslynAnalyzerProvider), 2); // C# and VBNet
201201
context.Factory.PluginCachePath.Should().Be(tmpCachePath);
@@ -216,7 +216,7 @@ public async Task Execute_EndToEnd_SuccessCase_NoActiveRule()
216216
(await context.Execute()).Should().BeTrue();
217217

218218
context.AssertDirectoriesCreated();
219-
context.AssertDownloadMethodsCalled(1, 1, 2, 2);
219+
context.AssertDownloadMethodsCalled(properties: 1, allLanguages: 1, qualityProfile: 2, rules: 2);
220220
context.AssertAnalysisConfig(2);
221221
}
222222

@@ -234,10 +234,23 @@ public async Task Execute_EndToEnd_SuccessCase_With_Organization()
234234
(await context.Execute(CreateArgs("organization"))).Should().BeTrue();
235235

236236
context.AssertDirectoriesCreated();
237-
context.AssertDownloadMethodsCalled(1, 1, 2, 2);
237+
context.AssertDownloadMethodsCalled(properties: 1, allLanguages: 1, qualityProfile: 2, rules: 2);
238238
context.AssertAnalysisConfig(2);
239239
}
240240

241+
[TestMethod]
242+
public async Task Execute_EndToEnd_UseCli_SuccessCase()
243+
{
244+
using var context = new Context(TestContext);
245+
var args = new List<string>(CreateArgs()) { "/d:sonar.scanner.useSonarScannerCLI=true" };
246+
(await context.Execute(args)).Should().BeTrue();
247+
248+
context.AssertDirectoriesCreated();
249+
context.AssertDownloadMethodsCalled(properties: 1, allLanguages: 1, qualityProfile: 2, rules: 2);
250+
context.AssertAnalysisConfig(2);
251+
await context.Factory.EngineResolver.DidNotReceiveWithAnyArgs().ResolvePath(null);
252+
}
253+
241254
[TestMethod]
242255
public async Task Execute_NoPlugin_ReturnsFalseAndLogsError()
243256
{
@@ -268,7 +281,7 @@ public async Task Execute_NoProject_ReturnsTrue()
268281
(await context.Execute()).Should().BeTrue();
269282

270283
context.AssertDirectoriesCreated();
271-
context.AssertDownloadMethodsCalled(1, 1, 2, 0); // no quality profile assigned to project
284+
context.AssertDownloadMethodsCalled(properties: 1, allLanguages: 1, qualityProfile: 2, rules: 0); // no quality profile assigned to project
272285
context.AssertAnalysisConfig(0);
273286
// only contains SonarQubeAnalysisConfig (no rulesets or additional files)
274287
context.AssertAnalysisConfigPathInSonarConfigDirectory();

Tests/SonarScanner.MSBuild.PreProcessor.Test/PreprocessorObjectFactoryTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,15 +193,15 @@ public async Task CreateSonarWebService_WithFailedAuthentication_ReturnsNullAndL
193193
public void CreateRoslynAnalyzerProvider_Success()
194194
{
195195
var sut = new PreprocessorObjectFactory(runtime);
196-
var settings = BuildSettings.CreateNonTeamBuildSettingsForTesting(TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext));
196+
var settings = BuildSettings.CreateSettingsForTesting(TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext));
197197
sut.CreateRoslynAnalyzerProvider(Substitute.For<ISonarWebServer>(), "cache", settings, new ListPropertiesProvider(), [], "cs").Should().NotBeNull();
198198
}
199199

200200
[TestMethod]
201201
public void CreateRoslynAnalyzerProvider_NullServer_ThrowsArgumentNullException()
202202
{
203203
var sut = new PreprocessorObjectFactory(runtime);
204-
var settings = BuildSettings.CreateNonTeamBuildSettingsForTesting(TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext));
204+
var settings = BuildSettings.CreateSettingsForTesting(TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext));
205205
FluentActions.Invoking(() => sut.CreateRoslynAnalyzerProvider(null, "cache", settings, new ListPropertiesProvider(), [], "cs")).Should()
206206
.ThrowExactly<ArgumentNullException>()
207207
.WithParameterName("server");
@@ -219,6 +219,7 @@ private ProcessedArgs CreateValidArguments(string hostUrl = "http://myhost:222",
219219
cmdLineArgs,
220220
new ListPropertiesProvider(),
221221
EmptyPropertyProvider.Instance,
222+
null,
222223
runtime);
223224
}
224225
}

Tests/SonarScanner.MSBuild.PreProcessor.Test/ProcessedArgsTests.cs

Lines changed: 50 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ public void ProcessedArgs_ParameterThrow_CmdLineProperties() =>
7676
cmdLineProperties: null,
7777
EmptyPropertyProvider.Instance,
7878
EmptyPropertyProvider.Instance,
79+
buildSettings: null,
7980
runtime))
8081
.Should().Throw<ArgumentNullException>()
8182
.WithParameterName("cmdLineProperties");
@@ -92,6 +93,7 @@ public void ProcessedArgs_ParameterThrow_GlobalFileProperties() =>
9293
EmptyPropertyProvider.Instance,
9394
globalFileProperties: null,
9495
EmptyPropertyProvider.Instance,
96+
buildSettings: null,
9597
runtime))
9698
.Should().Throw<ArgumentNullException>()
9799
.WithParameterName("globalFileProperties");
@@ -108,6 +110,7 @@ public void ProcessedArgs_ParameterThrow_ScannerEnvProperties() =>
108110
EmptyPropertyProvider.Instance,
109111
EmptyPropertyProvider.Instance,
110112
scannerEnvProperties: null,
113+
buildSettings: null,
111114
runtime))
112115
.Should().Throw<ArgumentNullException>()
113116
.WithParameterName("scannerEnvProperties");
@@ -210,8 +213,8 @@ public void ProcessedArgs_HostUrl_SonarCloudUrl_HostUrlSet()
210213
sut.ServerInfo.Should().NotBeNull();
211214
sut.ServerInfo.IsSonarCloud.Should().BeFalse();
212215
sut.ServerInfo.ServerUrl.Should().Be("http://host");
213-
runtime.Logger.Warnings.Should().BeEmpty();
214-
runtime.Logger.Errors.Should().BeEmpty();
216+
runtime.Logger.Should().HaveNoWarnings()
217+
.And.HaveNoErrors();
215218
sut.IsValid.Should().BeTrue();
216219
}
217220

@@ -223,8 +226,8 @@ public void ProcessedArgs_HostUrl_SonarCloudUrl_SonarCloudUrlSet()
223226
sut.ServerInfo.Should().NotBeNull();
224227
sut.ServerInfo.IsSonarCloud.Should().BeTrue();
225228
sut.ServerInfo.ServerUrl.Should().Be("https://sonarcloud.proxy");
226-
runtime.Logger.Warnings.Should().BeEmpty();
227-
runtime.Logger.Errors.Should().BeEmpty();
229+
runtime.Logger.Should().HaveNoWarnings()
230+
.And.HaveNoErrors();
228231
sut.IsValid.Should().BeTrue();
229232
}
230233

@@ -278,8 +281,8 @@ public void ProcessedArgs_HostUrl_SonarCloudUrl_HostUrlAndSonarcloudUrlMissing()
278281
sut.ServerInfo.Should().NotBeNull();
279282
sut.ServerInfo.IsSonarCloud.Should().BeTrue();
280283
sut.ServerInfo.ServerUrl.Should().Be("https://sonarcloud.io");
281-
runtime.Logger.Warnings.Should().BeEmpty();
282-
runtime.Logger.Errors.Should().BeEmpty();
284+
runtime.Logger.Should().HaveNoWarnings()
285+
.And.HaveNoErrors();
283286
sut.IsValid.Should().BeTrue();
284287
}
285288

@@ -311,8 +314,8 @@ public void ProcessedArgs_HostUrl_SonarCloudUrl_HostUrlIsAnySonarCloud(string ho
311314
Region = expectedRegion,
312315
},
313316
});
314-
runtime.Logger.Warnings.Should().BeEmpty();
315-
runtime.Logger.Errors.Should().BeEmpty();
317+
runtime.Logger.Should().HaveNoWarnings()
318+
.And.HaveNoErrors();
316319
}
317320

318321
[TestMethod]
@@ -323,8 +326,8 @@ public void ProcessedArgs_HostUrl_SonarCloudUrl_PropertyAggregation()
323326
new ListPropertiesProvider([new Property(SonarProperties.SonarcloudUrl, "https://sonarcloud.io")]));
324327

325328
sut.ServerInfo.Should().BeNull();
326-
runtime.Logger.Warnings.Should().BeEmpty();
327-
runtime.Logger.Should().HaveErrors("The arguments 'sonar.host.url' and 'sonar.scanner.sonarcloudUrl' are both set and are different. "
329+
runtime.Logger.Should().HaveNoWarnings()
330+
.And.HaveErrors("The arguments 'sonar.host.url' and 'sonar.scanner.sonarcloudUrl' are both set and are different. "
328331
+ "Please set either 'sonar.host.url' for SonarQube or 'sonar.scanner.sonarcloudUrl' for SonarCloud.");
329332
sut.IsValid.Should().BeFalse();
330333
}
@@ -360,6 +363,7 @@ public void ProcessedArgs_ErrorAndIsValid(bool invalidKey, bool invalidOrganizat
360363
: EmptyPropertyProvider.Instance,
361364
globalFileProperties: invalidOrganization ? new ListPropertiesProvider([new Property(SonarProperties.Organization, "organization")]) : EmptyPropertyProvider.Instance,
362365
scannerEnvProperties: new ListPropertiesProvider([new Property(SonarProperties.UserHome, "NotADirectory")]),
366+
buildSettings: null,
363367
runtime);
364368
runtime.Logger.Errors.Should().HaveCount(errors);
365369
sut.IsValid.Should().Be(errors == 0);
@@ -475,11 +479,43 @@ public void ProcessedArgs_SourcesOrTests_Warning(params Property[] properties)
475479
var sut = CreateDefaultArgs(new ListPropertiesProvider(properties));
476480

477481
sut.IsValid.Should().BeTrue();
478-
runtime.Logger.Errors.Should().BeEmpty();
479-
runtime.Logger.Warnings.Should().ContainSingle(expectedMessage);
482+
runtime.Logger.Should().HaveNoErrors()
483+
.And.HaveWarningOnce(expectedMessage);
480484
runtime.Logger.UIWarnings.Should().ContainSingle(expectedMessage);
481485
}
482486

487+
[TestMethod]
488+
public void ProcessedArgs_TfsLegacy_SetUseCliTrue()
489+
{
490+
using var env = new EnvironmentVariableScope();
491+
env.SetVariable(EnvironmentVariables.IsInTeamFoundationBuild, "true");
492+
env.SetVariable(EnvironmentVariables.BuildUriLegacy, "legacy build uri");
493+
var sut = CreateDefaultArgs(buildSettings: BuildSettings.GetSettingsFromEnvironment());
494+
sut.IsValid.Should().BeTrue();
495+
#if NETFRAMEWORK
496+
sut.UseSonarScannerCli.Should().BeTrue();
497+
runtime.Logger.Should().HaveDebugs("Falling back to SonarScannerCLI to guarantee TFS Legacy support.");
498+
#else
499+
sut.UseSonarScannerCli.Should().BeFalse();
500+
#endif
501+
runtime.Logger.Should().HaveNoWarnings()
502+
.And.HaveNoErrors();
503+
}
504+
505+
[TestMethod]
506+
public void ProcessedArgs_TfsLegacy_SkipCodeCoverage_SetUseCliFalse()
507+
{
508+
using var env = new EnvironmentVariableScope();
509+
env.SetVariable(EnvironmentVariables.IsInTeamFoundationBuild, "true");
510+
env.SetVariable(EnvironmentVariables.BuildUriLegacy, "legacy build uri");
511+
env.SetVariable(EnvironmentVariables.SkipLegacyCodeCoverage, "true");
512+
var sut = CreateDefaultArgs(buildSettings: BuildSettings.GetSettingsFromEnvironment());
513+
sut.IsValid.Should().BeTrue();
514+
sut.UseSonarScannerCli.Should().BeFalse();
515+
runtime.Logger.Should().HaveNoWarnings()
516+
.And.HaveNoErrors();
517+
}
518+
483519
private static IEnumerable<object[]> ProcessedArgs_SourcesOrTests_Warning_DataSource() =>
484520
[
485521
[new Property(SonarProperties.Sources, "src")],
@@ -490,6 +526,7 @@ [new Property(SonarProperties.Tests, "tests")],
490526
private ProcessedArgs CreateDefaultArgs(IAnalysisPropertyProvider cmdLineProperties = null,
491527
IAnalysisPropertyProvider globalFileProperties = null,
492528
IAnalysisPropertyProvider scannerEnvProperties = null,
529+
BuildSettings buildSettings = null,
493530
string key = "key",
494531
string organization = "organization") =>
495532
new(
@@ -501,6 +538,7 @@ private ProcessedArgs CreateDefaultArgs(IAnalysisPropertyProvider cmdLinePropert
501538
cmdLineProperties: cmdLineProperties ?? EmptyPropertyProvider.Instance,
502539
globalFileProperties: globalFileProperties ?? EmptyPropertyProvider.Instance,
503540
scannerEnvProperties: scannerEnvProperties ?? EmptyPropertyProvider.Instance,
541+
buildSettings: buildSettings,
504542
runtime);
505543

506544
private static void AssertExpectedValue(string key, string expectedValue, ProcessedArgs args)

0 commit comments

Comments
 (0)