/// <summary> /// Executes the WriteProjectInfoFile target in the the supplied project. /// The method will check the build succeeded and that a single project /// output file was created. /// </summary> /// <returns>The project info file that was created during the build</returns> private ProjectInfo ExecuteWriteProjectInfo(ProjectRootElement projectRoot, string rootOutputFolder, bool noWarningOrErrors = true) { projectRoot.Save(); // Act var result = BuildRunner.BuildTargets(TestContext, projectRoot.FullPath, // The "write" target depends on a couple of other targets having executed first to set properties appropriately TargetConstants.CategoriseProjectTarget, TargetConstants.CalculateFilesToAnalyzeTarget, TargetConstants.CreateProjectSpecificDirs, TargetConstants.WriteProjectDataTarget); // Assert result.AssertTargetSucceeded(TargetConstants.CalculateFilesToAnalyzeTarget); result.AssertTargetSucceeded(TargetConstants.CreateProjectSpecificDirs); result.AssertTargetSucceeded(TargetConstants.WriteProjectDataTarget); result.AssertTargetExecuted(TargetConstants.WriteProjectDataTarget); if (noWarningOrErrors) { result.AssertNoWarningsOrErrors(); } // Check expected project outputs Assert.AreEqual(1, Directory.EnumerateDirectories(rootOutputFolder).Count(), "Only expecting one child directory to exist under the root analysis output folder"); var projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectRoot.FullPath); return(projectInfo); }
public void Roslyn_Settings_TempFolderIsNotSet() { // Arrange var properties = new WellKnownProjectProperties { ErrorLog = "pre-existing.log", ResolvedCodeAnalysisRuleset = "pre-existing.ruleset", WarningsAsErrors = "CS101", TreatWarningsAsErrors = "true" }; var projectRoot = CreateValidProjectSetup(properties); projectRoot.AddProperty(TargetProperties.SonarQubeTempPath, string.Empty); // needs to overwritten once the valid project has been created projectRoot.Save(); // re-save the modified project // Act var result = BuildRunner.BuildTargets(TestContext, projectRoot.FullPath, TargetConstants.OverrideRoslynAnalysisTarget); // Assert result.AssertTargetNotExecuted(TargetConstants.OverrideRoslynAnalysisTarget); result.AssertTargetNotExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget); // Existing properties should not be changed AssertExpectedErrorLog(result, "pre-existing.log"); AssertExpectedResolvedRuleset(result, "pre-existing.ruleset"); result.AssertExpectedItemGroupCount(TargetProperties.AnalyzerItemType, 0); result.AssertExpectedItemGroupCount(TargetProperties.AdditionalFilesItemType, 0); result.AssertExpectedCapturedPropertyValue(TargetProperties.TreatWarningsAsErrors, "true"); result.AssertExpectedCapturedPropertyValue(TargetProperties.WarningsAsErrors, "CS101"); }
public void Roslyn_SetResults_ResultsFileExists() { // Arrange var rootInputFolder = TestUtils.CreateTestSpecificFolder(TestContext, "Inputs"); var resultsFile = TestUtils.CreateTextFile(rootInputFolder, "error.report.txt", "dummy report content"); var properties = new WellKnownProjectProperties { SonarQubeTempPath = rootInputFolder }; properties[TargetProperties.ErrorLog] = resultsFile; var projectRoot = BuildUtilities.CreateValidProjectRoot(TestContext, rootInputFolder, properties); AddCaptureTargetsImport(rootInputFolder, projectRoot); projectRoot.Save(); // Act var result = BuildRunner.BuildTargets(TestContext, projectRoot.FullPath, TargetConstants.CreateProjectSpecificDirs, TargetConstants.SetRoslynResultsTarget); var projectSpecificOutDir = result.GetCapturedPropertyValue(TargetProperties.ProjectSpecificOutDir); // Assert result.AssertTargetExecuted(TargetConstants.CreateProjectSpecificDirs); result.AssertTargetExecuted(TargetConstants.SetRoslynResultsTarget); AssertExpectedAnalysisSetting(result, RoslynAnalysisResultsSettingName, resultsFile); AssertExpectedAnalysisSetting(result, AnalyzerWorkDirectoryResultsSettingName, projectSpecificOutDir); }
public void E2E_NoAnalyzableFiles() { // Arrange var context = CreateContext(); // Only non-analyzable files var foo1 = context.CreateInputFile("foo1.txt"); var foo2 = context.CreateInputFile("foo2.txt"); var bar1 = context.CreateInputFile("bar1.txt"); var projectXml = $@" <ItemGroup> <Compile Include='*.cs' /> <Foo Include='{foo1}' /> <Foo Include='{foo2}' /> <Bar Include='{bar1}' /> </ItemGroup> "; var projectFilePath = context.CreateProjectFile(projectXml); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuild); // Build should succeed with warnings var actualStructure = context.ValidateAndLoadProjectStructure(); actualStructure.AssertConfigFileDoesNotExist(ExpectedAnalysisFilesListFileName); // Check the projectInfo.xml does not have an analysis result actualStructure.ProjectInfo.AssertAnalysisResultDoesNotExists("FilesToAnalyze"); }
public void E2E_ProductProjects() { // Arrange var context = CreateContext(); // Mix of analyzable and non-analyzable files var foo1 = context.CreateInputFile("foo1.txt"); var code1 = context.CreateInputFile("code1.txt"); var projectXml = $@" <PropertyGroup> <SonarQubeTestProject>false</SonarQubeTestProject> </PropertyGroup> <ItemGroup> <Foo Include='{foo1}' /> <Compile Include='{code1}' /> </ItemGroup> "; var projectFilePath = context.CreateProjectFile(projectXml); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuild); // Build should succeed with warnings var actualStructure = context.ValidateAndLoadProjectStructure(); actualStructure.ProjectInfo.ProjectType.Should().Be(ProjectType.Product); actualStructure.ProjectConfig.ProjectType.Should().Be(ProjectType.Product); actualStructure.AssertExpectedFileList("\\code1.txt"); }
public void ImportsBefore_BuildingInsideVS_NotImported() { // 1. Pre-build // Arrange var dummySonarTargetsDir = EnsureDummyIntegrationTargetsFileExists(); var projectXml = $@" <PropertyGroup> <SonarQubeTempPath>{Path.GetTempPath()}</SonarQubeTempPath> <SonarQubeTargetsPath>{Path.GetDirectoryName(dummySonarTargetsDir)}</SonarQubeTargetsPath> <BuildingInsideVisualStudio>tRuE</BuildingInsideVisualStudio> </PropertyGroup> "; var projectFilePath = CreateProjectFile(projectXml); // Act var projectInstance = CreateAndEvaluateProject(projectFilePath); // Assert BuildAssertions.AssertExpectedPropertyValue(projectInstance, TargetProperties.SonarQubeTargetFilePath, dummySonarTargetsDir); AssertAnalysisTargetsAreNotImported(projectInstance); // 2. Now build -> succeeds var result = BuildRunner.BuildTargets(TestContext, projectInstance.FullPath); result.AssertTargetSucceeded(TargetConstants.DefaultBuildTarget); result.AssertTargetNotExecuted(TargetConstants.ImportBeforeInfoTarget); result.AssertExpectedErrorCount(0); }
public void Roslyn_SetResults_BothResultsFilesCreated() { // Arrange var rootInputFolder = TestUtils.CreateTestSpecificFolder(TestContext, "Inputs"); var resultsFile = TestUtils.CreateTextFile(rootInputFolder, "error.report.txt", "dummy report content"); var razorResultsFile = TestUtils.CreateTextFile(rootInputFolder, "razor.error.report.txt", "dummy report content"); var projectSnippet = $@" <PropertyGroup> <SonarQubeTempPath>{rootInputFolder}</SonarQubeTempPath> <SonarCompileErrorLog>{resultsFile}</SonarCompileErrorLog> <RazorSonarCompileErrorLog>{razorResultsFile}</RazorSonarCompileErrorLog> </PropertyGroup> "; var projectFilePath = CreateProjectFile(null, projectSnippet); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath, TargetConstants.CreateProjectSpecificDirs, TargetConstants.SetRoslynResultsTarget); var projectSpecificOutDir = result.GetCapturedPropertyValue(TargetProperties.ProjectSpecificOutDir); // Assert result.AssertTargetExecuted(TargetConstants.CreateProjectSpecificDirs); result.AssertTargetExecuted(TargetConstants.SetRoslynResultsTarget); AssertExpectedAnalysisSetting(result, RoslynAnalysisResultsSettingName, resultsFile + "|" + razorResultsFile); AssertExpectedAnalysisSetting(result, AnalyzerWorkDirectoryResultsSettingName, projectSpecificOutDir); }
/// <summary> /// Creates and builds a new Sonar-enabled project using the supplied descriptor. /// The method will check the build succeeded and that a single project output file was created. /// </summary> /// <returns>The full path of the project-specific directory that was created during the build</returns> private string CreateAndBuildSonarProject(ProjectDescriptor descriptor, string rootOutputFolder, WellKnownProjectProperties preImportProperties) { var projectRoot = BuildUtilities.CreateInitializedProjectRoot(TestContext, descriptor, preImportProperties); // Act var result = BuildRunner.BuildTargets(TestContext, descriptor.FullFilePath); TestContext.AddResultFile(result.FilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuildTarget); // We expect the compiler to warn if there are no compiler inputs var expectedWarnings = (descriptor.ManagedSourceFiles.Any()) ? 0 : 1; result.AssertExpectedErrorCount(0); result.AssertExpectedWarningCount(expectedWarnings); result.AssertExpectedTargetOrdering( TargetConstants.CategoriseProjectTarget, TargetConstants.DefaultBuildTarget, TargetConstants.CalculateFilesToAnalyzeTarget, TargetConstants.WriteProjectDataTarget); // Check expected folder structure exists CheckRootOutputFolder(rootOutputFolder); // Check expected project outputs Assert.AreEqual(1, Directory.EnumerateDirectories(rootOutputFolder).Count(), "Only expecting one child directory to exist under the root analysis output folder"); ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, descriptor.FullFilePath); return(Directory.EnumerateDirectories(rootOutputFolder).Single()); }
public void ImportsBefore_MissingAnalysisTargets() { // 1. Prebuild // Arrange var preImportProperties = new WellKnownProjectProperties { SonarQubeTempPath = "nonExistentPath", MSBuildExtensionsPath = "nonExistentPath", TeamBuild2105BuildDirectory = "", TeamBuildLegacyBuildDirectory = "" }; // Act var projectInstance = CreateAndEvaluateProject(preImportProperties); // Assert BuildAssertions.AssertExpectedPropertyValue(projectInstance, TargetProperties.SonarQubeTargetsPath, @"nonExistentPath\bin\targets"); BuildAssertions.AssertExpectedPropertyValue(projectInstance, TargetProperties.SonarQubeTargetFilePath, @"nonExistentPath\bin\targets\SonarQube.Integration.targets"); AssertAnalysisTargetsAreNotImported(projectInstance); // Targets should not be imported // 2. Now build -> fails with an error message var result = BuildRunner.BuildTargets(TestContext, projectInstance.FullPath, buildShouldSucceed: false); result.BuildSucceeded.Should().BeFalse(); result.AssertTargetExecuted(TargetConstants.ImportBeforeInfoTarget); result.AssertExpectedErrorCount(1); var projectName = Path.GetFileName(projectInstance.FullPath); result.Errors[0].Contains(projectName).Should().BeTrue("Expecting the error message to contain the project file name"); }
public void E2E_NoAnalyzableFiles() { // Arrange var rootInputFolder = TestUtils.CreateTestSpecificFolder(TestContext, "Inputs"); var rootOutputFolder = TestUtils.CreateTestSpecificFolder(TestContext, "Outputs"); // Only non-analyzable files var foo1 = CreateEmptyFile(rootInputFolder, "foo1.txt"); var foo2 = CreateEmptyFile(rootInputFolder, "foo2.txt"); var bar1 = CreateEmptyFile(rootInputFolder, "bar1.txt"); var projectXml = $@" <ItemGroup> <Compile Include='*.cs' /> <Foo Include='{foo1}' /> <Foo Include='{foo2}' /> <Bar Include='{bar1}' /> </ItemGroup> "; var projectFilePath = CreateProjectFile(projectXml, rootOutputFolder); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuildTarget); // Build should succeed with warnings var projectSpecificOutputDir = CheckProjectSpecificOutputStructure(rootOutputFolder); AssertFileDoesNotExist(projectSpecificOutputDir, ExpectedAnalysisFilesListFileName); // Check the projectInfo.xml does not have an analysis result var actualProjectInfo = CheckProjectInfoExists(projectSpecificOutputDir); actualProjectInfo.AssertAnalysisResultDoesNotExists("FilesToAnalyze"); }
public void E2E_OutputFolderStructure() { // Checks the output folder structure is correct for a simple solution // Arrange var rootInputFolder = TestUtils.CreateTestSpecificFolder(TestContext, "Inputs"); var rootOutputFolder = TestUtils.CreateTestSpecificFolder(TestContext, "Outputs"); var codeFilePath = CreateEmptyFile(rootInputFolder, "codeFile1.txt"); var projectXml = $@" <ItemGroup> <Compile Include='{codeFilePath}' /> </ItemGroup> "; var projectFilePath = CreateProjectFile(projectXml, rootOutputFolder); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuildTarget); result.AssertExpectedErrorCount(0); result.AssertExpectedWarningCount(0); result.AssertExpectedTargetOrdering( TargetConstants.CategoriseProjectTarget, TargetConstants.DefaultBuildTarget, TargetConstants.CalculateFilesToAnalyzeTarget, TargetConstants.WriteProjectDataTarget); var projectSpecificOutputDir = CheckProjectSpecificOutputStructure(rootOutputFolder); var actualProjectInfo = CheckProjectInfoExists(projectSpecificOutputDir); }
public void SetResults_ResultsFileExists() { // Arrange var rootInputFolder = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext, "Inputs"); var resultsFile = TestUtils.CreateTextFile(rootInputFolder, "error.report.txt", "dummy report content"); var projectSnippet = $@" <PropertyGroup> <SonarQubeTempPath>{rootInputFolder}</SonarQubeTempPath> <SonarErrorLog>{resultsFile}</SonarErrorLog> </PropertyGroup> "; var filePath = CreateProjectFile(null, projectSnippet); // Act var result = BuildRunner.BuildTargets(TestContext, filePath, TargetConstants.SonarCreateProjectSpecificDirs, TargetConstants.InvokeSonarWriteProjectData_NonRazorProject); var projectSpecificOutDir = result.GetPropertyValue(TargetProperties.ProjectSpecificOutDir); // Assert result.AssertTargetExecuted(TargetConstants.SonarCreateProjectSpecificDirs); result.AssertTargetExecuted(TargetConstants.InvokeSonarWriteProjectData_NonRazorProject); result.AssertTargetExecuted(TargetConstants.SonarWriteProjectData); AssertExpectedAnalysisSetting(result, RoslynAnalysisResultsSettingName, resultsFile); AssertExpectedAnalysisSetting(result, AnalyzerWorkDirectoryResultsSettingName, projectSpecificOutDir); }
public void Settings_NotRunForExcludedProject() { // Arrange var projectSnippet = @" <PropertyGroup> <SonarQubeExclude>TRUE</SonarQubeExclude> <ResolvedCodeAnalysisRuleset>Dummy value</ResolvedCodeAnalysisRuleset> <ErrorLog>C:\UserDefined.json</ErrorLog> <RunAnalyzers>false</RunAnalyzers> <RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild> </PropertyGroup> "; var filePath = CreateProjectFile(null, projectSnippet); // Act var result = BuildRunner.BuildTargets(TestContext, filePath, TargetConstants.OverrideRoslynAnalysis); // Assert result.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysis); result.AssertTargetNotExecuted(TargetConstants.SetRoslynAnalysisProperties); result.BuildSucceeded.Should().BeTrue(); result.AssertPropertyValue("ResolvedCodeAnalysisRuleset", "Dummy value"); result.AssertPropertyValue(TargetProperties.RunAnalyzers, "false"); // We don't embed analyzers => we don't need to override this result.AssertPropertyValue(TargetProperties.RunAnalyzersDuringBuild, "false"); result.AssertPropertyValue(TargetProperties.SonarErrorLog, null); result.AssertPropertyValue(TargetProperties.ErrorLog, @"C:\UserDefined.json"); // Do not override }
public void E2E_ExcludedProjects() { // Project info should still be written for files with $(SonarQubeExclude) set to true // Arrange var context = CreateContext(); // Mix of analyzable and non-analyzable files var foo1 = context.CreateInputFile("foo1.txt"); var code1 = context.CreateInputFile("code1.txt"); var projectXml = $@" <PropertyGroup> <SonarQubeExclude>true</SonarQubeExclude> </PropertyGroup> <ItemGroup> <Foo Include='{foo1}' /> <Compile Include='{code1}' /> </ItemGroup> "; var projectFilePath = context.CreateProjectFile(projectXml); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuildTarget); // Build should succeed with warnings var actualStructure = context.ValidateAndLoadProjectStructure(checkAndLoadConfigFile: false); actualStructure.ProjectInfo.IsExcluded.Should().BeTrue(); actualStructure.AssertConfigFileDoesNotExist(ExpectedProjectConfigFileName); actualStructure.AssertExpectedFileList("\\code1.txt"); }
public void ImportsBefore_MissingAnalysisTargets() { // 1. Prebuild // Arrange var projectXml = @" <PropertyGroup> <SonarQubeTempPath>nonExistentPath</SonarQubeTempPath> <MSBuildExtensionsPath>nonExistentPath</MSBuildExtensionsPath> <AGENT_BUILDDIRECTORY /> <TF_BUILD_BUILDDIRECTORY /> </PropertyGroup> "; var projectFilePath = CreateProjectFile(projectXml); // Act var projectInstance = CreateAndEvaluateProject(projectFilePath); // Assert BuildAssertions.AssertExpectedPropertyValue(projectInstance, TargetProperties.SonarQubeTargetsPath, @"nonExistentPath\bin\targets"); BuildAssertions.AssertExpectedPropertyValue(projectInstance, TargetProperties.SonarQubeTargetFilePath, @"nonExistentPath\bin\targets\SonarQube.Integration.targets"); AssertAnalysisTargetsAreNotImported(projectInstance); // Targets should not be imported // 2. Now build -> fails with an error message var result = BuildRunner.BuildTargets(TestContext, projectInstance.FullPath, buildShouldSucceed: false); result.BuildSucceeded.Should().BeFalse(); result.AssertTargetExecuted(TargetConstants.ImportBeforeInfoTarget); result.AssertExpectedErrorCount(1); var projectName = Path.GetFileName(projectInstance.FullPath); result.Errors[0].Contains(projectName).Should().BeTrue("Expecting the error message to contain the project file name"); }
public void ImportsBefore_SonarQubeTargetsPathNotSet() { // 1. Prebuild // Arrange EnsureDummyIntegrationTargetsFileExists(); var preImportProperties = new WellKnownProjectProperties { SonarQubeTargetsPath = "", TeamBuild2105BuildDirectory = "", TeamBuildLegacyBuildDirectory = "" }; // Act var projectInstance = CreateAndEvaluateProject(preImportProperties); // Assert BuildAssertions.AssertPropertyDoesNotExist(projectInstance, TargetProperties.SonarQubeTargetFilePath); AssertAnalysisTargetsAreNotImported(projectInstance); // 2. Now build -> succeeds. Info target not executed var result = BuildRunner.BuildTargets(TestContext, projectInstance.FullPath); result.AssertTargetSucceeded(TargetConstants.DefaultBuildTarget); result.AssertTargetNotExecuted(TargetConstants.ImportBeforeInfoTarget); result.AssertExpectedErrorCount(0); }
public void ImportsBefore_SonarQubeTargetsPathNotSet() { // 1. Prebuild // Arrange var projectXml = @" <PropertyGroup> <SonarQubeTargetsPath /> <AGENT_BUILDDIRECTORY /> <TF_BUILD_BUILDDIRECTORY /> </PropertyGroup> "; var projectFilePath = CreateProjectFile(projectXml); // Act var projectInstance = CreateAndEvaluateProject(projectFilePath); // Assert BuildAssertions.AssertPropertyDoesNotExist(projectInstance, TargetProperties.SonarQubeTargetFilePath); AssertAnalysisTargetsAreNotImported(projectInstance); // 2. Now build -> succeeds. Info target not executed var result = BuildRunner.BuildTargets(TestContext, projectInstance.FullPath); result.AssertTargetSucceeded(TargetConstants.DefaultBuildTarget); result.AssertTargetNotExecuted(TargetConstants.ImportBeforeInfoTarget); result.AssertExpectedErrorCount(0); }
public void ImportsBefore_BuildingInsideVS_NotImported() { // 1. Pre-build // Arrange var dummySonarTargetsDir = EnsureDummyIntegrationTargetsFileExists(); var preImportProperties = new WellKnownProjectProperties { SonarQubeTempPath = Path.GetTempPath(), SonarQubeTargetsPath = Path.GetDirectoryName(dummySonarTargetsDir), BuildingInsideVS = "tRuE" // should not be case-sensitive }; // Act var projectInstance = CreateAndEvaluateProject(preImportProperties); // Assert BuildAssertions.AssertExpectedPropertyValue(projectInstance, TargetProperties.SonarQubeTargetFilePath, dummySonarTargetsDir); AssertAnalysisTargetsAreNotImported(projectInstance); // 2. Now build -> succeeds var result = BuildRunner.BuildTargets(TestContext, projectInstance.FullPath); result.AssertTargetSucceeded(TargetConstants.DefaultBuildTarget); result.AssertTargetNotExecuted(TargetConstants.ImportBeforeInfoTarget); result.AssertExpectedErrorCount(0); }
public void Roslyn_Settings_TempFolderIsNotSet() { // Arrange var projectSnippet = @" <PropertyGroup> <ErrorLog>pre-existing.log</ErrorLog> <ResolvedCodeAnalysisRuleset>pre-existing.ruleset</ResolvedCodeAnalysisRuleset> <WarningsAsErrors>CS101</WarningsAsErrors> <TreatWarningsAsErrors>true</TreatWarningsAsErrors> <!-- This will override the value that was set earlier in the project file --> <SonarQubeTempPath /> </PropertyGroup> "; var projectFilePath = CreateProjectFile(null, projectSnippet); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath, TargetConstants.OverrideRoslynAnalysisTarget); // Assert result.AssertTargetNotExecuted(TargetConstants.OverrideRoslynAnalysisTarget); result.AssertTargetNotExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget); // Existing properties should not be changed AssertExpectedErrorLog(result, "pre-existing.log"); AssertExpectedResolvedRuleset(result, "pre-existing.ruleset"); result.AssertExpectedItemGroupCount(TargetProperties.AnalyzerItemType, 0); result.AssertExpectedItemGroupCount(TargetProperties.AdditionalFilesItemType, 0); result.AssertExpectedCapturedPropertyValue(TargetProperties.TreatWarningsAsErrors, "true"); result.AssertExpectedCapturedPropertyValue(TargetProperties.WarningsAsErrors, "CS101"); }
public void E2E_MissingProjectGuid_ShouldGenerateRandomOne() { // Projects with missing guids should have a warning emitted. The project info // should still be generated. // Arrange var context = CreateContext(); // Include a compilable file to avoid warnings about no files var codeFilePath = context.CreateInputFile("codeFile1.txt"); var projectXml = $@" <PropertyGroup> <ProjectGuid /> </PropertyGroup> <ItemGroup> <Compile Include='{codeFilePath}' /> </ItemGroup> "; var projectFilePath = context.CreateProjectFile(projectXml); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuild); // Build should succeed with warnings var actualStructure = context.ValidateAndLoadProjectStructure(); actualStructure.ProjectInfo.ProjectGuid.Should().NotBeEmpty(); actualStructure.ProjectInfo.ProjectGuid.Should().NotBe(Guid.Empty); result.AssertNoWarningsOrErrors(); }
private ProjectInfo ExecuteWriteProjectInfo(string projectFilePath, string rootOutputFolder, bool noWarningOrErrors = true) { // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath, // The "write" target depends on a couple of other targets having executed first to set properties appropriately TargetConstants.SonarCategoriseProject, TargetConstants.SonarCreateProjectSpecificDirs, TargetConstants.SonarWriteFilesToAnalyze, TargetConstants.SonarWriteProjectData); // Assert result.AssertTargetSucceeded(TargetConstants.SonarCreateProjectSpecificDirs); result.AssertTargetSucceeded(TargetConstants.SonarWriteFilesToAnalyze); result.AssertTargetSucceeded(TargetConstants.SonarWriteProjectData); result.AssertTargetExecuted(TargetConstants.SonarWriteProjectData); if (noWarningOrErrors) { result.AssertNoWarningsOrErrors(); } // Check expected project outputs Directory.EnumerateDirectories(rootOutputFolder).Should().HaveCount(1, "Only expecting one child directory to exist under the root analysis output folder"); var projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectFilePath); return(projectInfo); }
public void E2E_OutputFolderStructure() { // Checks the output folder structure is correct for a simple solution // Arrange var context = CreateContext(); var codeFilePath = context.CreateInputFile("codeFile1.txt"); var projectXml = $@" <ItemGroup> <Compile Include='{codeFilePath}' /> </ItemGroup> "; var projectFilePath = context.CreateProjectFile(projectXml); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuild); result.AssertErrorCount(0); result.AssertWarningCount(0); result.AssertTargetOrdering( TargetConstants.SonarCategoriseProject, TargetConstants.SonarWriteFilesToAnalyze, TargetConstants.DefaultBuild, TargetConstants.InvokeSonarWriteProjectData_NonRazorProject, TargetConstants.SonarWriteProjectData); context.ValidateAndLoadProjectStructure(); }
public void E2E_HasManagedAndContentFiles_VB() { // Arrange var context = CreateContext(); // Mix of analyzable and non-analyzable files var none1 = context.CreateInputFile("none1.txt"); var foo1 = context.CreateInputFile("foo1.txt"); var code1 = context.CreateInputFile("code1.vb"); var code2 = context.CreateInputFile("code2.vb"); var projectXml = $@" <ItemGroup> <None Include='{none1}' /> <Foo Include='{foo1}' /> <Compile Include='{code1}' /> <Compile Include='{code2}' /> </ItemGroup> "; var projectFilePath = context.CreateProjectFile(projectXml, isVB: true); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuild); // Build should succeed with warnings // Check the projectInfo.xml file points to the file containing the list of files to analyze var actualStructure = context.ValidateAndLoadProjectStructure(); actualStructure.AssertExpectedFileList("\\none1.txt", "\\code1.vb", "\\code2.vb"); }
public void Razor_PreserveRazorCompilationErrorLog() { // Arrange var rootInputFolder = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext, "Inputs"); var rootOutputFolder = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext, "Outputs"); var projectSnippet = $@" <PropertyGroup> <SonarQubeTempPath>{rootInputFolder}</SonarQubeTempPath> <SonarQubeOutputPath>{rootOutputFolder}</SonarQubeOutputPath> <SonarErrorLog>OriginalValueFromFirstBuild.json</SonarErrorLog> <RazorCompilationErrorLog>C:\UserDefined.json</RazorCompilationErrorLog> <!-- Value used in Sdk.Razor.CurrentVersion.targets --> <RazorTargetNameSuffix>.Views</RazorTargetNameSuffix> </PropertyGroup> <ItemGroup> <RazorCompile Include='SomeRandomValue'> </RazorCompile> </ItemGroup> "; var filePath = CreateProjectFile(null, projectSnippet); // Act var result = BuildRunner.BuildTargets(TestContext, filePath, TargetConstants.SonarPrepareRazorProjectCodeAnalysis); // Assert result.AssertTargetExecuted(TargetConstants.SonarPrepareRazorProjectCodeAnalysis); AssertExpectedErrorLog(result, @"C:\UserDefined.json"); }
[TestCategory("E2E"), TestCategory("Targets")] // SONARMSBRU-104: files under the obj folder should be excluded from analysis public void E2E_IntermediateOutputFilesAreExcluded() { // Arrange var rootInputFolder = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext); var rootOutputFolder = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext, "Outputs"); // Add files that should be analyzed var nonObjFolder = Path.Combine(rootInputFolder, "foo"); Directory.CreateDirectory(nonObjFolder); var compile1 = CreateEmptyFile(rootInputFolder, "compile1.cs"); CreateEmptyFile(nonObjFolder, "compile2.cs"); // Add files under the obj folder that should not be analyzed var objFolder = Path.Combine(rootInputFolder, "obj"); var objSubFolder1 = Path.Combine(objFolder, "debug"); var objSubFolder2 = Path.Combine(objFolder, "xxx"); // any folder under obj should be ignored Directory.CreateDirectory(objSubFolder1); Directory.CreateDirectory(objSubFolder2); // File in obj var objFile = CreateEmptyFile(objFolder, "objFile1.cs"); // File in obj\debug CreateEmptyFile(objSubFolder1, "objDebugFile1.cs"); // File in obj\xxx var objFooFile = CreateEmptyFile(objSubFolder2, "objFooFile.cs"); var projectXml = $@" <ItemGroup> <Compile Include='{compile1}' /> <Compile Include='foo\compile2.cs' /> <Compile Include='{objFile}' /> <Compile Include='obj\debug\objDebugFile1.cs' /> <Compile Include='{objFooFile}' /> </ItemGroup> "; var projectFilePath = CreateProjectFile(projectXml, rootOutputFolder, isVB: true); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuildTarget); // Build should succeed with warnings var projectSpecificOutputDir = CheckProjectSpecificOutputStructure(rootOutputFolder); // Check the list of files to be analyzed var expectedFilesToAnalyzeFilePath = AssertFileExists(projectSpecificOutputDir, ExpectedAnalysisFilesListFileName); var fileList = File.ReadLines(expectedFilesToAnalyzeFilePath); fileList.Should().BeEquivalentTo(new string[] { rootInputFolder + "\\compile1.cs", rootInputFolder + "\\foo\\compile2.cs" }); }
private BuildLog Execute_E2E_TestProjects_ProtobufsUpdated(bool isTestProject, string projectSpecificSubDir) { // Protobuf files containing metrics information should be created for test projects. // However, some of the metrics files should be empty, as should the issues report. // See [MMF-485] : https://jira.sonarsource.com/browse/MMF-486 // This method creates some non-empty dummy protobuf files during a build. // The caller can should check that the protobufs have been updated/not-updated, // as expected, depending on the type of the project being built. // Arrange var context = CreateContext(); var code1 = context.CreateInputFile("code1.cs"); var projectXml = $@" <PropertyGroup> <SonarQubeTestProject>{isTestProject.ToString()}</SonarQubeTestProject> </PropertyGroup> <ItemGroup> <Compile Include='{code1}' /> </ItemGroup> <!-- Target to create dummy, non-empty protobuf files. We can't do this from code since the targets create a unique folder. We have to insert this target into the build after the unique folder has been created, but before the targets that modify the protobufs are executed --> <Target Name='CreateDummyProtobufFiles' DependsOnTargets='SonarCreateProjectSpecificDirs' BeforeTargets='OverrideRoslynCodeAnalysisProperties'> <Error Condition=""$(ProjectSpecificOutDir)==''"" Text='Test error: ProjectSpecificOutDir is not set' /> <Message Text='CAPTURE___PROPERTY___ProjectSpecificOutDir___$(ProjectSpecificOutDir)' Importance='high' /> <!-- Write the protobufs to an arbitrary subdirectory under the project-specific folder. --> <MakeDir Directories='$(ProjectSpecificOutDir)\{projectSpecificSubDir}' /> <WriteLinesToFile File='$(ProjectSpecificOutDir)\{projectSpecificSubDir}\encoding.pb' Lines='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' /> <WriteLinesToFile File='$(ProjectSpecificOutDir)\{projectSpecificSubDir}\file-metadata.pb' Lines='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' /> <WriteLinesToFile File='$(ProjectSpecificOutDir)\{projectSpecificSubDir}\metrics.pb' Lines='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' /> <WriteLinesToFile File='$(ProjectSpecificOutDir)\{projectSpecificSubDir}\symrefs.pb' Lines='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' /> <WriteLinesToFile File='$(ProjectSpecificOutDir)\{projectSpecificSubDir}\token-cpd.pb' Lines='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' /> <WriteLinesToFile File='$(ProjectSpecificOutDir)\{projectSpecificSubDir}\token-type.pb' Lines='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' /> </Target> "; var projectFilePath = context.CreateProjectFile(projectXml); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath); // Assert result.AssertTargetSucceeded(TargetConstants.DefaultBuild); // Build should succeed with warnings var actualStructure = context.ValidateAndLoadProjectStructure(); // Sanity check that the above target was executed result.AssertTargetExecuted("CreateDummyProtobufFiles"); var projectSpecificOutputDir2 = result.GetPropertyValue("ProjectSpecificOutDir"); projectSpecificOutputDir2.Should().Be(actualStructure.ProjectSpecificOutputDir); AssertNoAdditionalFilesInFolder(actualStructure.ProjectSpecificOutputDir, ProtobufFileNames.Concat(new[] { ExpectedAnalysisFilesListFileName, ExpectedIssuesFileName, FileConstants.ProjectInfoFileName }).ToArray()); return(result); }
private BuildLog CreateProjectAndLoad(string projectSnippet) { projectSnippet += @"<Target Name=""DoNothing"" />"; var projectDirectory = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext); var targetTestUtils = new TargetsTestsUtils(TestContext); var projectTemplate = targetTestUtils.GetProjectTemplate(null, projectDirectory, null, projectSnippet); var projectFile = targetTestUtils.CreateProjectFile(projectDirectory, projectTemplate); return(BuildRunner.BuildTargets(TestContext, projectFile, "DoNothing")); }
public void TargetExecutionOrderForRazor() { // Arrange var rootInputFolder = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext, "Inputs"); var rootOutputFolder = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext, "Outputs"); TestUtils.CreateEmptyFile(TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext), "Index.cshtml"); // We need to set the CodeAnalyisRuleSet property if we want ResolveCodeAnalysisRuleSet // to be executed. See test bug https://github.com/SonarSource/sonar-scanner-msbuild/issues/776 var dummyQpRulesetPath = TestUtils.CreateValidEmptyRuleset(rootInputFolder, "dummyQp"); var projectSnippet = $@" <PropertyGroup> <SonarQubeTempPath>{rootInputFolder}</SonarQubeTempPath> <SonarQubeOutputPath>{rootInputFolder}</SonarQubeOutputPath> <SonarQubeConfigPath>{rootOutputFolder}</SonarQubeConfigPath> <CodeAnalysisRuleSet>{dummyQpRulesetPath}</CodeAnalysisRuleSet> <ImportMicrosoftCSharpTargets>false</ImportMicrosoftCSharpTargets> <TargetFramework>net5</TargetFramework> <!-- Prevent references resolution --> <DesignTimeBuild>true</DesignTimeBuild> <GenerateDependencyFile>false</GenerateDependencyFile> <GenerateRuntimeConfigurationFiles>false</GenerateRuntimeConfigurationFiles> </PropertyGroup> "; var txtFilePath = CreateProjectFile(null, projectSnippet); var csprojFilePath = txtFilePath + ".csproj"; File.WriteAllText(csprojFilePath, File.ReadAllText(txtFilePath).Replace("<Project ", @"<Project Sdk=""Microsoft.NET.Sdk.Web"" ")); // Act var result = BuildRunner.BuildTargets(TestContext, csprojFilePath, TargetConstants.DefaultBuild); // Assert // Checks that should succeed irrespective of the MSBuild version result.AssertTargetSucceeded(TargetConstants.DefaultBuild); result.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysis); result.AssertTargetOrdering( TargetConstants.SonarResolveReferences, TargetConstants.SonarOverrideRunAnalyzers, TargetConstants.BeforeCompile, TargetConstants.ResolveCodeAnalysisRuleSet, TargetConstants.SonarCategoriseProject, TargetConstants.OverrideRoslynAnalysis, TargetConstants.SetRoslynAnalysisProperties, TargetConstants.CoreCompile, TargetConstants.InvokeSonarWriteProjectData_RazorProject, TargetConstants.SonarWriteProjectData, TargetConstants.SonarPrepareRazorProjectCodeAnalysis, TargetConstants.RazorCoreCompile, TargetConstants.SonarFinishRazorProjectCodeAnalysis, TargetConstants.DefaultBuild); }
private BuildLog BuildAndRunTarget(string projectFileName, string projectXmlSnippet, string analysisConfigDir = "c:\\dummy") { var projectFilePath = CreateProjectFile(projectFileName, projectXmlSnippet, analysisConfigDir); // Act var result = BuildRunner.BuildTargets(TestContext, projectFilePath, TargetConstants.SonarCategoriseProject); // Assert result.AssertTargetSucceeded(TargetConstants.SonarCategoriseProject); return(result); }
public void Roslyn_Settings_LanguageMissing_NoError() { // Arrange // Set the config directory so the targets know where to look for the analysis config file var confDir = TestUtils.CreateTestSpecificFolder(TestContext, "config"); // Create a valid config file that does not contain analyzer settings var config = new AnalysisConfig(); var configFilePath = Path.Combine(confDir, FileConstants.ConfigFileName); config.Save(configFilePath); // Create the project var properties = new WellKnownProjectProperties { SonarQubeConfigPath = confDir, ResolvedCodeAnalysisRuleset = "c:\\should.be.overridden.ruleset" }; var projectRoot = CreateValidProjectSetup(properties); projectRoot.AddProperty("Language", ""); projectRoot.AddItem(TargetProperties.AnalyzerItemType, "should.be.removed.analyzer1.dll"); const string additionalFileName = "should.not.be.removed.additional1.txt"; projectRoot.AddItem(TargetProperties.AdditionalFilesItemType, additionalFileName); projectRoot.Save(); // re-save the modified project // Act var result = BuildRunner.BuildTargets(TestContext, projectRoot.FullPath, TargetConstants.OverrideRoslynAnalysisTarget); var projectSpecificConfFilePath = result.GetCapturedPropertyValue(TargetProperties.ProjectConfFilePath); var expectedRoslynAdditionalFiles = new string[] { projectSpecificConfFilePath, additionalFileName /* additional files are not removed */ }; // Assert result.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget); result.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget); result.BuildSucceeded.Should().BeTrue(); result.MessageLog.Contains("Analysis language is not specified"); AssertErrorLogIsSetBySonarQubeTargets(result); AssertExpectedResolvedRuleset(result, string.Empty); result.AssertExpectedItemGroupCount(TargetProperties.AnalyzerItemType, 0); AssertExpectedItemValuesExists(result, TargetProperties.AdditionalFilesItemType, expectedRoslynAdditionalFiles); }