Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parse settings from Azure Devops Extension #1246

Merged
merged 13 commits into from Jun 9, 2022
Expand Up @@ -135,6 +135,7 @@ private IBootstrapperSettings MockBootstrapSettings(AnalysisPhase phase, bool de

File.Create(Path.Combine(rootDir, "SonarScanner.MSBuild.Common.dll")).Close();
File.Create(Path.Combine(rootDir, "SonarScanner.MSBuild.Tasks.dll")).Close();
File.Create(Path.Combine(rootDir, "Newtonsoft.Json.dll")).Close();

mockBootstrapSettings = new Mock<IBootstrapperSettings>();
mockBootstrapSettings.SetupGet(x => x.ChildCmdLineArgs).Returns(args.ToArray);
Expand Down
20 changes: 16 additions & 4 deletions Tests/SonarScanner.MSBuild.Test/BootstrapperClassTests.cs
Expand Up @@ -119,13 +119,15 @@ public void CopyDlls_WhenFileDoNotExist_FilesAreCopied()
// Sanity
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Common.dll")).Should().BeFalse();
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Tasks.dll")).Should().BeFalse();
File.Exists(Path.Combine(tempDir, "bin", "Newtonsoft.Json.dll")).Should().BeFalse();

// Act
CheckExecutionSucceeds(AnalysisPhase.PreProcessing, false, null, "/d:sonar.host.url=http://anotherHost");

// Assert
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Common.dll")).Should().BeTrue();
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Tasks.dll")).Should().BeTrue();
File.Exists(Path.Combine(tempDir, "bin", "Newtonsoft.Json.dll")).Should().BeTrue();
}
}

Expand All @@ -140,13 +142,15 @@ public void CopyDlls_WhenFileExistButAreNotLocked_FilesAreCopied()
Directory.CreateDirectory(Path.Combine(tempDir, "bin"));
File.Create(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Common.dll")).Close();
File.Create(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Tasks.dll")).Close();
File.Create(Path.Combine(tempDir, "bin", "Newtonsoft.Json.dll")).Close();

// Act
CheckExecutionSucceeds(AnalysisPhase.PreProcessing, false, null, "/d:sonar.host.url=http://anotherHost");

// Assert
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Common.dll")).Should().BeTrue();
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Tasks.dll")).Should().BeTrue();
File.Exists(Path.Combine(tempDir, "bin", "Newtonsoft.Json.dll")).Should().BeTrue();
}
}

Expand All @@ -161,17 +165,20 @@ public void CopyDlls_WhenFileExistAndAreLockedButSameVersion_DoNothing()
Directory.CreateDirectory(Path.Combine(tempDir, "bin"));
var file1 = File.Create(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Common.dll"));
var file2 = File.Create(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Tasks.dll"));
var file3 = File.Create(Path.Combine(tempDir, "bin", "Newtonsoft.Json.dll"));

// Act
CheckExecutionSucceeds(AnalysisPhase.PreProcessing, false, _ => new Version(), "/d:sonar.host.url=http://anotherHost");

// Assert
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Common.dll")).Should().BeTrue();
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Tasks.dll")).Should().BeTrue();
File.Exists(Path.Combine(tempDir, "bin", "Newtonsoft.Json.dll")).Should().BeTrue();

// Do not close before to ensure the file is locked
file1.Close();
file2.Close();
file3.Close();
}
}

