public void TfsProcessor_CmdLineArgsOrdering()
        {
            // Check that user arguments are passed through to the wrapper and that they appear first

            // Arrange
            var logger = new TestLogger();
            var args   = new string[] { "ConvertCoverage", "d:\\propertiesFile.Path" };

            var mockRunner = new MockProcessRunner(executeResult: true);

            // Act
            var success = ExecuteTFSProcessorIgnoringAsserts(
                new AnalysisConfig()
            {
                SonarScannerWorkingDirectory = "D:\\dummyWorkingDirectory"
            },
                args,
                logger,
                "c:\\dummy.exe",
                "c:\\foo.properties",
                mockRunner);

            // Assert
            VerifyProcessRunOutcome(mockRunner, logger, "D:\\dummyWorkingDirectory", success, true);

            CheckArgExists("ConvertCoverage", mockRunner);
            CheckArgExists("d:\\propertiesFile.Path", mockRunner);
        }
        private static void CheckArgDoesNotExist(string argToCheck, MockProcessRunner mockRunner)
        {
            string allArgs = mockRunner.SuppliedArguments.GetEscapedArguments();
            var    index   = allArgs.IndexOf(argToCheck);

            index.Should().Be(-1, "Not expecting to find the argument. Arg: '{0}', all args: '{1}'", argToCheck, allArgs);
        }
        public void SonarScanner_UserSpecifiedEnvVars_OnlySONARSCANNEROPTSIsPassed()
        {
            // Arrange
            var logger     = new TestLogger();
            var mockRunner = new MockProcessRunner(executeResult: true);
            var config     = new AnalysisConfig()
            {
                SonarScannerWorkingDirectory = "c:\\work"
            };

            using (new EnvironmentVariableScope())
            {
                // the SONAR_SCANNER_OPTS variable should be passed through explicitly,
                // but not other variables
                Environment.SetEnvironmentVariable("Foo", "xxx");
                Environment.SetEnvironmentVariable("SONAR_SCANNER_OPTS", "-Xmx2048m");
                Environment.SetEnvironmentVariable("Bar", "yyy");

                // Act
                var success = ExecuteJavaRunnerIgnoringAsserts(config, Enumerable.Empty <string>(), logger, "c:\\exe.Path", "d:\\propertiesFile.Path", mockRunner);

                // Assert
                VerifyProcessRunOutcome(mockRunner, logger, "c:\\work", success, true);
            }

            CheckEnvVarExists("SONAR_SCANNER_OPTS", "-Xmx2048m", mockRunner);
            mockRunner.SuppliedArguments.EnvironmentVariables.Count.Should().Be(1);
            logger.InfoMessages.Should().Contain(msg => msg.Contains("SONAR_SCANNER_OPTS"));
            logger.InfoMessages.Should().Contain(msg => msg.Contains("-Xmx2048m"));
        }
        public void SonarScanner_CmdLineArgsOrdering()
        {
            // Check that user arguments are passed through to the wrapper and that they appear first

            // Arrange
            var logger   = new TestLogger();
            var userArgs = new string[] { "-Dsonar.login=me", "-Dsonar.password=my.pwd" };

            var mockRunner = new MockProcessRunner(executeResult: true);

            // Act
            var success = ExecuteJavaRunnerIgnoringAsserts(
                new AnalysisConfig()
            {
                SonarScannerWorkingDirectory = "D:\\dummyWorkingDirectory"
            },
                userArgs,
                logger,
                "c:\\dummy.exe",
                "c:\\foo.properties",
                mockRunner);

            // Assert
            VerifyProcessRunOutcome(mockRunner, logger, "D:\\dummyWorkingDirectory", success, true);

            CheckStandardArgsPassed(mockRunner, "c:\\foo.properties");

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

            var propertiesFileIndex = CheckArgExists(SonarScannerWrapper.ProjectSettingsFileArgName, mockRunner);

            propertiesFileIndex.Should().BeGreaterThan(loginIndex, "User arguments should appear first");
            propertiesFileIndex.Should().BeGreaterThan(pwdIndex, "User arguments should appear first");
        }
        /// <summary>
        /// Checks that the argument exists, and returns the start position of the argument in the list of
        /// concatenated arguments so we can check that the arguments are passed in the correct order
        /// </summary>
        private int CheckArgExists(string expectedArg, MockProcessRunner mockRunner)
        {
            var allArgs = string.Join(" ", mockRunner.SuppliedArguments.CmdLineArgs);
            var index   = allArgs.IndexOf(expectedArg);

            index.Should().BeGreaterThan(-1, "Expected argument was not found. Arg: '{0}', all args: '{1}'", expectedArg, allArgs);
            return(index);
        }
        public void SonarScanner_SensitiveArgsPassedOnCommandLine()
        {
            // Check that sensitive arguments from the config are passed on the command line

            // Arrange
            var logger     = new TestLogger();
            var mockRunner = new MockProcessRunner(executeResult: true);
            var userArgs   = new string[] { "-Dxxx=yyy", "-Dsonar.password=cmdline.password" };

            // Create a config file containing sensitive arguments
            var fileSettings = new AnalysisProperties
            {
                new Property()
                {
                    Id = SonarProperties.DbPassword, Value = "file db pwd"
                },
                new Property()
                {
                    Id = SonarProperties.SonarPassword, Value = "file.password - should not be returned"
                },
                new Property()
                {
                    Id = "file.not.sensitive.key", Value = "not sensitive value"
                }
            };

            var testDir          = TestUtils.CreateTestSpecificFolderWithSubPaths(TestContext);
            var settingsFilePath = Path.Combine(testDir, "fileSettings.txt");

            fileSettings.Save(settingsFilePath);

            var config = new AnalysisConfig()
            {
                SonarScannerWorkingDirectory = testDir
            };

            config.SetSettingsFilePath(settingsFilePath);

            // Act
            var success = ExecuteJavaRunnerIgnoringAsserts(config, userArgs, logger, "c:\\foo.exe", "c:\\foo.props", mockRunner);

            // Assert
            VerifyProcessRunOutcome(mockRunner, logger, testDir, success, true);

            CheckStandardArgsPassed(mockRunner, "c:\\foo.props");

            // Non-sensitive values from the file should not be passed on the command line
            CheckArgDoesNotExist("file.not.sensitive.key", mockRunner);

            var dbPwdIndex   = CheckArgExists("-Dsonar.jdbc.password=file db pwd", mockRunner); // sensitive value from file
            var userPwdIndex = CheckArgExists("-Dsonar.password=cmdline.password", mockRunner); // sensitive value from cmd line: overrides file value

            var propertiesFileIndex = CheckArgExists(SonarScannerWrapper.ProjectSettingsFileArgName, mockRunner);

            propertiesFileIndex.Should().BeGreaterThan(dbPwdIndex, "User arguments should appear first");
            propertiesFileIndex.Should().BeGreaterThan(userPwdIndex, "User arguments should appear first");
        }
        public void TfsProcessor_StandardAdditionalArgumentsPassed()
        {
            // Arrange
            var logger     = new TestLogger();
            var mockRunner = new MockProcessRunner(executeResult: true);
            var config     = new AnalysisConfig()
            {
                SonarScannerWorkingDirectory = "c:\\work"
            };

            // Act
            var success = ExecuteTFSProcessorIgnoringAsserts(config, Enumerable.Empty <string>(), logger, "c:\\exe.Path", "d:\\propertiesFile.Path", mockRunner);

            // Assert
            VerifyProcessRunOutcome(mockRunner, logger, "c:\\work", success, true);
        }
        private static void VerifyProcessRunOutcome(MockProcessRunner mockRunner, TestLogger testLogger, string expectedWorkingDir, bool actualOutcome, bool expectedOutcome)
        {
            actualOutcome.Should().Be(expectedOutcome);

            mockRunner.SuppliedArguments.WorkingDirectory.Should().Be(expectedWorkingDir);

            if (actualOutcome)
            {
                // Errors can still be logged when the process completes successfully, so
                // we don't check the error log in this case
                testLogger.AssertInfoMessageExists(Resources.MSG_TFSProcessorCompleted);
            }
            else
            {
                testLogger.AssertErrorsLogged();
                testLogger.AssertErrorLogged(Resources.ERR_TFSProcessorExecutionFailed);
            }
        }
        private void TestWrapperErrorHandling(bool executeResult, bool addMessageToStdErr, bool expectedOutcome)
        {
            // Arrange
            var logger     = new TestLogger();
            var mockRunner = new MockProcessRunner(executeResult);

            var config = new AnalysisConfig()
            {
                SonarScannerWorkingDirectory = "C:\\working"
            };

            if (addMessageToStdErr)
            {
                logger.LogError("Dummy error");
            }

            // Act
            var success = ExecuteTFSProcessorIgnoringAsserts(config, Enumerable.Empty <string>(), logger, "c:\\bar.exe", "c:\\props.xml", mockRunner);

            // Assert
            VerifyProcessRunOutcome(mockRunner, logger, "C:\\working", success, expectedOutcome);
        }
        public void SonarScannerHome_MessageLoggedIfAlreadySet()
        {
            using (var scope = new EnvironmentVariableScope())
            {
                scope.SetVariable(SonarScannerWrapper.SonarScannerHomeVariableName, "some_path");

                // Arrange
                var testLogger = new TestLogger();
                var mockRunner = new MockProcessRunner(executeResult: true);
                var config     = new AnalysisConfig()
                {
                    SonarScannerWorkingDirectory = "c:\\workingDir"
                };

                // Act
                var success = ExecuteJavaRunnerIgnoringAsserts(config, Enumerable.Empty <string>(), testLogger, "c:\\exePath", "f:\\props.txt", mockRunner);

                // Assert
                VerifyProcessRunOutcome(mockRunner, testLogger, "c:\\workingDir", success, true);
                testLogger.AssertInfoMessageExists(SonarScanner.MSBuild.Shim.Resources.MSG_SonarScannerHomeIsSet);
            }
        }
        public void SonarScannerHome_NoMessageIfNotAlreadySet()
        {
            // Arrange
            var testLogger = new TestLogger();

            using (var scope = new EnvironmentVariableScope())
            {
                scope.SetVariable(SonarScannerWrapper.SonarScannerHomeVariableName, null);
                var config = new AnalysisConfig()
                {
                    SonarScannerWorkingDirectory = "C:\\working\\dir"
                };
                var mockRunner = new MockProcessRunner(executeResult: true);

                // Act
                var success = ExecuteJavaRunnerIgnoringAsserts(config, Enumerable.Empty <string>(), testLogger, "c:\\file.exe", "d:\\properties.prop", mockRunner);

                // Assert
                VerifyProcessRunOutcome(mockRunner, testLogger, "C:\\working\\dir", success, true);
                testLogger.AssertMessageNotLogged(SonarScanner.MSBuild.Shim.Resources.MSG_SonarScannerHomeIsSet);
            }
        }
        public void SonarScanner_NoUserSpecifiedEnvVars_SONARSCANNEROPTSIsNotPassed()
        {
            // Arrange
            var logger     = new TestLogger();
            var mockRunner = new MockProcessRunner(executeResult: true);
            var config     = new AnalysisConfig()
            {
                SonarScannerWorkingDirectory = "c:\\work"
            };

            // Act
            var success = ExecuteJavaRunnerIgnoringAsserts(config, Enumerable.Empty <string>(), logger, "c:\\exe.Path", "d:\\propertiesFile.Path", mockRunner);

            // Assert
            VerifyProcessRunOutcome(mockRunner, logger, "c:\\work", success, true);

            mockRunner.SuppliedArguments.EnvironmentVariables.Count.Should().Be(0);

            // #656: Check that the JVM size is not set by default
            // https://github.com/SonarSource/sonar-scanner-msbuild/issues/656
            logger.InfoMessages.Should().NotContain(msg => msg.Contains("SONAR_SCANNER_OPTS"));
        }
 private static void CheckEnvVarExists(string varName, string expectedValue, MockProcessRunner mockRunner)
 {
     mockRunner.SuppliedArguments.EnvironmentVariables.ContainsKey(varName).Should().BeTrue();
     mockRunner.SuppliedArguments.EnvironmentVariables[varName].Should().Be(expectedValue);
 }
 private void CheckStandardArgsPassed(MockProcessRunner mockRunner, string expectedPropertiesFilePath)
 {
     CheckArgExists("-Dproject.settings=" + expectedPropertiesFilePath, mockRunner); // should always be passing the properties file
 }