public void FileGen_VSBootstrapperIsDisabled_OverrideUserSettings_SameValue()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            Property bootstrapperProperty = new Property() { Id = PropertiesFileGenerator.VSBootstrapperPropertyKey, Value = "false" };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("disableBootstrapperSame", logger, bootstrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingExists(PropertiesFileGenerator.VSBootstrapperPropertyKey, "false");
            logger.AssertSingleDebugMessageExists(PropertiesFileGenerator.VSBootstrapperPropertyKey);
            logger.AssertWarningsLogged(0); // not expecting a warning if the user has supplied the value we want
        }
        public void FileGen_BuildWrapperOutputDirContainsFiles_PropertyIsWritten()
        {
            // Arrange
            // Create directory and file in child directory
            string bwOutputPath = TestUtils.CreateTestSpecificFolder(this.TestContext, "bw_output_withFiles");
            string childDir = TestUtils.CreateTestSpecificFolder(this.TestContext, "bw_output_withFiles\\childDir");
            string contentFilePath = Path.Combine(childDir, "dummy.txt");
            File.WriteAllText(contentFilePath, "dummy bw output");

            TestLogger logger = new TestLogger();
            Property buildWrapperProperty = new Property() { Id = PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, Value = bwOutputPath };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("buildwrapper_dirwithfiles", logger, buildWrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            string expectedPropertyValue = PropertiesWriter.Escape(bwOutputPath); // property is a path so it will be escaped
            provider.AssertSettingExists(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, expectedPropertyValue);

            logger.AssertSingleDebugMessageExists(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, bwOutputPath);

            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        private void CheckInvalidUrlFails(string url)
        {
            // Arrange
            TestLogger logger = new TestLogger();
            BuildAgentUpdater updater = new BuildAgentUpdater();

            string downloadDir = this.TestContext.DeploymentDirectory;
            string nonExistentUrl = url;

            string expectedUrl = nonExistentUrl + BootstrapperSettings.IntegrationUrlSuffix;
            string expectedDownloadPath = Path.Combine(downloadDir, BootstrapperSettings.SonarQubeIntegrationFilename);

            // Act
            bool success = updater.TryUpdate(nonExistentUrl, downloadDir, logger);

            // Assert
            Assert.IsFalse(success, "Not expecting the update to succeed");
            logger.AssertSingleDebugMessageExists(expectedUrl, expectedDownloadPath);
            logger.AssertSingleErrorExists(nonExistentUrl);
            logger.AssertErrorsLogged(1);
        }
        public void FileGen_BuildWrapperOutputDirIsMissing_PropertyNotWritten()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            Property buildWrapperProperty = new Property() { Id = PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, Value = "non-existent directory" };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("buildwrapper_missingdir", logger, buildWrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingDoesNotExist(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey);

            logger.AssertSingleDebugMessageExists(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, "non-existent directory");
            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        public void FileGen_BuildWrapperOutputDirIsEmpty_PropertyNotWritten()
        {
            // Arrange
            // Create empty folder with empty child folder
            string emptyFolderPath = TestUtils.CreateTestSpecificFolder(this.TestContext, "empty_bw_output");
            TestUtils.CreateTestSpecificFolder(this.TestContext, "empty_bw_output\\childDir");

            TestLogger logger = new TestLogger();
            Property buildWrapperProperty = new Property() { Id = PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, Value = emptyFolderPath };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("buildwrapper_emptydir", logger, buildWrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingDoesNotExist(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey);

            logger.AssertSingleDebugMessageExists(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, emptyFolderPath);
            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        public void ProcRunner_DoNotLogSensitiveData()
        {
            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            // Create a dummy exe that will produce a log file showing any input args
            string exeName = DummyExeHelper.CreateDummyPostProcessor(testDir, 0);

            TestLogger logger = new TestLogger();

            // Public args - should appear in the log
            string[] publicArgs = new string[]
            {
                "public1",
                "public2",
                "/d:sonar.projectKey=my.key"
            };

            string[] sensitiveArgs = new string[] {
                // Public args - should appear in the log
                "public1", "public2", "/dmy.key=value",

                // Sensitive args - should not appear in the log
                "/d:sonar.password=secret data password",
                "/d:sonar.login=secret data login",
                "/d:sonar.jdbc.password=secret data db password",
                "/d:sonar.jdbc.username=secret data db user name",

                // Sensitive args - different cases -> exclude to be on the safe side
                "/d:SONAR.jdbc.password=secret data db password upper",
                "/d:sonar.PASSWORD=secret data password upper",

                // Sensitive args - parameter format is slightly incorrect -> exclude to be on the safe side
                "/dsonar.login =secret data key typo",
                "sonar.password=secret data password typo"
            };

            string[] allArgs = sensitiveArgs.Union(publicArgs).ToArray();

            ProcessRunnerArguments runnerArgs = new ProcessRunnerArguments(exeName, logger)
            {
                CmdLineArgs = allArgs
            };
            ProcessRunner runner = new ProcessRunner();

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

            // Assert
            Assert.IsTrue(success, "Expecting the process to have succeeded");
            Assert.AreEqual(0, runner.ExitCode, "Unexpected exit code");

            // Check public arguments are logged but private ones are not
            foreach(string arg in publicArgs)
            {
                logger.AssertSingleDebugMessageExists(arg);
            }

            logger.AssertSingleDebugMessageExists(SonarQube.Common.Resources.MSG_CmdLine_SensitiveCmdLineArgsAlternativeText);
            AssertTextDoesNotAppearInLog("secret", logger);

            // Check that the public and private arguments are passed to the child process
            string exeLogFile = DummyExeHelper.AssertDummyPostProcLogExists(testDir, this.TestContext);
            DummyExeHelper.AssertExpectedLogContents(exeLogFile, allArgs);
        }
        public void ProcRunner_PassesEnvVariables_OverrideExisting()
        {
            // Tests that existing environment variables will be overwritten successfully

            // Arrange
            TestLogger logger = new TestLogger();
            ProcessRunner runner = new ProcessRunner();

            try
            {
                // It's possible the user won't be have permissions to set machine level variables
                // (e.g. when running on a build agent). Carry on with testing the other variables.
                SafeSetEnvironmentVariable("proc.runner.test.machine", "existing machine value", EnvironmentVariableTarget.Machine, logger);
                Environment.SetEnvironmentVariable("proc.runner.test.process", "existing process value", EnvironmentVariableTarget.Process);
                Environment.SetEnvironmentVariable("proc.runner.test.user", "existing user value", EnvironmentVariableTarget.User);

                string exeName = TestUtils.WriteBatchFileForTest(TestContext,
            @"@echo file: %proc.runner.test.machine%
            @echo file: %proc.runner.test.process%
            @echo file: %proc.runner.test.user%
            ");

                var envVariables = new Dictionary<string, string>() {
                    { "proc.runner.test.machine", "machine override" },
                    { "proc.runner.test.process", "process override" },
                    { "proc.runner.test.user", "user override" } };

                ProcessRunnerArguments args = new ProcessRunnerArguments(exeName, logger)
                {
                    EnvironmentVariables = envVariables
                };

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

                // Assert
                Assert.IsTrue(success, "Expecting the process to have succeeded");
                Assert.AreEqual(0, runner.ExitCode, "Unexpected exit code");
            }
            finally
            {
                SafeSetEnvironmentVariable("proc.runner.test.machine", null, EnvironmentVariableTarget.Machine, logger);
                Environment.SetEnvironmentVariable("proc.runner.test.process", null, EnvironmentVariableTarget.Process);
                Environment.SetEnvironmentVariable("proc.runner.test.user", null, EnvironmentVariableTarget.User);
            }

            // Check the child process used expected values
            logger.AssertMessageLogged("file: machine override");
            logger.AssertMessageLogged("file: process override");
            logger.AssertMessageLogged("file: user override");

            // Check the runner reported it was overwriting existing variables
            // Note: the existing non-process values won't be visible to the child process
            // unless they were set *before* the test host launched, which won't be the case.
            logger.AssertSingleDebugMessageExists("proc.runner.test.process", "existing process value", "process override");
        }
 private static void AssertRetryAttempted(TestLogger logger)
 {
     // We'll assume retry has been attempted if there is a message containing
     // both of the timeout values
     logger.AssertSingleDebugMessageExists(TaskUtilities.MaxConfigRetryPeriodInMilliseconds.ToString(), TaskUtilities.DelayBetweenRetriesInMilliseconds.ToString());
 }