/// <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);
        }
Beispiel #4
0
        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");
        }
Beispiel #5
0
        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);
        }
Beispiel #8
0
        /// <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());
        }
Beispiel #9
0
        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);
        }
Beispiel #12
0
        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);
        }
Beispiel #13
0
        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");
        }
Beispiel #16
0
        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);
        }
Beispiel #18
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");
        }
Beispiel #20
0
        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();
        }
Beispiel #21
0
        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);
        }
Beispiel #22
0
        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();
        }
Beispiel #23
0
        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");
        }
Beispiel #24
0
        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"
            });
        }
Beispiel #26
0
        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);
        }
Beispiel #27
0
        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"));
        }
Beispiel #28
0
        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);
        }
Beispiel #30
0
        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);
        }