Expand All @@ -186,6 +193,7 @@ public void CopyDlls_WhenFileExistAndAreLockedButDifferentVersion_Fails()
Directory.CreateDirectory(Path.Combine(tempDir, "bin"));
var file1 = File.Create(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Common.dll"));
var file2 = File.Create(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Tasks.dll"));
var file3 = File.Create(Path.Combine(tempDir, "bin", "Newtonsoft.Json.dll"));

var callCount = 0;
Func<string, Version> getAssemblyVersion = _ =>
Expand All @@ -205,11 +213,13 @@ public void CopyDlls_WhenFileExistAndAreLockedButDifferentVersion_Fails()
// Assert
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Common.dll")).Should().BeTrue();
File.Exists(Path.Combine(tempDir, "bin", "SonarScanner.MSBuild.Tasks.dll")).Should().BeTrue();
File.Exists(Path.Combine(tempDir, "bin", "Newtonsoft.Json.dll")).Should().BeTrue();

logger.DebugMessages.Should().HaveCount(3);
logger.DebugMessages[0].Should().Match(@"Cannot delete directory: '*\.sonarqube\bin' because The process cannot access the file 'SonarScanner.MSBuild.Common.dll' because it is being used by another process..");
logger.DebugMessages[1].Should().Match(@"Cannot delete file: '*\.sonarqube\bin\SonarScanner.MSBuild.Common.dll' because The process cannot access the file '*SonarScanner.MSBuild.Common.dll' because it is being used by another process..");
logger.DebugMessages[2].Should().Match(@"Cannot delete file: '*\.sonarqube\bin\SonarScanner.MSBuild.Tasks.dll' because The process cannot access the file '*SonarScanner.MSBuild.Tasks.dll' because it is being used by another process..");
logger.DebugMessages.Should().HaveCount(4);
logger.DebugMessages[0].Should().Match(@"Cannot delete directory: '*\.sonarqube\bin' because The process cannot access the file 'Newtonsoft.Json.dll' because it is being used by another process..");
logger.DebugMessages[1].Should().Match(@"Cannot delete file: '*\.sonarqube\bin\Newtonsoft.Json.dll' because The process cannot access the file '*Newtonsoft.Json.dll' because it is being used by another process..");
logger.DebugMessages[2].Should().Match(@"Cannot delete file: '*\.sonarqube\bin\SonarScanner.MSBuild.Common.dll' because The process cannot access the file '*SonarScanner.MSBuild.Common.dll' because it is being used by another process..");
logger.DebugMessages[3].Should().Match(@"Cannot delete file: '*\.sonarqube\bin\SonarScanner.MSBuild.Tasks.dll' because The process cannot access the file '*SonarScanner.MSBuild.Tasks.dll' because it is being used by another process..");

logger.AssertErrorLogged(@"Cannot copy a different version of the SonarScanner for MSBuild assemblies because they are used by a running MSBuild/.Net Core process. To resolve this problem try one of the following:
- Analyze this project using the same version of SonarScanner for MSBuild
Expand All @@ -218,6 +228,7 @@ public void CopyDlls_WhenFileExistAndAreLockedButDifferentVersion_Fails()
// Do not close before to ensure the file is locked
file1.Close();
file2.Close();
file3.Close();
}
}

Expand Down Expand Up @@ -391,6 +402,7 @@ private IBootstrapperSettings MockBootstrapSettings(AnalysisPhase phase, bool de

File.Create(Path.Combine(rootDir, "SonarScanner.MSBuild.Common.dll")).Close();
File.Create(Path.Combine(rootDir, "SonarScanner.MSBuild.Tasks.dll")).Close();
File.Create(Path.Combine(rootDir, "Newtonsoft.Json.dll")).Close();
andrei-epure-sonarsource marked this conversation as resolved.
Show resolved Hide resolved

mockBootstrapSettings = new Mock<IBootstrapperSettings>();
mockBootstrapSettings.SetupGet(x => x.ChildCmdLineArgs).Returns(args.ToArray);
Expand Down
Expand Up @@ -83,7 +83,7 @@ public class ScannerMSBuildTest {
private static Server server;
private static int httpProxyPort;

private static ConcurrentLinkedDeque<String> seenByProxy = new ConcurrentLinkedDeque<>();
private static final ConcurrentLinkedDeque<String> seenByProxy = new ConcurrentLinkedDeque<>();

@ClassRule
public static TemporaryFolder temp = TestUtils.createTempFolder();
Expand Down Expand Up @@ -225,12 +225,30 @@ private void assertLineCountForProjectUnderTest(String projectKey) {
@Test
public void testExcludedAndTest_AnalyzeTestProject() throws Exception {
int expectedTestProjectIssues = isTestProjectSupported() ? 1 : 0;
testExcludedAndTest(false, expectedTestProjectIssues);
String token = TestUtils.getNewToken(ORCHESTRATOR);
andrei-epure-sonarsource marked this conversation as resolved.
Show resolved Hide resolved
Path projectDir = TestUtils.projectDir(temp, "ExcludedTest");
ScannerForMSBuild build = TestUtils.newScannerBegin(ORCHESTRATOR, "ExcludedTest_False", projectDir, token, ScannerClassifier.NET_FRAMEWORK_46)
andrei-epure-sonarsource marked this conversation as resolved.
Show resolved Hide resolved
// don't exclude test projects
.setProperty("sonar.dotnet.excludeTestProjects", "false");
testExcludedAndTest(build, "ExcludedTest_False", projectDir, token, expectedTestProjectIssues, false);
}

@Test
public void testExcludedAndTest_ExcludeTestProject() throws Exception {
testExcludedAndTest(true, 0);
String token = TestUtils.getNewToken(ORCHESTRATOR);
Path projectDir = TestUtils.projectDir(temp, "ExcludedTest");
ScannerForMSBuild build = TestUtils.newScannerBegin(ORCHESTRATOR, "ExcludedTest_True", projectDir, token, ScannerClassifier.NET_FRAMEWORK_46)
// exclude test projects
.setProperty("sonar.dotnet.excludeTestProjects", "true");
testExcludedAndTest(build, "ExcludedTest_True", projectDir, token, 0, false);
}

@Test
csaba-sagi-sonarsource marked this conversation as resolved.
Show resolved Hide resolved
public void testExcludedAndTest_simulateAzureDevopsEnvironmentSetting_ExcludeTestProject() throws Exception {
String token = TestUtils.getNewToken(ORCHESTRATOR);
Path projectDir = TestUtils.projectDir(temp, "ExcludedTest");
ScannerForMSBuild build = TestUtils.newScannerBegin(ORCHESTRATOR, "ExcludedTest_True_FromAzureDevOps", projectDir, token, ScannerClassifier.NET_FRAMEWORK_46);
testExcludedAndTest(build, "ExcludedTest_True_FromAzureDevOps", projectDir, token, 0, true);
}

@Test
Expand Down Expand Up @@ -489,7 +507,7 @@ public void checkExternalIssuesCS() throws Exception {
if (ORCHESTRATOR.getServer().version().isGreaterThanOrEquals(7, 4)) {
// if external issues are imported, then there should also be some
// Wintellect errors. However, only file-level issues are imported.
assertThat(ruleKeys).containsAll(Arrays.asList(
assertThat(ruleKeys).containsAll(List.of(
"external_roslyn:Wintellect004"));

assertThat(issues).hasSize(3);
Expand Down Expand Up @@ -854,7 +872,7 @@ private void assertProjectFileContains(String projectName, String textToLookFor)
Path csProjPath = projectPath.resolve("RazorWebApplication\\RazorWebApplication.csproj");
String str = FileUtils.readFileToString(csProjPath.toFile(), "utf-8");
assertThat(str.indexOf(textToLookFor))
.isGreaterThan(0);
.isPositive();
}

private BuildResult runBeginBuildAndEndForStandardProject(String folderName, String projectName) throws IOException {
Expand Down Expand Up @@ -896,7 +914,7 @@ private BuildResult runNetCoreBeginBuildAndEnd(Path projectDir, ScannerClassifie
return TestUtils.executeEndStepAndDumpResults(ORCHESTRATOR, projectDir, folderName, token, classifier);
}

private BuildResult runBeginBuildAndEndForStandardProject(Path projectDir, String projectName, Boolean setProjectBaseDirExplicitly, Boolean useNuGet) throws IOException {
private BuildResult runBeginBuildAndEndForStandardProject(Path projectDir, String projectName, Boolean setProjectBaseDirExplicitly, Boolean useNuGet) {
String token = TestUtils.getNewToken(ORCHESTRATOR);
String folderName = projectDir.getFileName().toString();
ScannerForMSBuild scanner = TestUtils.newScanner(ORCHESTRATOR, projectDir)
Expand All @@ -918,7 +936,7 @@ private BuildResult runBeginBuildAndEndForStandardProject(Path projectDir, Strin
if (projectName.isEmpty()) {
scanner.addArgument("/d:sonar.projectBaseDir=" + projectDir.toAbsolutePath());
} else {
scanner.addArgument("/d:sonar.projectBaseDir=" + Paths.get(projectDir.toAbsolutePath().toString(), projectName).toString());
scanner.addArgument("/d:sonar.projectBaseDir=" + Paths.get(projectDir.toAbsolutePath().toString(), projectName));
}

}
Expand Down Expand Up @@ -963,28 +981,23 @@ private void validateRazorProject(String projectName) throws IOException {
assertThat(TestUtils.getMeasureAsInteger(localProjectKey, "files", ORCHESTRATOR)).isEqualTo(2);
}

private void testExcludedAndTest(boolean excludeTestProjects, int expectedTestProjectIssues) throws Exception {
String normalProjectKey = TestUtils.hasModules(ORCHESTRATOR) ? "my.project:my.project:B93B287C-47DB-4406-9EAB-653BCF7D20DC" : "my.project:Normal";
String testProjectKey = TestUtils.hasModules(ORCHESTRATOR) ? "my.project:my.project:2DC588FC-16FB-42F8-9FDA-193852E538AF" : "my.project:Test";
private void testExcludedAndTest(ScannerForMSBuild build, String projectKeyName, Path projectDir, String token, int expectedTestProjectIssues, boolean simulateAzureDevopsEnvironment) {
andrei-epure-sonarsource marked this conversation as resolved.
Show resolved Hide resolved
String normalProjectKey = TestUtils.hasModules(ORCHESTRATOR)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opened #1248 to remove hasModules()

outside the scope of this PR

? String.format("%1$s:%1$s:B93B287C-47DB-4406-9EAB-653BCF7D20DC", projectKeyName)
: String.format("%1$s:Normal", projectKeyName);
String testProjectKey = TestUtils.hasModules(ORCHESTRATOR)
? String.format("%1$s:%1$s:2DC588FC-16FB-42F8-9FDA-193852E538AF", projectKeyName)
: String.format("%1$s:Test", projectKeyName);

ORCHESTRATOR.getServer().restoreProfile(FileLocation.of("projects/ProjectUnderTest/TestQualityProfile.xml"));
ORCHESTRATOR.getServer().provisionProject(PROJECT_KEY, "excludedAndTest");
ORCHESTRATOR.getServer().associateProjectToQualityProfile(PROJECT_KEY, "cs", "ProfileForTest");
ORCHESTRATOR.getServer().provisionProject(projectKeyName, projectKeyName);
ORCHESTRATOR.getServer().associateProjectToQualityProfile(projectKeyName, "cs", "ProfileForTest");

Path projectDir = TestUtils.projectDir(temp, "ExcludedTest");
String token = TestUtils.getNewToken(ORCHESTRATOR);
ORCHESTRATOR.executeBuild(TestUtils.newScanner(ORCHESTRATOR, projectDir)
.addArgument("begin")
.setProjectKey(PROJECT_KEY)
.setProjectName("excludedAndTest")
.setProjectVersion("1.0")
.setProperty("sonar.projectBaseDir", projectDir.toAbsolutePath().toString())
.setProperty("sonar.login", token)
.setProperty("sonar.dotnet.excludeTestProjects", String.valueOf(excludeTestProjects)));
ORCHESTRATOR.executeBuild(build);

TestUtils.runMSBuild(ORCHESTRATOR, projectDir, "/t:Rebuild");
TestUtils.runMSBuild(ORCHESTRATOR, projectDir, simulateAzureDevopsEnvironment, "/t:Rebuild");

BuildResult result = TestUtils.executeEndStepAndDumpResults(ORCHESTRATOR, projectDir, PROJECT_KEY, token);
BuildResult result = TestUtils.executeEndStepAndDumpResults(ORCHESTRATOR, projectDir, projectKeyName, token);
assertTrue(result.isSuccess());

// Dump debug info
Expand All @@ -1003,7 +1016,7 @@ private void testExcludedAndTest(boolean excludeTestProjects, int expectedTestPr

// excluded project doesn't exist in SonarQube

assertThat(TestUtils.getMeasureAsInteger(PROJECT_KEY, "ncloc", ORCHESTRATOR)).isEqualTo(45);
assertThat(TestUtils.getMeasureAsInteger(projectKeyName, "ncloc", ORCHESTRATOR)).isEqualTo(45);
assertThat(TestUtils.getMeasureAsInteger(normalProjectKey, "ncloc", ORCHESTRATOR)).isEqualTo(45);
assertThat(TestUtils.getMeasureAsInteger(testProjectKey, "ncloc", ORCHESTRATOR)).isNull();
}
Expand Down Expand Up @@ -1050,17 +1063,17 @@ private static void startProxy(boolean needProxyAuth) throws Exception {
private static ServletContextHandler proxyHandler(boolean needProxyAuth) {
ServletContextHandler contextHandler = new ServletContextHandler();
if (needProxyAuth) {
contextHandler.setSecurityHandler(basicAuth(PROXY_USER, PROXY_PASSWORD, "Private!"));
contextHandler.setSecurityHandler(basicAuth("Private!"));
}
contextHandler.setServletHandler(newServletHandler());
return contextHandler;
}

private static SecurityHandler basicAuth(String username, String password, String realm) {
private static SecurityHandler basicAuth(String realm) {
HashLoginService l = new HashLoginService();

UserStore userStore = new UserStore();
userStore.addUser(username, Credential.getCredential(password), new String[]{"user"});
userStore.addUser(ScannerMSBuildTest.PROXY_USER, Credential.getCredential(ScannerMSBuildTest.PROXY_PASSWORD), new String[]{"user"});

l.setUserStore(userStore);
l.setName(realm);
Expand Down