public void Roslyn_Settings_ValidSetup()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();
            ProjectRootElement projectRoot = CreateValidProjectSetup(null);

            // Add analyzer settings that should be removed
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "Analyzer1.dll");
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\Analyzer2.dll");

            projectRoot.AddItem(TargetProperties.AdditionalFilesItemType, "additional1.txt");
            projectRoot.AddItem(TargetProperties.AdditionalFilesItemType, "additional2.txt");

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the intermediate working properties have the expected values
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynRulesetExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynAssemblyExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarLintFound", "true");

            // Check the error log and ruleset properties are set
            string targetDir = result.ProjectStateAfterBuild.GetPropertyValue(TargetProperties.TargetDir);
            string expectedErrorLog = Path.Combine(targetDir, ErrorLogFileName);
            AssertExpectedAnalysisProperties(result, expectedErrorLog, GetDummyRulesetFilePath(), GetDummySonarLintXmlFilePath());
            AssertExpectedItemValuesExists(result, TargetProperties.AnalyzerItemType, GetSonarLintAnalyzerFilePaths());

            BuildAssertions.AssertWarningsAreNotTreatedAsErrorsNorIgnored(result);
        }
        public void Roslyn_Settings_ValidSetup()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();

            // Set the config directory so the targets know where to look for the analysis config file
            string confDir = TestUtils.CreateTestSpecificFolder(this.TestContext, "config");

            // Create a valid config file containing analyzer settings
            string[] expectedAssemblies = new string[] { "c:\\data\\config.analyzer1.dll", "c:\\config2.dll" };
            string[] expectedAdditionalFiles = new string[] { "c:\\config.1.txt", "c:\\config.2.txt" };

            AnalysisConfig config = new AnalysisConfig();
            config.AnalyzerSettings = new AnalyzerSettings();
            config.AnalyzerSettings.RuleSetFilePath = "d:\\my.ruleset";
            config.AnalyzerSettings.AnalyzerAssemblyPaths = expectedAssemblies.ToList();
            config.AnalyzerSettings.AdditionalFilePaths = expectedAdditionalFiles.ToList();
            string configFilePath = Path.Combine(confDir, FileConstants.ConfigFileName);
            config.Save(configFilePath);

            // Create the project
            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeConfigPath = confDir;
            properties.ResolvedCodeAnalysisRuleset = "c:\\should.be.overridden.ruleset";

            ProjectRootElement projectRoot = CreateValidProjectSetup(properties);

            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "should.be.removed.analyzer1.dll");
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\should.be.removed.analyzer2.dll");
            projectRoot.AddItem(TargetProperties.AdditionalFilesItemType, "should.be.removed.additional1.txt");
            projectRoot.AddItem(TargetProperties.AdditionalFilesItemType, "should.be.removed.additional2.txt");

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the error log and ruleset properties are set
            AssertErrorLogIsSetBySonarQubeTargets(result);
            AssertExpectedResolvedRuleset(result, "d:\\my.ruleset");
            AssertExpectedItemValuesExists(result, TargetProperties.AdditionalFilesItemType, expectedAdditionalFiles);
            AssertExpectedItemValuesExists(result, TargetProperties.AnalyzerItemType, expectedAssemblies);

            BuildAssertions.AssertWarningsAreNotTreatedAsErrorsNorIgnored(result);
        }
        public void StyleCop_TargetExecutionOrder()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;
            properties.SonarQubeOutputPath = rootInputFolder;
            properties.SonarQubeConfigPath = rootOutputFolder;

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            // Add some settings we expect to be ignored
            AddAnalysisSetting("sonar.other.setting", "other value", projectRoot);
            AddAnalysisSetting("sonar.other.setting.2", "other value 2", projectRoot);
            projectRoot.Save();

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.DefaultBuildTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.SetStyleCopSettingsTarget);
            logger.AssertExpectedTargetOrdering(TargetConstants.SetStyleCopSettingsTarget, TargetConstants.WriteProjectDataTarget);

            AssertExpectedStyleCopSetting(projectRoot.ProjectFileLocation.File, result);
        }
        public void SQBeforeClCompile_DefaultBinPath_BinariesFound_TaskExecuted()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");
            BuildLogger logger = new BuildLogger();

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;
            properties.BuildWrapperSkipFlag = "false";
            properties.SonarQubeOutputPath = rootOutputFolder;

            // By default, the targets try to find the build wrapper binaries in a specific folder
            // below the folder containing the integration tasks assembly

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            // Check we can find the integration targets file in the expected location
            string targetsDir = TestUtils.GetTestSpecificFolderName(this.TestContext);
            string integrationTargetsPath = Path.Combine(targetsDir, TestUtils.AnalysisTargetFile);
            Assert.IsTrue(File.Exists(integrationTargetsPath), "Test setup error: did not find the integration targets in the expected location: {0}", integrationTargetsPath);

            // The targets expect to find the build wrapper binaries in a folder under
            // the folder containing the tasks assembly.
            // Create a dummy tasks assembly
            string dummyAsmFilePath = Path.Combine(targetsDir, "SonarQube.Integration.Tasks.dll");
            Assert.IsFalse(File.Exists(dummyAsmFilePath), "Test setup error: not expecting the integration tasks assembly to exist at {0}", dummyAsmFilePath);
            File.WriteAllText(dummyAsmFilePath, "dummy content");

            // Create the build wrapper sub directory
            string buildWrapperBinDir = Path.Combine(targetsDir, "build-wrapper-win-x86");
            Directory.CreateDirectory(buildWrapperBinDir);

            // Create the required build wrapper files relative to this location
            CreateBuildWrapperMarkerFile(buildWrapperBinDir);

            // Act
            BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.BuildWrapperBeforeClCompileTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.BuildWrapperBeforeClCompileTarget);
            logger.AssertTargetExecuted(TargetConstants.BuildWrapperAttachTarget);
            // Note: task should fail because not all required files are present. However,
            // the important thing for this test is that is executed.
            logger.AssertTaskExecuted(TargetConstants.BuildWrapperAttachTask);
        }
        public void Roslyn_SetResults_ResultsFileDoesNotExist()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.SetRoslynResultsTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.SetRoslynResultsTarget);
            BuildAssertions.AssertAnalysisSettingDoesNotExist(result, RoslynAnalysisResultsSettingName);
        }
        public void StyleCop_TempFolderIsSet()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;
            properties.SonarQubeOutputPath = rootInputFolder;

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.SetStyleCopSettingsTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.SetStyleCopSettingsTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.SetStyleCopSettingsTarget);
        }
