public void RoslynConfig_BranchMissingRuleset()
        {
            // This test is a regression scenario for SONARMSBRU-187:
            // We do not expect the project profile to be returned if we ask for a branch-specific profile

            // Arrange
            string rootDir = CreateTestFolders();
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings = CreateSettings(rootDir);

            WellKnownProfile testProfile = CreateValidCSharpProfile();
            MockSonarQubeServer mockServer = CreateServer("valid.project", null, "valid.profile", testProfile);

            MockAnalyzerInstaller mockInstaller = new MockAnalyzerInstaller();
            mockInstaller.AssemblyPathsToReturn = new HashSet<string>(new string[] { "c:\\assembly1.dll", "d:\\foo\\assembly2.dll" });

            RoslynAnalyzerProvider testSubject = new RoslynAnalyzerProvider(mockInstaller, logger);

            // Act
            AnalyzerSettings actualSettings = testSubject.SetupAnalyzers(mockServer, settings, "valid.project", "missingBranch");

            // Assert
            AssertAnalyzerSetupNotPerformed(actualSettings, rootDir);

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
        }
        public void ReportProcessor_CannotConvertFiles()
        {
            // Arrange
            MockReportUrlProvider urlProvider = new MockReportUrlProvider() { UrlsToReturn = new string[] { ValidUrl1 } };
            MockReportDownloader downloader = new MockReportDownloader();
            MockReportConverter converter = new MockReportConverter() { CanConvert = false };
            AnalysisConfig context = this.CreateValidContext();
            TeamBuildSettings settings = this.CreateValidSettings();
            TestLogger logger = new TestLogger();

            TfsLegacyCoverageReportProcessor processor = new TfsLegacyCoverageReportProcessor(urlProvider, downloader, converter);

            // Act
            bool initResult = processor.Initialise(context, settings, logger);

            // Assert
            Assert.IsFalse(initResult, "Expecting false: processor should not have been initialised successfully");

            urlProvider.AssertGetUrlsNotCalled();
            downloader.AssertDownloadNotCalled();
            converter.AssertConvertNotCalled();

            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        public void BuildWrapper_OldCppPluginInstalled_FilesDownloaded()
        {
            // If an older version of the C++ plugin is installed then the embedded resource
            // won't exist. In that case we expect a warning message telling the user to upgrade.

            // Arrange
            string rootDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            TestLogger logger = new TestLogger();

            MockSonarQubeServer mockServer = new MockSonarQubeServer();
            mockServer.Data.InstalledPlugins.Add("cpp"); // plugin exists but no zip file

            BuildWrapperInstaller testSubject = new BuildWrapperInstaller(logger);

            // Act
            AnalysisProperties properties = testSubject.InstallBuildWrapper(mockServer, rootDir, "c:\\output\\");

            // Assert
            logger.AssertSingleWarningExists(SonarQube.TeamBuild.PreProcessor.Resources.BW_CppPluginUpgradeRequired);
            logger.AssertErrorsLogged(0);

            AssertNoFilesExist(rootDir);

            Assert.IsNotNull(properties, "Returned properties should not be null");
            Assert.AreEqual(0, properties.Count, "Not expecting any properties to be set");
        }
        public void Parser_UnrecognizedArguments()
        {
            CommandLineParser parser;
            IEnumerable<ArgumentInstance> instances;
            TestLogger logger;

            string[] args = new string[] { "/a:XXX", "/unrecognized" };

            ArgumentDescriptor d1 = new ArgumentDescriptor("id1", new string[] { "/a:" }, true, "desc1", false);

            // 1. Don't allow unrecognized
            parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, false);

            logger = CheckProcessingFails(parser, args);

            logger.AssertSingleErrorExists("/unrecognized");
            logger.AssertErrorsLogged(1);

            // 2. Allow unrecognized
            parser = new CommandLineParser(new ArgumentDescriptor[] { d1 }, true);
            logger = new TestLogger();
            instances = CheckProcessingSucceeds(parser, logger, args);

            AssertExpectedValue("id1", "XXX", instances);
            AssertExpectedInstancesCount(1, instances);
            logger.AssertMessagesLogged(0); // expecting unrecognized arguments to be ignored silently
        }
        [WorkItem(72)] // Regression test for bug #72: CodeCoverage conversion - conversion errors should be detected and reported
        public void Conv_OutputIsCaptured()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            string outputFilePath = Path.Combine(testDir, "output.txt");

            string inputFilePath = Path.Combine(testDir, "input.txt");
            File.WriteAllText(inputFilePath, "dummy input file");
            
            string converterFilePath = Path.Combine(testDir, "converter.bat");
            File.WriteAllText(converterFilePath,
@"
echo Normal output...
echo Error output...>&2
echo Create a new file using the output parameter
echo foo > """ + outputFilePath + @"""");

            // Act
            bool success = CoverageReportConverter.ConvertBinaryToXml(converterFilePath, inputFilePath, outputFilePath, logger);
            
            // Assert
            Assert.IsTrue(success, "Expecting the process to succeed");

            Assert.IsTrue(File.Exists(outputFilePath), "Expecting the output file to exist");
            this.TestContext.AddResultFile(outputFilePath);

            logger.AssertMessageLogged("Normal output...");
            logger.AssertErrorLogged("Error output...");
        }
        public void AnalysisConfGen_AnalysisConfigDoesNotContainSensitiveData()
        {
            // Arrange
            string analysisDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            TestLogger logger = new TestLogger();

            ListPropertiesProvider cmdLineArgs = new ListPropertiesProvider();
            // Public args - should be written to the config file
            cmdLineArgs.AddProperty("sonar.host.url", "http://host");
            cmdLineArgs.AddProperty("public.key", "public value");

            // Sensitive values - should not be written to the config file
            cmdLineArgs.AddProperty(SonarProperties.DbPassword, "secret db password");
            cmdLineArgs.AddProperty(SonarProperties.DbUserName, "secret db user");

            // Create a settings file with public and sensitive data
            AnalysisProperties fileSettings = new AnalysisProperties();
            fileSettings.Add(new Property() { Id = "file.public.key", Value = "file public value" });
            fileSettings.Add(new Property() {Id = SonarProperties.DbUserName, Value = "secret db user"});
            fileSettings.Add(new Property() { Id = SonarProperties.DbPassword, Value = "secret db password"});
            string fileSettingsPath = Path.Combine(analysisDir, "fileSettings.txt");
            fileSettings.Save(fileSettingsPath);
            FilePropertyProvider fileProvider = FilePropertyProvider.Load(fileSettingsPath);

            ProcessedArgs args = new ProcessedArgs("key", "name", "1.0", false, cmdLineArgs, fileProvider);

            IDictionary<string, string> serverProperties = new Dictionary<string, string>();
            // Public server settings
            serverProperties.Add("server.key.1", "server value 1");
            // Sensitive server settings
            serverProperties.Add(SonarProperties.SonarUserName, "secret user");
            serverProperties.Add(SonarProperties.SonarPassword, "secret pwd");

            TeamBuildSettings settings = TeamBuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir);
            Directory.CreateDirectory(settings.SonarConfigDirectory); // config directory needs to exist

            // Act
            AnalysisConfig config = AnalysisConfigGenerator.GenerateFile(args, settings, serverProperties, logger);

            // Assert
            AssertConfigFileExists(config);
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);

            // Check the config

            // "Public" arguments should be in the file
            Assert.AreEqual("key", config.SonarProjectKey, "Unexpected project key");
            Assert.AreEqual("name", config.SonarProjectName, "Unexpected project name");
            Assert.AreEqual("1.0", config.SonarProjectVersion, "Unexpected project version");

            AssertExpectedLocalSetting(SonarProperties.HostUrl, "http://host", config);
            AssertExpectedServerSetting("server.key.1", "server value 1", config);

            AssertFileDoesNotContainText(config.FileName, "file.public.key"); // file settings values should not be in the config

            // SONARMSBRU-136: TODO - uncomment the following code:
            AssertFileDoesNotContainText(config.FileName, "secret"); // sensitive data should not be in config
        }
        public void SonarRunner_CmdLineArgsOrdering()
        {
            // Check that user arguments are passed through to the wrapper and that they appear first

            // Arrange
            TestLogger logger = new TestLogger();

            string exePath = CreateDummarySonarRunnerBatchFile();
            string propertiesFilePath = CreateDummySonarRunnerPropertiesFile();

            string[] userArgs = new string[] { "-Dsonar.login=me", "-Dsonar.password=my.pwd" };

            // Act
            bool success = SonarRunnerWrapper.ExecuteJavaRunner(
                new AnalysisConfig() { SonarRunnerWorkingDirectory = this.TestContext.DeploymentDirectory },
                userArgs,
                logger,
                exePath,
                propertiesFilePath);

            // Assert
            VerifyProcessRunOutcome(logger, this.TestContext.DeploymentDirectory, success, true);

            string actualCmdLineArgs = CheckStandardArgsPassed(logger, propertiesFilePath);

            int loginIndex = CheckArgExists("-Dsonar.login=me", actualCmdLineArgs);
            int pwdIndex = CheckArgExists("-Dsonar.password=my.pwd", actualCmdLineArgs);

            int standardArgsIndex = CheckArgExists(SonarRunnerWrapper.StandardAdditionalRunnerArguments, actualCmdLineArgs);
            int propertiesFileIndex = CheckArgExists(SonarRunnerWrapper.ProjectSettingsFileArgName, actualCmdLineArgs);

            Assert.IsTrue(loginIndex < standardArgsIndex && loginIndex < propertiesFileIndex, "User arguments should appear first");
            Assert.IsTrue(pwdIndex < standardArgsIndex && pwdIndex < propertiesFileIndex, "User arguments should appear first");
        }
        public void ProcRunner_FailsOnTimeout()
        {
            // Arrange
            string exeName = TestUtils.WriteBatchFileForTest(TestContext,
@"TIMEOUT 2
@echo Hello world
");

            TestLogger logger = new TestLogger();
            ProcessRunnerArguments args = new ProcessRunnerArguments(exeName, logger)
            {
                TimeoutInMilliseconds = 100
            };
            ProcessRunner runner = new ProcessRunner();

            // Act
            bool success = runner.Execute(args);

            // Assert
            Assert.IsFalse(success, "Expecting the process to have failed");
            Assert.AreEqual(ProcessRunner.ErrorCode, runner.ExitCode, "Unexpected exit code");
            logger.AssertMessageNotLogged("Hello world");

            // Give the spawned process a chance to terminate.
            // This isn't essential (and having a Sleep in the test isn't ideal), but it stops
            // the test framework outputting this warning which appears in the TeamBuild summary:
            // "System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain. This can happen 
            // if the test(s) started a thread but did not stop it. Make sure that all the threads started by 
            // the test(s) are stopped before completion."
            System.Threading.Thread.Sleep(1100);
        }
        public void FileGen_DuplicateProjectIds()
        {
            // ProjectInfo files with duplicate ids should be ignored

            // Arrange - three files, all with the same Guid, one of which is excluded
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            Guid duplicateGuid = Guid.NewGuid();
            CreateProjectInfoInSubDir(testDir, "duplicate1", duplicateGuid, ProjectType.Product, false, "c:\\abc\\duplicateProject1.proj"); // not excluded
            CreateProjectInfoInSubDir(testDir, "duplicate2", duplicateGuid, ProjectType.Test, false, "S:\\duplicateProject2.proj"); // not excluded
            CreateProjectInfoInSubDir(testDir, "excluded", duplicateGuid, ProjectType.Product, true, null); // excluded

            TestLogger logger = new TestLogger();
            AnalysisConfig config = CreateValidConfig(testDir);

            // Act
            ProjectInfoAnalysisResult result = null;
            using (new AssertIgnoreScope()) // expecting the properties writer to assert
            {
                result = PropertiesFileGenerator.GenerateFile(config, logger);
            }

            // Assert
            AssertExpectedStatus("duplicate1", ProjectInfoValidity.DuplicateGuid, result);
            AssertExpectedStatus("duplicate2", ProjectInfoValidity.DuplicateGuid, result);
            AssertExpectedStatus("excluded", ProjectInfoValidity.ExcludeFlagSet, result); // Expecting excluded rather than duplicate
            AssertExpectedProjectCount(3, result);

            // No valid project info files -> file not generated
            AssertFailedToCreatePropertiesFiles(result, logger);
            logger.AssertWarningsLogged(2); // should be a warning for each project with a duplicate id

            logger.AssertSingleWarningExists(duplicateGuid.ToString(), "c:\\abc\\duplicateProject1.proj");
            logger.AssertSingleWarningExists(duplicateGuid.ToString(), "S:\\duplicateProject2.proj");
        }
        public void ReportProcessor_NoUrlsFound()
        {
            // Arrange
            MockReportUrlProvider urlProvider = new MockReportUrlProvider() { UrlsToReturn = new string[] { } };
            MockReportDownloader downloader = new MockReportDownloader();
            MockReportConverter converter = new MockReportConverter() { CanConvert = true };
            AnalysisConfig context = this.CreateValidContext();
            TeamBuildSettings settings = this.CreateValidSettings();
            TestLogger logger = new TestLogger();

            TfsLegacyCoverageReportProcessor processor = new TfsLegacyCoverageReportProcessor(urlProvider, downloader, converter);

            // Act
            bool initResult = processor.Initialise(context, settings, logger);
            Assert.IsTrue(initResult, "Expecting true: processor should have been initialised successfully");
            bool result = processor.ProcessCoverageReports();

            // Assert
            urlProvider.AssertGetUrlsCalled();
            downloader.AssertDownloadNotCalled(); // no urls returned, so should go any further
            converter.AssertConvertNotCalled();
            Assert.IsTrue(result, "Expecting true: no coverage reports is a valid scenario");

            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        public void ArgProc_UrlIsRequired()
        {
            // 0. Setup
            TestLogger logger;

            // Create a valid settings file that contains a URL
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            string propertiesFilePath = Path.Combine(testDir, "mysettings.txt");

            AnalysisProperties properties = new AnalysisProperties();
            properties.Add(new Property() { Id = SonarProperties.HostUrl, Value = "http://filehost" });
            properties.Save(propertiesFilePath);

            // 1. Url is not specified on the command line or in a properties file -> fail
            logger = CheckProcessingFails("/key:k1", "/name:n1", "/version:1.0");

            logger.AssertErrorLogged(SonarQube.Bootstrapper.Resources.ERROR_Args_UrlRequired);
            logger.AssertErrorsLogged(1);

            // 2. Url is specified in the file -> ok
            logger = new TestLogger();
            IBootstrapperSettings settings = CheckProcessingSucceeds(logger, "/key:k1", "/name:n1", "/version:1.0", "/s:" + propertiesFilePath);
            AssertUrl(settings, "http://filehost");

            // 3. Url is specified on the command line too -> ok, and overrides the file setting
            logger = new TestLogger();
            settings = CheckProcessingSucceeds(logger, "/key:k1", "/name:n1", "/version:1.0", "/s:" + propertiesFilePath, "/d:sonar.host.url=http://cmdlinehost");
            AssertUrl(settings, "http://cmdlinehost");
        }
        public void BootSettings_DownloadDirFromEnvVars()
        {
            // 0. Setup
            TestLogger logger = new TestLogger();

            // 1. Legacy TFS variable will be used if available
            using (EnvironmentVariableScope scope = new EnvironmentVariableScope())
            {
                scope.SetVariable(BootstrapperSettings.BuildDirectory_Legacy, "legacy tf build");
                scope.SetVariable(BootstrapperSettings.BuildDirectory_TFS2015, null);

                IBootstrapperSettings settings = new BootstrapperSettings(AnalysisPhase.PreProcessing, null, "http://sq", LoggerVerbosity.Debug, logger);
                AssertExpectedDownloadDir(Path.Combine("legacy tf build", DownloadFolderRelativePath), settings);
            }

            // 2. TFS2015 variable will be used if available
            using (EnvironmentVariableScope scope = new EnvironmentVariableScope())
            {
                scope.SetVariable(BootstrapperSettings.BuildDirectory_Legacy, null);
                scope.SetVariable(BootstrapperSettings.BuildDirectory_TFS2015, "tfs build");

                IBootstrapperSettings settings = new BootstrapperSettings(AnalysisPhase.PreProcessing, null, "http://sq", LoggerVerbosity.Debug, logger);
                AssertExpectedDownloadDir(Path.Combine("tfs build", DownloadFolderRelativePath), settings);
            }

            // 3. CWD has least precedence over env variables
            using (EnvironmentVariableScope scope = new EnvironmentVariableScope())
            {
                scope.SetVariable(BootstrapperSettings.BuildDirectory_Legacy, null);
                scope.SetVariable(BootstrapperSettings.BuildDirectory_TFS2015, null);

                IBootstrapperSettings settings = new BootstrapperSettings(AnalysisPhase.PreProcessing, null, "http://sq", LoggerVerbosity.Debug, logger);
                AssertExpectedDownloadDir(Path.Combine(Directory.GetCurrentDirectory(), DownloadFolderRelativePath), settings);
            }
        }
        public void ArgProc_UnrecognizedArgumentsAreIgnored()
        {
            TestLogger logger = new TestLogger();

            // 1. Minimal command line settings with extra values
            IBootstrapperSettings settings = CheckProcessingSucceeds(logger, "/d:sonar.host.url=foo", "foo", "blah", "/xxxx");
            AssertUrlAndChildCmdLineArgs(settings, "foo", "/d:sonar.host.url=foo", "foo", "blah", "/xxxx");
        }
        public void Factory_InvalidCallSequence_Fails()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            IPreprocessorObjectFactory testSubject = new PreprocessorObjectFactory();

            // 2. Act and assert
            AssertException.Expects<InvalidOperationException>(() => testSubject.CreateAnalyzerProvider(logger));
        }
        public void BootSettings_InvalidArguments()
        {
            string validUrl = "http://myserver";
            ILogger validLogger = new TestLogger();
            IList<string> validArgs = null;

            AssertException.Expects<ArgumentNullException>(() => new BootstrapperSettings(AnalysisPhase.PostProcessing, validArgs, null, LoggerVerbosity.Debug, validLogger));
            AssertException.Expects<ArgumentNullException>(() => new BootstrapperSettings(AnalysisPhase.PreProcessing, validArgs, validUrl, LoggerVerbosity.Debug, null));
        }
        public void ArgProc_StripVerbsAndPrefixes()
        {
            TestLogger logger = new TestLogger();

            IBootstrapperSettings settings = CheckProcessingSucceeds(logger, "/d:sonar.host.url=foo", "/begin:true", "/install:true");
            AssertUrlAndChildCmdLineArgs(settings, "foo", "/d:sonar.host.url=foo", "/begin:true", "/install:true");

            settings = CheckProcessingSucceeds(logger, "/d:sonar.host.url=foo", "begin", "/installXXX:true");
            AssertUrlAndChildCmdLineArgs(settings, "foo", "/d:sonar.host.url=foo", "/installXXX:true");
        }
        public void EmbeddedInstall_CachingScenarios()
        {
            // Arrange
            string localCacheDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            TestLogger logger = new TestLogger();

            Plugin requestA = new Plugin("p111", "1.0-SNAPSHOT", "p1.zip");
            Plugin requestB = new Plugin("p222", "9.1.3.0", "p2.zip");

            MockSonarQubeServer mockServer = new MockSonarQubeServer();
            AddPlugin(mockServer, requestA, "aaa", "bbb");
            AddPlugin(mockServer, requestB, "ccc");

            IList<string> expectedPlugin111Paths = CalculateExpectedCachedFilePaths(localCacheDir, requestA, "p1.zip", "aaa", "bbb");
            IList<string> expectedPlugin222Paths = CalculateExpectedCachedFilePaths(localCacheDir, requestB, "p2.zip", "ccc");
            List<string> allExpectedPaths = new List<string>(expectedPlugin111Paths);
            allExpectedPaths.AddRange(expectedPlugin222Paths);

            EmbeddedAnalyzerInstaller testSubject = new EmbeddedAnalyzerInstaller(mockServer, localCacheDir, logger);

            AssertExpectedFilesInCache(0, localCacheDir); // cache should be empty to start with

            // 1. Empty cache -> cache miss -> server called
            IEnumerable<string> actualFiles = testSubject.InstallAssemblies(new Plugin[] { requestA });
            mockServer.AssertMethodCalled(DownloadEmbeddedFileMethodName, 1); // should have tried to download

            AssertExpectedFilesReturned(expectedPlugin111Paths, actualFiles);
            AssertExpectedFilesExist(expectedPlugin111Paths);
            AssertExpectedFilesInCache(3, localCacheDir); // only files for the first request should exist

            // 2. New request + request request -> partial cache miss -> server called only for the new request
            actualFiles = testSubject.InstallAssemblies(new Plugin[] { requestA, requestB });
            mockServer.AssertMethodCalled(DownloadEmbeddedFileMethodName, 2); // new request

            AssertExpectedFilesReturned(allExpectedPaths, actualFiles);
            AssertExpectedFilesExist(allExpectedPaths);
            AssertExpectedFilesInCache(5, localCacheDir); // files for both plugins should exist

            // 3. Repeat the request -> cache hit -> server not called
            actualFiles = testSubject.InstallAssemblies(new Plugin[] { requestA, requestB });
            mockServer.AssertMethodCalled(DownloadEmbeddedFileMethodName, 2); // call count should not have changed

            AssertExpectedFilesReturned(allExpectedPaths, actualFiles);

            // 4. Clear the cache and request both -> cache miss -> multiple requests
            Directory.Delete(localCacheDir, true);
            Assert.IsFalse(Directory.Exists(localCacheDir), "Test error: failed to delete the local cache directory");

            actualFiles = testSubject.InstallAssemblies(new Plugin[] { requestA, requestB });
            mockServer.AssertMethodCalled(DownloadEmbeddedFileMethodName, 4); // two new requests

            AssertExpectedFilesReturned(allExpectedPaths, actualFiles);
            AssertExpectedFilesExist(allExpectedPaths);
            AssertExpectedFilesInCache(5, localCacheDir); // files for both plugins should exist
        }
        private static void CheckVerbosity(string errorMessage, LoggerVerbosity expectedVerbosity, string verbosity = null, string logLevel = null, int expectedNumberOfWarnings = 0)
        {
            var provider = CreatePropertiesProvider(verbosity, logLevel);
            TestLogger logger = new TestLogger();

            var actualVerbosity = VerbosityCalculator.ComputeVerbosity(provider, logger);

            Assert.AreEqual(expectedVerbosity, actualVerbosity, errorMessage);

            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(expectedNumberOfWarnings);
        }
        public void AnalysisConfGen_Simple()
        {
            // Arrange
            string analysisDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            TestLogger logger = new TestLogger();

            ListPropertiesProvider propertyProvider = new ListPropertiesProvider();
            propertyProvider.AddProperty(SonarProperties.HostUrl, "http://foo");
            ProcessedArgs args = new ProcessedArgs("valid.key", "valid.name", "1.0", false, EmptyPropertyProvider.Instance, propertyProvider);

            TeamBuildSettings tbSettings = TeamBuildSettings.CreateNonTeamBuildSettingsForTesting(analysisDir);

            Dictionary<string, string> serverSettings = new Dictionary<string, string>();
            serverSettings.Add("server.key.1", "server.value.1");

            AnalyzerSettings analyzerSettings = new AnalyzerSettings();
            analyzerSettings.RuleSetFilePath = "c:\\xxx.ruleset";
            analyzerSettings.AdditionalFilePaths = new List<string>();
            analyzerSettings.AdditionalFilePaths.Add("f:\\additionalPath1.txt");
            analyzerSettings.AnalyzerAssemblyPaths = new List<string>();
            analyzerSettings.AnalyzerAssemblyPaths.Add("f:\\temp\\analyzer1.dll");

            Directory.CreateDirectory(tbSettings.SonarConfigDirectory); // config directory needs to exist

            // Act
            AnalysisConfig actualConfig = AnalysisConfigGenerator.GenerateFile(args, tbSettings, serverSettings, analyzerSettings, logger);

            // Assert
            AssertConfigFileExists(actualConfig);
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);

            Assert.AreEqual("valid.key", actualConfig.SonarProjectKey);
            Assert.AreEqual("valid.name", actualConfig.SonarProjectName);
            Assert.AreEqual("1.0", actualConfig.SonarProjectVersion);

            Assert.AreEqual("http://foo", actualConfig.SonarQubeHostUrl);

            Assert.AreEqual(tbSettings.SonarBinDirectory, actualConfig.SonarBinDir);
            Assert.AreEqual(tbSettings.SonarConfigDirectory, actualConfig.SonarConfigDir);
            Assert.AreEqual(tbSettings.SonarOutputDirectory, actualConfig.SonarOutputDir);
            Assert.AreEqual(tbSettings.SonarRunnerWorkingDirectory, actualConfig.SonarRunnerWorkingDirectory);
            Assert.AreEqual(tbSettings.BuildUri, actualConfig.GetBuildUri());
            Assert.AreEqual(tbSettings.TfsUri, actualConfig.GetTfsUri());

            Assert.IsNotNull(actualConfig.ServerSettings);
            Property serverProperty = actualConfig.ServerSettings.SingleOrDefault(s => string.Equals(s.Id, "server.key.1", System.StringComparison.Ordinal));
            Assert.IsNotNull(serverProperty);
            Assert.AreEqual("server.value.1", serverProperty.Value);

            Assert.AreSame(analyzerSettings, actualConfig.AnalyzerSettings);
        }
        public void PostArgProc_NoArgs()
        {
            // 0. Setup
            TestLogger logger = new TestLogger();
            IAnalysisPropertyProvider provider;

            // 1. Null input
            AssertException.Expects<ArgumentNullException>(() => ArgumentProcessor.TryProcessArgs(null, logger, out provider));

            // 2. Empty array input
            provider = CheckProcessingSucceeds(logger, new string[] { });
            provider.AssertExpectedPropertyCount(0);
        }
        public void FileProvider_NoFileArguments()
        {
            // Arrange
            IAnalysisPropertyProvider provider;
            TestLogger logger = new TestLogger();
            string defaultPropertiesDir = this.TestContext.TestDeploymentDir;

            // Act
            provider = CheckProcessingSucceeds(Enumerable.Empty<ArgumentInstance>(), defaultPropertiesDir, logger);

            // Assert
            Assert.IsNotNull(provider, "Expecting a provider to have been created");
            Assert.AreEqual(0, provider.GetAllProperties().Count(), "Not expecting the provider to return any properties");
        }
        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);
        }
        public void Factory_ThrowsOnInvalidInput()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            ProcessedArgs validArgs = CreateValidArguments();
            IPreprocessorObjectFactory testSubject = new PreprocessorObjectFactory();

            // 1. CreateSonarQubeServer method
            AssertException.Expects<ArgumentNullException>(() => testSubject.CreateSonarQubeServer(null, logger));
            AssertException.Expects<ArgumentNullException>(() => testSubject.CreateSonarQubeServer(validArgs, null));

            // 2. CreateAnalyzerProvider method
            AssertException.Expects<ArgumentNullException>(() => testSubject.CreateAnalyzerProvider(null));
        }
        public void FileGen_AdditionalProperties()
        {
            // 0. Arrange
            string analysisRootDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            TestLogger logger = new TestLogger();

            CreateProjectWithFiles("project1", analysisRootDir);
            AnalysisConfig config = CreateValidConfig(analysisRootDir);

            // Add additional properties
            config.LocalSettings = new AnalysisProperties();
            config.LocalSettings.Add(new Property() { Id = "key1", Value = "value1" });
            config.LocalSettings.Add(new Property() { Id = "key.2", Value = "value two" });
            config.LocalSettings.Add(new Property() { Id = "key.3", Value = " " });

            // Sensitive data should not be written
            config.LocalSettings.Add(new Property() { Id = SonarProperties.DbPassword, Value ="secret db pwd" });
            config.LocalSettings.Add(new Property() { Id = SonarProperties.SonarPassword, Value = "secret pwd" });

            // Server properties should not be added
            config.ServerSettings = new AnalysisProperties();
            config.ServerSettings.Add(new Property() { Id = "server.key", Value = "should not be added" });

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

            // Assert
            AssertExpectedProjectCount(1, result);

            // One valid project info file -> file created
            AssertPropertiesFilesCreated(result, logger);

            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingExists("key1", "value1");
            provider.AssertSettingExists("key.2", "value two");
            provider.AssertSettingExists("key.3", " ");

            provider.AssertSettingDoesNotExist("server.key");

            // SONARMSBRU-136: TODO - uncomment the following code:
            //provider.AssertSettingExists("server.key", "");
            //provider.AssertSettingDoesNotExist(SonarProperties.DbPassword);
            //provider.AssertSettingDoesNotExist(SonarProperties.SonarPassword);

            // SONARMSBRU-136: TODO - delete the following code:
            // v1.0.1 back-compat: check sensitive data is written to the properties file
            provider.AssertSettingExists(SonarProperties.DbPassword, "secret db pwd");
            provider.AssertSettingExists(SonarProperties.SonarPassword, "secret pwd");
        }
        public void SonarLint_ValidRuleset()
        {
            // Arrange
            string rootDir = CreateTestFolders();
            TestLogger logger = new TestLogger();
            TeamBuildSettings settings = CreateSettings(rootDir);
            MockSonarQubeServer mockServer = CreateValidServer("valid.project", "valid.profile");

            // Act
            SonarLintAnalyzerProvider.SetupAnalyzers(mockServer, settings, "valid.project", logger);

            // Assert
            CheckRulesetExists(rootDir);
            CheckSonarLintBinariesExist(rootDir);
        }
        public void SarifFixer_ShouldNotChange_Unfixable()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            string testSarifString = @"{
  ""version"": ""0.1"",
  ""toolInfo"": {
                ""toolName"": ""Microsoft (R) Visual C# Compiler"",
    ""productVersion"": ""1.0.0"",
    ""fileVersion"": ""1.0.0""
  },
  ""issues"": [
    { 

}}}}}}}}}}}}}}}}}}}}}}}}}

      ""ruleId"": ""DD001"",
      ""locations"": [
        {
          ""analysisTarget"": [
            {
              ""uri"": ""C:\\agent\\_work\\2\\s\\MyTestProj\\Program.cs"",
}
          ]
        }
      ],
      ""shortMessage"": ""Test shortMessage. It features \""quoted text\""."",
      ""properties"": {
        ""severity"": ""Info"",
        ""helpLink"": ""https://github.com/SonarSource/sonar-msbuild-runner"",
      }
    }
  ]
}";
            string testSarifPath = Path.Combine(testDir, "testSarif.json");
            File.WriteAllText(testSarifPath, testSarifString);
            DateTime originalWriteTime = new FileInfo(testSarifPath).LastWriteTime;

            // Act
            string returnedSarifPath = new RoslynV1SarifFixer().LoadAndFixFile(testSarifPath, logger);

            // Assert
            // unfixable -> no change to file, null return
            AssertFileUnchanged(testSarifPath, originalWriteTime);
            Assert.IsNull(returnedSarifPath);
        }
        public void TrxReader_TestsResultsDirectoryMissing()
        {
            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            TestLogger logger = new TestLogger();

            // Act
            string coverageFilePath = TrxFileReader.LocateCodeCoverageFile(testDir, logger);

            // Assert
            Assert.AreEqual(null, coverageFilePath);

            // Not expecting errors or warnings: we assume it means that tests have not been executed
            logger.AssertErrorsLogged(0);
            logger.AssertWarningsLogged(0);
        }
        public void ProcRunner_ExecutionFailed()
        {
            // Arrange
            string exeName = TestUtils.WriteBatchFileForTest(TestContext, "exit -2");

            TestLogger logger = new TestLogger();
            ProcessRunnerArguments args = new ProcessRunnerArguments(exeName, logger);
            ProcessRunner runner = new ProcessRunner();

            // Act
            bool success = runner.Execute(args);

            // Assert
            Assert.IsFalse(success, "Expecting the process to have failed");
            Assert.AreEqual(-2, runner.ExitCode, "Unexpected exit code");
        }
        public void FileProvider_InvalidDefaultPropertiesFile()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            string defaultPropertiesDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            string invalidFile = CreateFile(defaultPropertiesDir, FilePropertyProvider.DefaultFileName, "not a valid XML properties file");

            IList<ArgumentInstance> args = new List<ArgumentInstance>();

            // Act
            CheckProcessingFails(args, defaultPropertiesDir, logger);

            // Assert
            logger.AssertErrorsLogged(1);
            logger.AssertSingleErrorExists(invalidFile);
        }
        public void Credentials()
        {
            ILogger logger = new TestLogger();

            WebClientDownloader downloader;
            downloader = new WebClientDownloader(null, null, logger);
            Assert.AreEqual(null, downloader.GetHeader(HttpRequestHeader.Authorization));

            downloader = new WebClientDownloader("da39a3ee5e6b4b0d3255bfef95601890afd80709", null, logger);
            Assert.AreEqual("Basic ZGEzOWEzZWU1ZTZiNGIwZDMyNTViZmVmOTU2MDE4OTBhZmQ4MDcwOTo=", downloader.GetHeader(HttpRequestHeader.Authorization));

            downloader = new WebClientDownloader(null, "password", logger);
            Assert.AreEqual(null, downloader.GetHeader(HttpRequestHeader.Authorization));

            downloader = new WebClientDownloader("admin", "password", logger);
            Assert.AreEqual("Basic YWRtaW46cGFzc3dvcmQ=", downloader.GetHeader(HttpRequestHeader.Authorization));
        }