public static AnalysisConfig GenerateFile(ProcessedArgs args, TeamBuildSettings settings, IDictionary<string, string> serverProperties, ILogger logger)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }
            if (serverProperties == null)
            {
                throw new ArgumentNullException("serverProperties");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            AnalysisConfig config = new AnalysisConfig();
            config.SonarProjectKey = args.ProjectKey;
            config.SonarProjectName = args.ProjectName;
            config.SonarProjectVersion = args.ProjectVersion;
            config.SonarQubeHostUrl = args.GetSetting(SonarProperties.HostUrl);

            config.SetBuildUri(settings.BuildUri);
            config.SetTfsUri(settings.TfsUri);
            config.SonarConfigDir = settings.SonarConfigDirectory;
            config.SonarOutputDir = settings.SonarOutputDirectory;
            config.SonarBinDir = settings.SonarBinDirectory;
            config.SonarRunnerWorkingDirectory = settings.SonarRunnerWorkingDirectory;

            // Add the server properties to the config
            config.ServerSettings = new AnalysisProperties();

            foreach (var property in serverProperties)
            {
                if (!IsSecuredServerProperty(property.Key))
                {
                    AddSetting(config.ServerSettings, property.Key, property.Value);
                }
            }

            // Add command line arguments
            config.LocalSettings = new AnalysisProperties();
            foreach (var property in args.LocalProperties.GetAllProperties())
            {
                AddSetting(config.LocalSettings, property.Id, property.Value);
            }

            // Set the pointer to the properties file
            if (args.PropertiesFileName != null)
            {
                config.SetSettingsFilePath(args.PropertiesFileName);
            }

            config.Save(settings.AnalysisConfigFilePath);

            return config;
        }
        /// <summary>
        /// Generates summary reports for LegacyTeamBuild and for Build Vnext
        /// </summary>
        public void GenerateReports(TeamBuildSettings settings, AnalysisConfig config, ProjectInfoAnalysisResult result, ILogger logger)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            this.settings = settings;
            this.config = config;
            this.result = result;
            this.logger = logger;

            this.GenerateReports();
        }
        public void GetAnalyzerSettings_ConfigExists_DataReturned()
        {
            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            GetAnalyzerSettings testSubject = new GetAnalyzerSettings();

            string[] expectedAnalyzers = new string[] { "c:\\analyzer1.DLL", "c:\\analyzer2.dll" };
            string[] expectedAdditionalFiles = new string[] { "c:\\add1.txt", "d:\\add2.txt" };

            // SONARMSBRU-216: non-assembly files should be filtered out
            List<string> filesInConfig = new List<string>(expectedAnalyzers);
            filesInConfig.Add("c:\\not_an_assembly.exe");
            filesInConfig.Add("c:\\not_an_assembly.zip");
            filesInConfig.Add("c:\\not_an_assembly.txt");
            filesInConfig.Add("c:\\not_an_assembly.dll.foo");
            filesInConfig.Add("c:\\not_an_assembly.winmd");

            AnalysisConfig config = new AnalysisConfig();
            config.AnalyzerSettings = new AnalyzerSettings();
            config.AnalyzerSettings.RuleSetFilePath = "f:\\yyy.ruleset";
            config.AnalyzerSettings.AnalyzerAssemblyPaths = filesInConfig;
            config.AnalyzerSettings.AdditionalFilePaths = expectedAdditionalFiles.ToList();
            string fullPath = Path.Combine(testDir, FileConstants.ConfigFileName);
            config.Save(fullPath);

            testSubject.AnalysisConfigDir = testDir;

            // Act
            ExecuteAndCheckSuccess(testSubject);

            // Assert
            Assert.AreEqual("f:\\yyy.ruleset", testSubject.RuleSetFilePath);
            CollectionAssert.AreEquivalent(expectedAnalyzers, testSubject.AnalyzerFilePaths);
            CollectionAssert.AreEquivalent(expectedAdditionalFiles, testSubject.AdditionalFiles);
        }
        public void SummaryReport_AllTypesOfProjects()
        {
            // Arrange
            string hostUrl = "http://mySonarQube:9000";
            ProjectInfoAnalysisResult result = new ProjectInfoAnalysisResult() { RanToCompletion = true };
            AnalysisConfig config = new AnalysisConfig() { SonarProjectKey = "", SonarQubeHostUrl = hostUrl };

            AddProjectInfoToResult(result, ProjectInfoValidity.DuplicateGuid, count: 3);
            AddProjectInfoToResult(result, ProjectInfoValidity.ExcludeFlagSet, type: ProjectType.Product, count: 4);
            AddProjectInfoToResult(result, ProjectInfoValidity.ExcludeFlagSet, type: ProjectType.Test , count: 1);
            AddProjectInfoToResult(result, ProjectInfoValidity.InvalidGuid, type: ProjectType.Product, count: 7);
            AddProjectInfoToResult(result, ProjectInfoValidity.InvalidGuid, type: ProjectType.Test , count: 8);
            AddProjectInfoToResult(result, ProjectInfoValidity.NoFilesToAnalyze, count: 11);
            AddProjectInfoToResult(result, ProjectInfoValidity.Valid, type: ProjectType.Product, count: 13);
            AddProjectInfoToResult(result, ProjectInfoValidity.Valid, type: ProjectType.Test, count: 17);

            // Act
            var summaryReportData = SummaryReportBuilder.CreateSummaryData(config, result);

            // Assert
            VerifySummaryReportData(summaryReportData, result, hostUrl, config);
            VerifySummaryProjectCounts(
                summaryReportData,
                expectedExcludedProjects: 5, // ExcludeFlagSet
                expectedInvalidProjects: 18, // InvalidGuid + DuplicateGuid
                expectedSkippedProjects: 11, // No files to analyze
                expectedProductProjects: 13,
                expectedTestProjects: 17);
        }
        public void GetAnalyzerSettings_ConfigExists_DataReturned()
        {
            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            GetAnalyzerSettings testSubject = new GetAnalyzerSettings();

            string[] expectedAnalyzers = new string[] { "c:\\analyzer1.dll", "c:\\analyzer2.dll" };
            string[] expectedAdditionalFiles = new string[] { "c:\\add1.txt", "d:\\add2.txt" };

            AnalysisConfig config = new AnalysisConfig();
            config.AnalyzerSettings = new AnalyzerSettings();
            config.AnalyzerSettings.RuleSetFilePath = "f:\\yyy.ruleset";
            config.AnalyzerSettings.AnalyzerAssemblyPaths = expectedAnalyzers.ToList();
            config.AnalyzerSettings.AdditionalFilePaths = expectedAdditionalFiles.ToList();
            string fullPath = Path.Combine(testDir, FileConstants.ConfigFileName);
            config.Save(fullPath);

            testSubject.AnalysisConfigDir = testDir;

            // Act
            ExecuteAndCheckSuccess(testSubject);

            // Assert
            Assert.AreEqual("f:\\yyy.ruleset", testSubject.RuleSetFilePath);
            CollectionAssert.AreEquivalent(expectedAnalyzers, testSubject.AnalyzerFilePaths);
            CollectionAssert.AreEquivalent(expectedAdditionalFiles, testSubject.AdditionalFiles);
        }
        public ProjectInfoAnalysisResult Execute(AnalysisConfig config, IEnumerable<string> userCmdLineArguments, ILogger logger)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            if (userCmdLineArguments == null)
            {
                throw new ArgumentNullException("userCmdLineArguments");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            ProjectInfoAnalysisResult result = PropertiesFileGenerator.GenerateFile(config, logger);
            Debug.Assert(result != null, "Not expecting the file generator to return null");
            result.RanToCompletion = false;

            SonarProjectPropertiesValidator.Validate(
                config.SonarRunnerWorkingDirectory,
                result.Projects,
                onValid: () =>
                {
                    InternalExecute(config, userCmdLineArguments, logger, result);
                },
                onInvalid: (invalidFolders) =>
                {
                    // LOG error message
                    logger.LogError(Resources.ERR_ConflictingSonarProjectProperties, string.Join(", ", invalidFolders));
                });

            return result;
        }
 private ProjectInfoReportBuilder(AnalysisConfig config, ProjectInfoAnalysisResult result, ILogger logger)
 {
     this.config = config;
     this.analysisResult = result;
     this.logger = logger;
     this.sb = new StringBuilder();
 }
        /* for test purposes */
        public static SummaryReportData CreateSummaryData(
            AnalysisConfig config,
            ProjectInfoAnalysisResult result)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            SummaryReportData summaryData = new SummaryReportData();

            summaryData.SkippedProjects = GetProjectsByStatus(result, ProjectInfoValidity.NoFilesToAnalyze).Count();
            summaryData.InvalidProjects = GetProjectsByStatus(result, ProjectInfoValidity.InvalidGuid).Count();
            summaryData.InvalidProjects += GetProjectsByStatus(result, ProjectInfoValidity.DuplicateGuid).Count();

            summaryData.ExcludedProjects = GetProjectsByStatus(result, ProjectInfoValidity.ExcludeFlagSet).Count();
            IEnumerable<ProjectInfo> validProjects = GetProjectsByStatus(result, ProjectInfoValidity.Valid);
            summaryData.ProductProjects = validProjects.Count(p => p.ProjectType == ProjectType.Product);
            summaryData.TestProjects = validProjects.Count(p => p.ProjectType == ProjectType.Test);

            summaryData.Succeeded = result.RanToCompletion;

            summaryData.DashboardUrl = GetSonarDashboadUrl(config);
            summaryData.ProjectDescription = string.Format(System.Globalization.CultureInfo.CurrentCulture,
                Resources.Report_SonarQubeProjectDescription, config.SonarProjectName, config.SonarProjectKey, config.SonarProjectVersion);
            return summaryData;
        }
        /* for test purposes */
        public static bool ExecuteJavaRunner(AnalysisConfig config, IEnumerable<string> userCmdLineArguments, ILogger logger, string exeFileName, string propertiesFileName)
        {
            Debug.Assert(File.Exists(exeFileName), "The specified exe file does not exist: " + exeFileName);
            Debug.Assert(File.Exists(propertiesFileName), "The specified properties file does not exist: " + propertiesFileName);

            IgnoreSonarRunnerHome(logger);

            IEnumerable<string> allCmdLineArgs = GetAllCmdLineArgs(propertiesFileName, userCmdLineArguments, config);

            IDictionary<string, string> envVarsDictionary = GetAdditionalEnvVariables(logger);
            Debug.Assert(envVarsDictionary != null);

            logger.LogInfo(Resources.MSG_CallingSonarRunner);
            ProcessRunnerArguments runnerArgs = new ProcessRunnerArguments(exeFileName, logger)
            {
                CmdLineArgs = allCmdLineArgs,
                WorkingDirectory = Path.GetDirectoryName(exeFileName),
                EnvironmentVariables = envVarsDictionary
            };
            ProcessRunner runner = new ProcessRunner();

            bool success = runner.Execute(runnerArgs);

            success = success && !runner.ErrorsLogged;

            if (success)
            {
                logger.LogInfo(Resources.MSG_SonarRunnerCompleted);
            }
            else
            {
                logger.LogError(Resources.ERR_SonarRunnerExecutionFailed);
            }
            return success;
        }
        public ProjectInfoAnalysisResult Execute(AnalysisConfig config, IEnumerable<string> userCmdLineArguments, ILogger logger)
        {
            Assert.IsFalse(this.methodCalled, "Runner should only be called once");
            this.methodCalled = true;
            this.SuppliedCommandLineArgs = userCmdLineArguments;

            return this.ValueToReturn;
        }
        public PropertiesWriter(AnalysisConfig config)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }

            this.config = config;
            this.sb = new StringBuilder();
            this.projects = new List<ProjectInfo>();
        }
        public /* for test */ static ProjectInfoAnalysisResult GenerateFile(AnalysisConfig config, ILogger logger, IRoslynV1SarifFixer fixer)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            string fileName = Path.Combine(config.SonarOutputDir, ProjectPropertiesFileName);
            logger.LogDebug(Resources.MSG_GeneratingProjectProperties, fileName);

            IEnumerable<ProjectInfo> projects = ProjectLoader.LoadFrom(config.SonarOutputDir);
            if (projects == null || !projects.Any())
            {
                logger.LogError(Resources.ERR_NoProjectInfoFilesFound);
                return new ProjectInfoAnalysisResult();
            }

            FixSarifReport(logger, projects, fixer);

            PropertiesWriter writer = new PropertiesWriter(config);

            ProjectInfoAnalysisResult result = ProcessProjectInfoFiles(projects, writer, logger);

            IEnumerable<ProjectInfo> validProjects = result.GetProjectsByStatus(ProjectInfoValidity.Valid);

            if (validProjects.Any())
            {
                // Handle global settings
                AnalysisProperties properties = GetAnalysisPropertiesToWrite(config, logger);
                writer.WriteGlobalSettings(properties);

                string contents = writer.Flush();

                result.FullPropertiesFilePath = fileName;
                File.WriteAllText(result.FullPropertiesFilePath, contents, Encoding.ASCII);
            }
            else
            {
                // if the user tries to build multiple configurations at once there will be duplicate projects
                if (result.GetProjectsByStatus(ProjectInfoValidity.DuplicateGuid).Any())
                {
                    logger.LogError(Resources.ERR_NoValidButDuplicateProjects);
                }
                else
                {
                    logger.LogError(Resources.ERR_NoValidProjectInfoFiles);
                }
            }
            return result;
        }
        public bool Initialise(AnalysisConfig config, TeamBuildSettings settings, ILogger logger)
        {
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            this.TryCreateCoverageReportProcessor(settings);

            this.initialisedSuccesfully = (this.processor != null && this.processor.Initialise(config, settings, logger));
            return this.initialisedSuccesfully;
        }
        public void SonarRunner_StandardAdditionalArgumentsPassed()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            string exePath = CreateDummarySonarRunnerBatchFile();
            string propertiesFilePath = CreateDummySonarRunnerPropertiesFile();
            AnalysisConfig config = new AnalysisConfig() { SonarRunnerWorkingDirectory = this.TestContext.DeploymentDirectory };

            // Act
            bool success = SonarRunnerWrapper.ExecuteJavaRunner(config, Enumerable.Empty<string>(), logger, exePath, propertiesFilePath);

            // Assert
            VerifyProcessRunOutcome(logger, this.TestContext.DeploymentDirectory, success, true);
        }
        private string TryGetRegularExpression(AnalysisConfig config)
        {
            Debug.Assert(config != null, "Not expecting the supplied config to be null");

            string regEx;
            config.GetAnalysisSettings(true).TryGetValue(TestRegExSettingId, out regEx);
            
            if (!string.IsNullOrWhiteSpace(regEx))
            {
                this.Log.LogMessage(MessageImportance.Low, Resources.IsTest_UsingRegExFromConfig, regEx);
            }

            return regEx;
        }
        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);
        }
        /// <summary>
        /// Attempts to load the config file, suppressing any IO errors that occur.
        /// This method is expected to be called inside a "retry"
        /// </summary>
        private static bool DoLoadConfig(string filePath, ILogger logger, out AnalysisConfig config)
        {
            Debug.Assert(File.Exists(filePath), "Expecting the config file to exist: " + filePath);
            config = null;

            try
            {
                config = AnalysisConfig.Load(filePath);
            }
            catch (IOException e)
            {
                // Log this as a message for info. We'll log an error if all of the re-tries failed
                logger.LogDebug(Resources.Shared_ErrorReadingConfigFile, e.Message);
                return false;
            }
            return true;
        }
        public bool Execute(string[] args, AnalysisConfig config, TeamBuildSettings settings, ILogger logger)
        {
            if (args == null)
            {
                throw new ArgumentNullException("args");
            }
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            IAnalysisPropertyProvider provider;
            if (!ArgumentProcessor.TryProcessArgs(args, logger, out provider))
            {
                return false;
            }

            logger.Verbosity = VerbosityCalculator.ComputeVerbosity(config.GetAnalysisSettings(true), logger);
            LogStartupSettings(config, settings, logger);

            if (!CheckEnvironmentConsistency(config, settings, logger))
            {
                return false;
            }

            // if initialisation fails a warning will have been logged at the source of the failure
            bool initialised = this.codeCoverageProcessor.Initialise(config, settings, logger);

            if (initialised && !this.codeCoverageProcessor.ProcessCoverageReports())
            {
                //  if processing fails, stop the workflow
                return false;
            }

            ProjectInfoAnalysisResult result = InvokeSonarRunner(provider, config, logger);
            this.reportBuilder.GenerateReports(settings, config, result, logger);
            return result.RanToCompletion;
        }
        public static void WriteSummaryReport(AnalysisConfig config, ProjectInfoAnalysisResult result, ILogger logger)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            ProjectInfoReportBuilder builder = new ProjectInfoReportBuilder(config, result, logger);
            builder.Generate();
        }
        public void GetAnalyzerSettings_ConfigExistsButNoAnalyzerSettings_NoError()
        {
            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            GetAnalyzerSettings testSubject = new GetAnalyzerSettings();

            AnalysisConfig config = new AnalysisConfig();
            string fullPath = Path.Combine(testDir, FileConstants.ConfigFileName);
            config.Save(fullPath);

            testSubject.AnalysisConfigDir = testDir;

            // Act
            ExecuteAndCheckSuccess(testSubject);

            // Assert
            CheckNoAnalyzerSettings(testSubject);
        }
        public void SonarRunnerHome_MessageLoggedIfAlreadySet()
        {
            using (EnvironmentVariableScope scope = new EnvironmentVariableScope())
            {
                scope.SetVariable(SonarRunnerWrapper.SonarRunnerHomeVariableName, "some_path");

                // Arrange
                TestLogger testLogger = new TestLogger();
                string exePath = CreateDummarySonarRunnerBatchFile();
                string propertiesFilePath = CreateDummySonarRunnerPropertiesFile();
                AnalysisConfig config = new AnalysisConfig() { SonarRunnerWorkingDirectory = this.TestContext.DeploymentDirectory };

                // Act
                bool success = SonarRunnerWrapper.ExecuteJavaRunner(config, Enumerable.Empty<string>(), testLogger, exePath, propertiesFilePath);

                // Assert
                VerifySuccessfullRun(testLogger, success , this.TestContext.DeploymentDirectory);
            }
        }
        public void SonarRunnerHome_NoMessageIfNotAlreadySet()
        {
            // Arrange
            TestLogger testLogger = new TestLogger();
            string exePath = CreateDummarySonarRunnerBatchFile();
            string propertiesFilePath = CreateDummySonarRunnerPropertiesFile();

            using (EnvironmentVariableScope scope = new EnvironmentVariableScope())
            {
                scope.SetVariable(SonarRunnerWrapper.SonarRunnerHomeVariableName, null);
                AnalysisConfig config = new AnalysisConfig() { SonarRunnerWorkingDirectory = this.TestContext.DeploymentDirectory };

                // Act
                bool success = SonarRunnerWrapper.ExecuteJavaRunner(config, Enumerable.Empty<string>(), testLogger, exePath, propertiesFilePath);

                // Assert
                VerifyProcessRunOutcome(testLogger, this.TestContext.DeploymentDirectory, success, true);
                testLogger.AssertMessageNotLogged(SonarRunner.Shim.Resources.MSG_SonarRunnerHomeIsSet);
            }
        }
        public void SummaryReport_NoProjects()
        {
            // Arrange
            string hostUrl = "http://mySonarQube:9000";
            ProjectInfoAnalysisResult result = new ProjectInfoAnalysisResult() { RanToCompletion = false };
            AnalysisConfig config = new AnalysisConfig() { SonarProjectKey = "Foo" , SonarQubeHostUrl = hostUrl };

            // Act
            var summaryReportData = SummaryReportBuilder.CreateSummaryData(config, result);

            // Assert
            VerifySummaryReportData(summaryReportData, result, hostUrl, config);
            VerifySummaryProjectCounts(
                summaryReportData,
                expectedExcludedProjects: 0,
                expectedInvalidProjects: 0,
                expectedSkippedProjects: 0,
                expectedProductProjects: 0,
                expectedTestProjects: 0);
        }
        /* for test purposes */
        public static bool ExecuteJavaRunner(AnalysisConfig config, IEnumerable<string> userCmdLineArguments, ILogger logger, string exeFileName, string propertiesFileName)
        {
            Debug.Assert(File.Exists(exeFileName), "The specified exe file does not exist: " + exeFileName);
            Debug.Assert(File.Exists(propertiesFileName), "The specified properties file does not exist: " + propertiesFileName);

            IgnoreSonarScannerHome(logger);

            IEnumerable<string> allCmdLineArgs = GetAllCmdLineArgs(propertiesFileName, userCmdLineArguments, config);

            IDictionary<string, string> envVarsDictionary = GetAdditionalEnvVariables(logger);
            Debug.Assert(envVarsDictionary != null);

            logger.LogInfo(Resources.MSG_SonarScannerCalling);

            Debug.Assert(!String.IsNullOrWhiteSpace(config.SonarRunnerWorkingDirectory), "The working dir should have been set in the analysis config");
            Debug.Assert(Directory.Exists(config.SonarRunnerWorkingDirectory), "The working dir should exist");

            ProcessRunnerArguments runnerArgs = new ProcessRunnerArguments(exeFileName, logger)
            {
                CmdLineArgs = allCmdLineArgs,
                WorkingDirectory = config.SonarRunnerWorkingDirectory,
                EnvironmentVariables = envVarsDictionary
            };

            ProcessRunner runner = new ProcessRunner();

            // SONARMSBRU-202 Note that the Sonar Scanner may write warnings to stderr so
            // we should only rely on the exit code when deciding if it ran successfully
            bool success = runner.Execute(runnerArgs);

            if (success)
            {
                logger.LogInfo(Resources.MSG_SonarScannerCompleted);
            }
            else
            {
                logger.LogError(Resources.ERR_SonarScannerExecutionFailed);
            }
            return success;
        }
        public void FileGen_NoProjectInfoFiles()
        {
            // Properties file should not be generated if there are no project info files.

            // Arrange - two sub-directories, neither containing a ProjectInfo.xml
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            string subDir1 = TestUtils.EnsureTestSpecificFolder(this.TestContext, "dir1");
            string subDir2 = TestUtils.EnsureTestSpecificFolder(this.TestContext, "dir2");

            CreateEmptyFile(subDir1, "file1.txt");
            CreateEmptyFile(subDir2, "file2.txt");

            TestLogger logger = new TestLogger();
            AnalysisConfig config = new AnalysisConfig() { SonarOutputDir = testDir };

            // Act
            ProjectInfoAnalysisResult result = PropertiesFileGenerator.GenerateFile(config, logger);

            // Assert
            AssertFailedToCreatePropertiesFiles(result, logger);
            AssertExpectedProjectCount(0, result);
        }
        public bool Initialise(AnalysisConfig config, TeamBuildSettings settings, ILogger logger)
        {
            if (config == null)
            {
                throw new ArgumentNullException("config");
            }
            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }
            if (logger == null)
            {
                throw new ArgumentNullException("logger");
            }

            this.config = config;
            this.settings = settings;
            this.logger = logger;

            this.succesfullyInitialised =  this.converter.Initialize(logger);
            return succesfullyInitialised;
        }
        protected override bool TryGetBinaryReportFile(AnalysisConfig config, TeamBuildSettings settings, ILogger logger, out string binaryFilePath)
        {
            IEnumerable<string> urls = this.urlProvider.GetCodeCoverageReportUrls(config.GetTfsUri(), config.GetBuildUri(), logger);
            Debug.Assert(urls != null, "Not expecting the returned list of urls to be null");

            bool continueProcessing = true;
            binaryFilePath = null;

            switch (urls.Count())
            {
                case 0:
                    logger.LogInfo(Resources.PROC_DIAG_NoCodeCoverageReportsFound);
                    break;

                case 1:
                    string url = urls.First();

                    string targetFileName = Path.Combine(config.SonarOutputDir, DownloadFileName);
                    bool result = this.downloader.DownloadReport(config.GetTfsUri(), url, targetFileName, logger);

                    if (result)
                    {
                        binaryFilePath = targetFileName;
                    }
                    else
                    {
                        continueProcessing = false;
                        logger.LogError(Resources.PROC_ERROR_FailedToDownloadReport);
                    }
                    break;

                default: // More than one
                    continueProcessing = false;
                    logger.LogError(Resources.PROC_ERROR_MultipleCodeCoverageReportsFound);
                    break;
            }

            return continueProcessing;
        }
        public void SummaryReport_WithBranch()
        {
            // Arrange
            string hostUrl = "http://mySonarQube:9000";
            ProjectInfoAnalysisResult result = new ProjectInfoAnalysisResult { RanToCompletion = false };
            AnalysisConfig config = new AnalysisConfig() { SonarProjectKey = "Foo", SonarQubeHostUrl = hostUrl };
            config.LocalSettings = new AnalysisProperties();
            config.LocalSettings.Add(new Property() { Id = SonarProperties.Branch, Value = "master" });
            AddProjectInfoToResult(result, ProjectInfoValidity.Valid, type: ProjectType.Product, count: 4);

            // Act
            var summaryReportData = SummaryReportBuilder.CreateSummaryData(config, result);

            // Assert
            VerifySummaryReportData(summaryReportData, result, hostUrl, config);
            VerifySummaryProjectCounts(
                summaryReportData,
                expectedExcludedProjects: 0,
                expectedInvalidProjects: 0,
                expectedSkippedProjects: 0,
                expectedProductProjects: 4,
                expectedTestProjects: 0);
        }
        /// <summary>
        /// Attempts to load the config file, suppressing any IO errors that occur.
        /// This method is expected to be called inside a "retry"
        /// </summary>
        private bool DoLoadConfig(string filePath, out AnalysisConfig config)
        {
            Debug.Assert(File.Exists(filePath), "Expecting the config file to exist: " + filePath);
            config = null;

            try
            {
                config = AnalysisConfig.Load(filePath);
            }
            catch (IOException e)
            {
                // Log this as a message for info. We'll log an error if all of the re-tries failed
                this.Log.LogMessage(MessageImportance.Low, Resources.IsTest_ErrorReadingConfigFile, e.Message);
                return false;
            }
            return true;
        }
        private static void AssertExpectedServerSetting(string key, string expectedValue, AnalysisConfig actualConfig)
        {
            Property actualProperty;
            bool found = Property.TryGetProperty(key, actualConfig.ServerSettings, out actualProperty);

            Assert.IsTrue(found, "Failed to find the expected server setting: {0}", key);
            Assert.AreEqual(expectedValue, actualProperty.Value, "Unexpected property value. Key: {0}", key);
        }
Example #31
0
 /// <summary>
 /// Sets the value of the additional setting. The setting will be added if it does not already exist.
 /// </summary>
 public static void SetConfigValue(this AnalysisConfig config, string settingId, string value)
 {
     SetValue(config, settingId, value);
 }