Example #7
0
        public void E2E_FxCop_OutputFolderSet_SonarRulesetNotFound()
        {
            // Arrange
            string rootInputFolder  = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            // Set the output folder and config path
            // Don't create a ruleset file on disc
            string fxCopLogFile = Path.Combine(rootInputFolder, "FxCopResults.xml");
            WellKnownProjectProperties preImportProperties = new WellKnownProjectProperties();

            preImportProperties.SonarQubeTempPath   = rootOutputFolder; // FIXME
            preImportProperties.SonarQubeOutputPath = rootOutputFolder;
            preImportProperties.RunCodeAnalysis     = "true";           // our targets should override this value
            preImportProperties.CodeAnalysisLogFile = fxCopLogFile;
            preImportProperties.SonarQubeConfigPath = rootInputFolder;
            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, preImportProperties);

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger);

            // Assert
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);

            logger.AssertTargetExecuted(TargetConstants.OverrideFxCopSettingsTarget);  // output folder is set so this should be executed
            logger.AssertTargetNotExecuted(TargetConstants.SetFxCopResultsTarget);

            // We expect the core FxCop *target* to have been started, but it should then be skipped
            // executing the FxCop *task* because the condition on the target is false
            // -> the FxCop output file should not be produced
            AssertFxCopNotExecuted(logger);

            Assert.IsFalse(File.Exists(fxCopLogFile), "FxCop log file should not have been produced");

            ProjectInfo projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectRoot.FullPath);

            ProjectInfoAssertions.AssertAnalysisResultDoesNotExists(projectInfo, AnalysisType.FxCop.ToString());
        }
        public void Roslyn_Settings_NotRunForExcludedProject()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();
            WellKnownProjectProperties properties = new WellKnownProjectProperties
            {
                SonarQubeExclude            = "TRUE", // mark the project as excluded
                ResolvedCodeAnalysisRuleset = "Dummy value"
            };

            ProjectRootElement projectRoot = CreateValidProjectSetup(properties);

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetNotExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            AssertCodeAnalysisIsDisabled(result, properties.ResolvedCodeAnalysisRuleset);
        }
Example #9
0
        public void Roslyn_TargetExecutionOrder()
        {
            // Arrange
            string rootInputFolder  = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            WellKnownProjectProperties properties = new WellKnownProjectProperties();

            properties.SonarQubeTempPath   = rootInputFolder;
            properties.SonarQubeOutputPath = rootInputFolder;
            properties.SonarQubeConfigPath = rootOutputFolder;

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);


            // Add some settings we expect to be ignored
            AddAnalysisSetting("sonar.other.setting", "other value", projectRoot);
            projectRoot.Save();

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.DefaultBuildTarget);

            // Assert
            // Checks that should succeed irrespective of the MSBuild version
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);

            logger.AssertExpectedTargetOrdering(
                TargetConstants.ResolveCodeAnalysisRuleSet,
                TargetConstants.CategoriseProjectTarget,
                TargetConstants.OverrideRoslynAnalysisTarget,
                TargetConstants.SetRoslynAnalysisPropertiesTarget,
                TargetConstants.CoreCompile,
                TargetConstants.DefaultBuildTarget,
                TargetConstants.SetRoslynResultsTarget,
                TargetConstants.WriteProjectDataTarget);
        }
        public void Roslyn_SetResults_ResultsFileExists()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");

            string resultsFile = TestUtils.CreateTextFile(rootInputFolder, "error.report.txt", "dummy report content");

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;
            properties[TargetProperties.ErrorLog] = resultsFile;

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult actualResult = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.SetRoslynResultsTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.SetRoslynResultsTarget);
            BuildAssertions.AssertExpectedAnalysisSetting(actualResult, RoslynAnalysisResultsSettingName, resultsFile);
        }
        public void Roslyn_SetResults_ResultsFileExists()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");

            string resultsFile = TestUtils.CreateTextFile(rootInputFolder, "error.report.txt", "dummy report content");

            WellKnownProjectProperties properties = new WellKnownProjectProperties();

            properties.SonarQubeTempPath          = rootInputFolder;
            properties[TargetProperties.ErrorLog] = resultsFile;

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.SetRoslynResultsTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.SetRoslynResultsTarget);
            BuildAssertions.AssertExpectedAnalysisSetting(result, RoslynAnalysisResultsSettingName, resultsFile);
        }
        public void Roslyn_Settings_Analyzer_AssemblyDoesNotExist()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();
            ProjectRootElement projectRoot = CreateValidProjectSetup(null);

            this.DeleteDummySonarLintFiles();

            // The downloaded SonarLint.dll could not be found so any existing settings should be preserved
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "analyzer1.dll");
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\myfolder\\analyzer2.dll");
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\myfolder\\sonarlint.dll");

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the intermediate working properties have the expected values
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynRulesetExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarLintFound", "false");

            // Check the analyzer properties are set as expected
            AssertExpectedAnalyzersExists(result,
                "analyzer1.dll",
                "c:\\myfolder\\analyzer2.dll",
                "c:\\myfolder\\sonarlint.dll");
        }
        public void ImportsBefore_MissingAnalysisTargets()
        {
            // 1. Prebuild
            // Arrange
            WellKnownProjectProperties preImportProperties = new WellKnownProjectProperties();
            preImportProperties.SonarQubeTempPath = "nonExistentPath";
            preImportProperties.MSBuildExtensionsPath = "nonExistentPath";
            preImportProperties.TeamBuild2105BuildDirectory = "";
            preImportProperties.TeamBuildLegacyBuildDirectory = "";

            // Act
            ProjectInstance projectInstance = this.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
            BuildLogger logger = new BuildLogger();

            BuildResult result = BuildUtilities.BuildTargets(projectInstance, logger);

            BuildAssertions.AssertTargetFailed(result, TargetConstants.DefaultBuildTarget);
            logger.AssertTargetExecuted(TargetConstants.ImportBeforeInfoTarget);
            logger.AssertExpectedErrorCount(1);

            string projectName = Path.GetFileName(projectInstance.FullPath);
            Assert.IsTrue(logger.Errors[0].Message.Contains(projectName), "Expecting the error message to contain the project file name");
        }
        public void ImportsBefore_TargetsExist()
        {
            // 1. Pre-build
            // Arrange
            string dummySonarTargetsDir = this.EnsureDummyIntegrationTargetsFileExists();

            WellKnownProjectProperties preImportProperties = new WellKnownProjectProperties();
            preImportProperties.SonarQubeTempPath = Path.GetTempPath();
            preImportProperties.SonarQubeTargetsPath = Path.GetDirectoryName(dummySonarTargetsDir);
            preImportProperties.TeamBuild2105BuildDirectory = "";
            preImportProperties.TeamBuildLegacyBuildDirectory = "";

            // Act
            ProjectInstance projectInstance = this.CreateAndEvaluateProject(preImportProperties);

            // Assert
            BuildAssertions.AssertExpectedPropertyValue(projectInstance, TargetProperties.SonarQubeTargetFilePath, dummySonarTargetsDir);
            AssertAnalysisTargetsAreImported(projectInstance);


            // 2. Now build -> succeeds
            BuildLogger logger = new BuildLogger();

            BuildResult result = BuildUtilities.BuildTargets(projectInstance, logger);

            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);
            logger.AssertTargetExecuted(TargetConstants.ImportBeforeInfoTarget);
            logger.AssertExpectedErrorCount(0);
        }
 private void AssertFxCopExecuted(BuildLogger logger)
 {
     logger.AssertTargetExecuted(TargetConstants.FxCopTarget);
     logger.AssertTaskExecuted(TargetConstants.FxCopTask);
 }
        public void E2E_FxCop_TestProject_TestProjectTypeGuid()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            string fxCopLogFile = Path.Combine(rootInputFolder, "FxCopResults.xml");
            WellKnownProjectProperties preImportProperties = new WellKnownProjectProperties();
            preImportProperties.SonarQubeTempPath = rootOutputFolder; // FIXME
            preImportProperties.SonarQubeOutputPath = rootOutputFolder;
            preImportProperties.CodeAnalysisLogFile = fxCopLogFile;
            preImportProperties.CodeAnalysisRuleset = "specifiedInProject.ruleset";

            preImportProperties.ProjectTypeGuids = "X;" + TargetConstants.MsTestProjectTypeGuid.ToUpperInvariant() + ";Y";

            preImportProperties[TargetProperties.SonarQubeConfigPath] = rootInputFolder;
            CreateValidFxCopRuleset(rootInputFolder, string.Format(TargetProperties.SonarQubeRulesetFormat, "cs"));

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, preImportProperties);

            // Add a file to the project
            string itemPath = TestUtils.CreateTextFile(rootInputFolder, "code1.cs", "class myclassXXX{}");
            projectRoot.AddItem(TargetProperties.ItemType_Compile, itemPath);
            projectRoot.Save();

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger);

            // Assert
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);

            logger.AssertExpectedTargetOrdering(
                TargetConstants.CategoriseProjectTarget,
                TargetConstants.OverrideFxCopSettingsTarget,
                TargetConstants.FxCopTarget,
                TargetConstants.DefaultBuildTarget,
                TargetConstants.CalculateFilesToAnalyzeTarget,
                TargetConstants.WriteProjectDataTarget);

            // We expect the FxCop target to be executed...
            logger.AssertTargetExecuted(TargetConstants.FxCopTarget);
            // ... but we don't expect the FxCop *task* to have executed
            logger.AssertTaskNotExecuted(TargetConstants.FxCopTask);

            logger.AssertTargetNotExecuted(TargetConstants.SetFxCopResultsTarget);

            ProjectInfo projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectRoot.FullPath);
            ProjectInfoAssertions.AssertAnalysisResultDoesNotExists(projectInfo, AnalysisType.FxCop.ToString());
        }
        public void Roslyn_Settings_ValidSetup_OverrideExistingSettings_RelativePath()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();

            // Add some existing analyzer settings
            ProjectRootElement projectRoot = CreateValidProjectSetup(null);

            // Create a ruleset file in a location relative to the project file
            string projectFilePath = projectRoot.ProjectFileLocation.File;
            string rulesetDir = Path.Combine(Path.GetDirectoryName(projectFilePath), "subdir");
            Directory.CreateDirectory(rulesetDir);
            string rulesetFilePath = TestUtils.CreateTextFile(rulesetDir, "existing.ruleset", "dummy ruleset");

            projectRoot.AddProperty(TargetProperties.ResolvedCodeAnalysisRuleset, "subdir\\existing.ruleset");

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the error log and ruleset properties are set
            string sourceRulesetFilePath = GetDummyRulesetFilePath();
            this.TestContext.AddResultFile(sourceRulesetFilePath);

            BuildAssertions.AssertWarningsAreNotTreatedAsErrorsNorIgnored(result);

            string targetDir = result.ProjectStateAfterBuild.GetPropertyValue(TargetProperties.TargetDir);
            string expectedErrorLog = Path.Combine(targetDir, ErrorLogFileName);

            AssertExpectedAnalysisProperties(result, expectedErrorLog, sourceRulesetFilePath, GetDummySonarLintXmlFilePath());
            BuildAssertions.AssertWarningsAreNotTreatedAsErrorsNorIgnored(result);

            // Check the analyzer properties are set as expected
            List<string> expectedAnalyzers = new List<string>(GetSonarLintAnalyzerFilePaths());
            AssertExpectedItemValuesExists(result, TargetProperties.AnalyzerItemType, expectedAnalyzers.ToArray());
        }
        public void Roslyn_Settings_ValidSetup_OverrideExistingSettings_AbsolutePath()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();

            // Set the ruleset property
            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.ResolvedCodeAnalysisRuleset = "c:\\existing.ruleset";

            // Add some existing analyzer settings
            ProjectRootElement projectRoot = CreateValidProjectSetup(properties);
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "Analyzer1.dll");
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\Analyzer2.dll");

            projectRoot.AddItem(TargetProperties.AdditionalFilesItemType, "additional1.txt");
            projectRoot.AddItem(TargetProperties.AdditionalFilesItemType, "additional2.txt");


            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the error log and ruleset properties are set
            string sourceRulesetFilePath = GetDummyRulesetFilePath();
            this.TestContext.AddResultFile(sourceRulesetFilePath);

            string targetDir = result.ProjectStateAfterBuild.GetPropertyValue(TargetProperties.TargetDir);
            string expectedErrorLog = Path.Combine(targetDir, ErrorLogFileName);

            AssertExpectedAnalysisProperties(result, expectedErrorLog, sourceRulesetFilePath, GetDummySonarLintXmlFilePath());
            BuildAssertions.AssertWarningsAreNotTreatedAsErrorsNorIgnored(result);

            // Check the analyzer properties are set as expected
            List<string> expectedAnalyzers = new List<string>(GetSonarLintAnalyzerFilePaths());
            AssertExpectedItemValuesExists(result, TargetProperties.AnalyzerItemType, expectedAnalyzers.ToArray());
        }
        public void Roslyn_Settings_ValidSetup()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();
            ProjectRootElement projectRoot = CreateValidProjectSetup(null);

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            logger.AssertTaskNotExecuted(TargetConstants.MergeResultSetsTask);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the intermediate working properties have the expected values
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynRulesetExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynAssemblyExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarLintFound", "true");

            // Check the error log and ruleset properties are set
            string targetDir = result.ProjectStateAfterBuild.GetPropertyValue(TargetProperties.TargetDir);
            string expectedErrorLog = Path.Combine(targetDir, ErrorLogFileName);
            AssertExpectedAnalysisProperties(result, expectedErrorLog, GetDummyRulesetFilePath());
            AssertExpectedAnalyzersExists(result, GetSonarLintAnalyzerFilePaths());
        }
        public void Roslyn_Settings_NotRunForTestProject()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();
            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.ProjectTypeGuids = TargetConstants.MsTestProjectTypeGuid; // mark the project as a test project

            ProjectRootElement projectRoot = CreateValidProjectSetup(properties);

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetNotExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            AssertCodeAnalysisIsDisabled(result);
        }
        public void SQBeforeClCompile_DefaultBinPath_BinariesNotFound_TaskNotExecuted()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");
            BuildLogger logger = new BuildLogger();

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;
            properties.BuildWrapperSkipFlag = "false";
            properties.SonarQubeOutputPath = rootOutputFolder;

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            // Act
            BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.BuildWrapperBeforeClCompileTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.BuildWrapperBeforeClCompileTarget);
            logger.AssertTargetNotExecuted(TargetConstants.BuildWrapperAttachTarget);
        }
        public void SQBeforeClCompile_SpecifiedWrapperLocation_BinariesFound_TaskExecuted()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");
            BuildLogger logger = new BuildLogger();

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;
            properties.BuildWrapperSkipFlag = "false";
            properties.SonarQubeOutputPath = rootOutputFolder;

            string buildWrapperDir = TestUtils.CreateTestSpecificFolder(this.TestContext, "dummyBW");

            properties.BuildWrapperBinPath = buildWrapperDir;
            // Create the required build wrapper files relative to this location
            CreateBuildWrapperMarkerFile(buildWrapperDir);

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            // Act
            BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.BuildWrapperBeforeClCompileTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.BuildWrapperBeforeClCompileTarget);
            logger.AssertTargetExecuted(TargetConstants.BuildWrapperAttachTarget);
            // Note: task should fail because not all required files are present. However,
            // the important thing for this test is that is executed.
            logger.AssertTaskExecuted(TargetConstants.BuildWrapperAttachTask);
        }
        public void StyleCop_ValueAlreadySet()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;
            properties.SonarQubeOutputPath = rootInputFolder;
            properties.SonarQubeConfigPath = rootOutputFolder;

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            // Apply some SonarQubeSettings, one of which specifies the StyleCop setting
            AddAnalysisSetting("sonar.other.setting", "other value", projectRoot);
            AddAnalysisSetting(TargetConstants.StyleCopProjectPathItemName, "xxx.yyy", projectRoot);
            AddAnalysisSetting("sonar.other.setting.2", "other value 2", projectRoot);
            projectRoot.Save();

            BuildLogger logger = new BuildLogger();
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.SetStyleCopSettingsTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.SetStyleCopSettingsTarget);
            AssertExpectedStyleCopSetting("xxx.yyy", result);
        }
        public void Roslyn_Settings_Analyzer_AssemblyExists()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();
            WellKnownProjectProperties properties = new WellKnownProjectProperties();

            ProjectRootElement projectRoot = CreateValidProjectSetup(properties);

            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "analyzer1.dll"); // additional -> preserve
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\myfolder\\analyzer2.dll"); // additional -> preserve
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "sonarlint.dll"); // relative path -> remove
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\myfolder\\sonarlint.dll"); // absolute path -> remove
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "XXSONARLINT.dll"); // case-sensitivity -> remove
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "sonarLint.dll.xxx"); // doesn't match -> preserve
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\sonarLint\\my.dll"); // doesn't match -> preserve

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the intermediate working properties have the expected values
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynRulesetExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarLintFound", "true");

            // Check the analyzer properties are set as expected
            List<string> expectedAnalyzers = new List<string>(GetSonarLintAnalyzerFilePaths());
            expectedAnalyzers.Add("analyzer1.dll");
            expectedAnalyzers.Add("c:\\myfolder\\analyzer2.dll");
            expectedAnalyzers.Add("sonarLint.dll.xxx");
            expectedAnalyzers.Add("c:\\sonarLint\\my.dll");

            AssertExpectedAnalyzersExists(result, expectedAnalyzers.ToArray());
        }
        public void Roslyn_TargetExecutionOrder()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;
            properties.SonarQubeOutputPath = rootInputFolder;
            properties.SonarQubeConfigPath = rootOutputFolder;

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            // Add some settings we expect to be ignored
            AddAnalysisSetting("sonar.other.setting", "other value", projectRoot);
            projectRoot.Save();

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.DefaultBuildTarget);

            // Assert
            // Checks that should succeed irrespective of the MSBuild version
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);

            // Note: use VS2013 to run this test using MSBuild 12.0.
            // Use VS2015 to run this test using MSBuild 14.0.
            if (result.ProjectStateAfterBuild.ToolsVersion.CompareTo("14.0") < 0)
            {
                logger.AssertTargetNotExecuted(TargetConstants.ResolveCodeAnalysisRuleSet); // sanity-check: should only be in MSBuild 14.0+
                Assert.Inconclusive("This test requires MSBuild 14.0 to be installed. Version used: {0}", result.ProjectStateAfterBuild.ToolsVersion);
            }
            else
            {
                // MSBuild 14.0+ checks
                logger.AssertExpectedTargetOrdering(
                    TargetConstants.ResolveCodeAnalysisRuleSet,
                    TargetConstants.CategoriseProjectTarget,
                    TargetConstants.OverrideRoslynAnalysisTarget,
                    TargetConstants.SetRoslynAnalysisPropertiesTarget,
                    TargetConstants.CoreCompile,
                    TargetConstants.DefaultBuildTarget,
                    TargetConstants.SetRoslynResultsTarget,
                    TargetConstants.WriteProjectDataTarget);
            }
        }
        public void Roslyn_Settings_ErrorLogAlreadySet()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();
            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties[TargetProperties.ErrorLog] = "already.set.txt";

            ProjectRootElement projectRoot = CreateValidProjectSetup(properties);

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the intermediate working properties have the expected values
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynRulesetExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynAssemblyExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarLintFound", "true");

            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, TargetProperties.ErrorLog, "already.set.txt");
        }
        /// <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();
            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger,
                // The "write" target depends on a couple of other targets having executed first to set properties appropriately
                TargetConstants.CategoriseProjectTarget,
                TargetConstants.CalculateFilesToAnalyzeTarget,
                TargetConstants.WriteProjectDataTarget);

            // Assert
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.CalculateFilesToAnalyzeTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.WriteProjectDataTarget);

            logger.AssertTargetExecuted(TargetConstants.WriteProjectDataTarget);

            if (noWarningOrErrors)
            {
                logger.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");
            ProjectInfo projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectRoot.FullPath);

            return projectInfo;
        }
        public void Roslyn_Settings_RuleSetDoesNotExist()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();
            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.ResolvedCodeAnalysisRuleset = "pre-existing.ruleset";
            properties.ErrorLog = "pre-existing.log";

            ProjectRootElement projectRoot = CreateValidProjectSetup(properties);
            this.DeleteDummyRulesetFile();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the intermediate working properties have the expected values
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynRulesetExists", "False");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynAssemblyExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarLintFound", "false");

            AssertExpectedAnalysisProperties(result, "pre-existing.log", "pre-existing.ruleset");
        }
        public void E2E_FxCop_TestProject_TestProjectByName()
        {
            // Arrange
            string rootInputFolder  = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            string fxCopLogFile = Path.Combine(rootInputFolder, "FxCopResults.xml");
            WellKnownProjectProperties preImportProperties = new WellKnownProjectProperties();

            preImportProperties.SonarQubeTempPath   = rootOutputFolder; // FIXME
            preImportProperties.SonarQubeOutputPath = rootOutputFolder;
            preImportProperties.CodeAnalysisLogFile = fxCopLogFile;
            preImportProperties.CodeAnalysisRuleset = "specifiedInProject.ruleset";

            preImportProperties.SonarQubeConfigPath = rootInputFolder;

            preImportProperties[TargetProperties.SonarQubeConfigPath] = rootInputFolder;
            CreateValidFxCopRuleset(rootInputFolder, string.Format(TargetProperties.SonarQubeRulesetFormat, "cs"));

            // Create a config file in the config folder containing a reg ex to identify tests projects
            AnalysisConfig config = new AnalysisConfig();

            config.LocalSettings = new AnalysisProperties();
            config.LocalSettings.Add(new Property()
            {
                Id = IsTestFileByName.TestRegExSettingId, Value = ".testp."
            });

            string configFullPath = Path.Combine(rootInputFolder, FileConstants.ConfigFileName);

            config.Save(configFullPath);

            // Create a project with a file name that will match the reg ex
            ProjectDescriptor  descriptor  = BuildUtilities.CreateValidProjectDescriptor(rootInputFolder, "MyTestProject.proj");
            ProjectRootElement projectRoot = BuildUtilities.CreateInitializedProjectRoot(this.TestContext, descriptor, preImportProperties);


            // Add a file to the project
            string itemPath = CreateTextFile(rootInputFolder, "code1.cs", "class myclassXXX{}");

            projectRoot.AddItem(TargetProperties.ItemType_Compile, itemPath);
            projectRoot.Save();

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger);

            // Assert
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);

            logger.AssertExpectedTargetOrdering(
                TargetConstants.CategoriseProjectTarget,
                TargetConstants.OverrideFxCopSettingsTarget,
                TargetConstants.FxCopTarget,
                TargetConstants.DefaultBuildTarget,
                TargetConstants.CalculateFilesToAnalyzeTarget,
                TargetConstants.WriteProjectDataTarget);

            // We expect the FxCop target to be executed...
            logger.AssertTargetExecuted(TargetConstants.FxCopTarget);
            // ... but we don't expect the FxCop *task* to have executed
            logger.AssertTaskNotExecuted(TargetConstants.FxCopTask);

            logger.AssertTargetNotExecuted(TargetConstants.SetFxCopResultsTarget);

            ProjectInfo projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectRoot.FullPath);

            ProjectInfoAssertions.AssertAnalysisResultDoesNotExists(projectInfo, AnalysisType.FxCop.ToString());
        }
        public void Roslyn_Settings_ValidSetup_MergeWithExistingSettings()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();

            // Set the ruleset property
            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.ResolvedCodeAnalysisRuleset = "c:\\existing.ruleset";

            // Add some existing analyzer settings
            ProjectRootElement projectRoot = CreateValidProjectSetup(properties);
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "Analyzer1.dll");
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\Analyzer2.dll");

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            logger.AssertTaskExecuted(TargetConstants.MergeResultSetsTask);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the error log and ruleset properties are set
            string finalRulesetFilePath = GetDummyRulesetFilePath();
            this.TestContext.AddResultFile(finalRulesetFilePath);

            string targetDir = result.ProjectStateAfterBuild.GetPropertyValue(TargetProperties.TargetDir);
            string expectedErrorLog = Path.Combine(targetDir, ErrorLogFileName);
            AssertExpectedAnalysisProperties(result, expectedErrorLog, finalRulesetFilePath);

            RuleSetAssertions.AssertExpectedIncludeFiles(finalRulesetFilePath, "c:\\existing.ruleset");
            RuleSetAssertions.AssertExpectedIncludeAction(finalRulesetFilePath, "c:\\existing.ruleset", RuleSetAssertions.DefaultActionValue);
        }
        public void Roslyn_Settings_RuleSetExists()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rulesetFilePath = CreateDummyRuleset(rootInputFolder);

            WellKnownProjectProperties properties = new WellKnownProjectProperties();
            properties.SonarQubeTempPath = rootInputFolder;
            properties.CodeAnalysisRuleset = "should.be.overwritten";

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, properties);

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynSettingsTarget);

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynSettingsTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynSettingsTarget);

            // Check the intermediate working properties have the expected values
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRoslynRulesetExists", "True");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, "SonarQubeRunRoslynCodeAnalysis", "True");

            // Check the error log and ruleset properties are set
            string targetDir = result.ProjectStateAfterBuild.GetPropertyValue(TargetProperties.TargetDir);
            string expectedErrorLog = Path.Combine(targetDir, "SonarQube.Roslyn.ErrorLog.json");
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, TargetProperties.ErrorLog, expectedErrorLog);
            BuildAssertions.AssertExpectedPropertyValue(result.ProjectStateAfterBuild, TargetProperties.ResolvedCodeAnalysisRuleset, rulesetFilePath);
        }
        public void E2E_FxCop_NoFilesToAnalyse()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            string fxCopLogFile = Path.Combine(rootInputFolder, "FxCopResults.xml");
            WellKnownProjectProperties preImportProperties = new WellKnownProjectProperties();
            preImportProperties.SonarQubeTempPath = rootOutputFolder; // FIXME
            preImportProperties.SonarQubeOutputPath = rootOutputFolder;
            preImportProperties.RunCodeAnalysis = "false";
            preImportProperties.CodeAnalysisLogFile = fxCopLogFile;
            preImportProperties.CodeAnalysisRuleset = "specifiedInProject.ruleset";

            preImportProperties[TargetProperties.SonarQubeConfigPath] = rootInputFolder;
            CreateValidFxCopRuleset(rootInputFolder, string.Format(TargetProperties.SonarQubeRulesetFormat, "cs"));

            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, preImportProperties);

            // Add some files to the project
            string itemPath = TestUtils.CreateTextFile(rootInputFolder, "content1.txt", "aaaa");
            projectRoot.AddItem("Content", itemPath);

            itemPath = TestUtils.CreateTextFile(rootInputFolder, "code1.cs", "class myclassXXX{} // wrong item type");
            projectRoot.AddItem("CompileXXX", itemPath);

            projectRoot.Save();

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger);

            // Assert
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);

            logger.AssertExpectedTargetOrdering(
                TargetConstants.CategoriseProjectTarget,
                TargetConstants.OverrideFxCopSettingsTarget,

                TargetConstants.FxCopTarget,
                TargetConstants.SetFxCopResultsTarget, // should set the FxCop results after the platform "run Fx Cop" target

                TargetConstants.DefaultBuildTarget,
                TargetConstants.CalculateFilesToAnalyzeTarget,
                TargetConstants.WriteProjectDataTarget);

            logger.AssertTargetExecuted(TargetConstants.SetFxCopResultsTarget);

            ProjectInfo projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectRoot.FullPath);
            ProjectInfoAssertions.AssertAnalysisResultDoesNotExists(projectInfo, AnalysisType.FxCop.ToString());
        }
        public void E2E_FxCop_TestProject_TestProjectByName()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            string fxCopLogFile = Path.Combine(rootInputFolder, "FxCopResults.xml");
            WellKnownProjectProperties preImportProperties = new WellKnownProjectProperties();
            preImportProperties.SonarQubeTempPath = rootOutputFolder; // FIXME
            preImportProperties.SonarQubeOutputPath = rootOutputFolder;
            preImportProperties.CodeAnalysisLogFile = fxCopLogFile;
            preImportProperties.CodeAnalysisRuleset = "specifiedInProject.ruleset";

            preImportProperties.SonarQubeConfigPath = rootInputFolder;

            preImportProperties[TargetProperties.SonarQubeConfigPath] = rootInputFolder;
            CreateValidFxCopRuleset(rootInputFolder, string.Format(TargetProperties.SonarQubeRulesetFormat, "cs"));

            // Create a config file in the config folder containing a reg ex to identify tests projects
            AnalysisConfig config = new AnalysisConfig();
            config.LocalSettings = new AnalysisProperties();
            config.LocalSettings.Add(new Property() { Id = IsTestFileByName.TestRegExSettingId, Value = ".testp." });

            string configFullPath = Path.Combine(rootInputFolder, FileConstants.ConfigFileName);
            config.Save(configFullPath);

            // Create a project with a file name that will match the reg ex
            ProjectDescriptor descriptor = BuildUtilities.CreateValidProjectDescriptor(rootInputFolder, "MyTestProject.proj");
            ProjectRootElement projectRoot = BuildUtilities.CreateInitializedProjectRoot(this.TestContext, descriptor, preImportProperties);

            // Add a file to the project
            string itemPath = TestUtils.CreateTextFile(rootInputFolder, "code1.cs", "class myclassXXX{}");
            projectRoot.AddItem(TargetProperties.ItemType_Compile, itemPath);
            projectRoot.Save();

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger);

            // Assert
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);

            logger.AssertExpectedTargetOrdering(
                TargetConstants.CategoriseProjectTarget,
                TargetConstants.OverrideFxCopSettingsTarget,
                TargetConstants.FxCopTarget,
                TargetConstants.DefaultBuildTarget,
                TargetConstants.CalculateFilesToAnalyzeTarget,
                TargetConstants.WriteProjectDataTarget);

            // We expect the FxCop target to be executed...
            logger.AssertTargetExecuted(TargetConstants.FxCopTarget);
            // ... but we don't expect the FxCop *task* to have executed
            logger.AssertTaskNotExecuted(TargetConstants.FxCopTask);

            logger.AssertTargetNotExecuted(TargetConstants.SetFxCopResultsTarget);

            ProjectInfo projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectRoot.FullPath);
            ProjectInfoAssertions.AssertAnalysisResultDoesNotExists(projectInfo, AnalysisType.FxCop.ToString());
        }
        public void Roslyn_Settings_ValidSetup()
        {
            // Arrange
            BuildLogger logger = new BuildLogger();

            // Set the config directory so the targets know where to look for the analysis config file
            string confDir = TestUtils.CreateTestSpecificFolder(this.TestContext, "config");

            // Create a valid config file containing analyzer settings
            string[] expectedAssemblies      = new string[] { "c:\\data\\config.analyzer1.dll", "c:\\config2.dll" };
            string[] analyzerAdditionalFiles = new string[] { "c:\\config.1.txt", "c:\\config.2.txt" };

            AnalysisConfig config = new AnalysisConfig();

            AnalyzerSettings analyzerSettings = new AnalyzerSettings
            {
                Language              = "cs",
                RuleSetFilePath       = "d:\\my.ruleset",
                AnalyzerAssemblyPaths = expectedAssemblies.ToList(),
                AdditionalFilePaths   = analyzerAdditionalFiles.ToList()
            };

            config.AnalyzersSettings = new List <AnalyzerSettings>
            {
                analyzerSettings
            };

            string configFilePath = Path.Combine(confDir, FileConstants.ConfigFileName);

            config.Save(configFilePath);

            // Create the project
            WellKnownProjectProperties properties = new WellKnownProjectProperties
            {
                SonarQubeConfigPath         = confDir,
                ResolvedCodeAnalysisRuleset = "c:\\should.be.overridden.ruleset"
            };

            ProjectRootElement projectRoot = CreateValidProjectSetup(properties);

            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "should.be.removed.analyzer1.dll");
            projectRoot.AddItem(TargetProperties.AnalyzerItemType, "c:\\should.be.removed.analyzer2.dll");

            string[] notRemovedAdditionalFiles = new string[] { "should.not.be.removed.additional1.txt", "should.not.be.removed.additional2.txt" };

            foreach (var notRemovedAdditionalFile in notRemovedAdditionalFiles)
            {
                projectRoot.AddItem(TargetProperties.AdditionalFilesItemType, notRemovedAdditionalFile);
            }

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger, TargetConstants.OverrideRoslynAnalysisTarget);

            string projectSpecificConfFilePath = result.ProjectStateAfterBuild.GetPropertyValue(TargetProperties.ProjectConfFilePath);

            string[] expectedRoslynAdditionalFiles = new string[] { projectSpecificConfFilePath }
            .Concat(analyzerAdditionalFiles)
            .Concat(notRemovedAdditionalFiles)
            .ToArray();

            // Assert
            logger.AssertTargetExecuted(TargetConstants.OverrideRoslynAnalysisTarget);
            logger.AssertTargetExecuted(TargetConstants.SetRoslynAnalysisPropertiesTarget);
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.OverrideRoslynAnalysisTarget);

            // Check the error log and ruleset properties are set
            AssertErrorLogIsSetBySonarQubeTargets(result);
            AssertExpectedResolvedRuleset(result, "d:\\my.ruleset");
            AssertExpectedItemValuesExists(result, TargetProperties.AdditionalFilesItemType, expectedRoslynAdditionalFiles);
            AssertExpectedItemValuesExists(result, TargetProperties.AnalyzerItemType, expectedAssemblies);

            BuildAssertions.AssertWarningsAreNotTreatedAsErrorsNorIgnored(result);
        }
        public void E2E_FxCop_OutputFolderSet_SonarRulesetNotFound()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            // Set the output folder and config path
            // Don't create a ruleset file on disc
            string fxCopLogFile = Path.Combine(rootInputFolder, "FxCopResults.xml");
            WellKnownProjectProperties preImportProperties = new WellKnownProjectProperties();
            preImportProperties.SonarQubeTempPath = rootOutputFolder; // FIXME
            preImportProperties.SonarQubeOutputPath = rootOutputFolder;
            preImportProperties.RunCodeAnalysis = "true"; // our targets should override this value
            preImportProperties.CodeAnalysisLogFile = fxCopLogFile;
            preImportProperties.SonarQubeConfigPath = rootInputFolder;
            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, preImportProperties);

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger);

            // Assert
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);

            logger.AssertTargetExecuted(TargetConstants.OverrideFxCopSettingsTarget);  // output folder is set so this should be executed
            logger.AssertTargetNotExecuted(TargetConstants.SetFxCopResultsTarget);

            // We expect the core FxCop *target* to have been started, but it should then be skipped
            // executing the FxCop *task* because the condition on the target is false
            // -> the FxCop output file should not be produced
            AssertFxCopNotExecuted(logger);

            Assert.IsFalse(File.Exists(fxCopLogFile), "FxCop log file should not have been produced");

            ProjectInfo projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectRoot.FullPath);
            ProjectInfoAssertions.AssertAnalysisResultDoesNotExists(projectInfo, AnalysisType.FxCop.ToString());
        }
 private void AssertFxCopExecuted(BuildLogger logger)
 {
     logger.AssertTargetExecuted(TargetConstants.FxCopTarget);
     logger.AssertTaskExecuted(TargetConstants.FxCopTask);
 }
        public void E2E_FxCop_OutputFolderSet_SonarRulesetNotSpecified()
        {
            // Arrange
            string rootInputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Inputs");
            string rootOutputFolder = TestUtils.CreateTestSpecificFolder(this.TestContext, "Outputs");

            // Set the output folder but not the config folder
            string fxCopLogFile = Path.Combine(rootInputFolder, "FxCopResults.xml");
            WellKnownProjectProperties preImportProperties = new WellKnownProjectProperties();
            preImportProperties.SonarQubeTempPath = rootOutputFolder; // FIXME
            preImportProperties.SonarQubeOutputPath = rootOutputFolder;
            preImportProperties.SonarQubeConfigPath = rootInputFolder;
            preImportProperties.RunCodeAnalysis = "TRUE";
            preImportProperties.CodeAnalysisLogFile = fxCopLogFile;
            ProjectRootElement projectRoot = BuildUtilities.CreateValidProjectRoot(this.TestContext, rootInputFolder, preImportProperties);

            BuildLogger logger = new BuildLogger();

            // Act
            BuildResult result = BuildUtilities.BuildTargets(projectRoot, logger);

            // Assert
            BuildAssertions.AssertTargetSucceeded(result, TargetConstants.DefaultBuildTarget);

            logger.AssertTargetExecuted(TargetConstants.OverrideFxCopSettingsTarget); // output folder is set so this should be executed
            logger.AssertTargetNotExecuted(TargetConstants.SetFxCopResultsTarget);

            AssertFxCopNotExecuted(logger);
            Assert.IsFalse(File.Exists(fxCopLogFile), "FxCop log file should not have been produced");

            ProjectInfo projectInfo = ProjectInfoAssertions.AssertProjectInfoExists(rootOutputFolder, projectRoot.FullPath);
            ProjectInfoAssertions.AssertAnalysisResultDoesNotExists(projectInfo, AnalysisType.FxCop.ToString());
        }