public void Exe_PostProc_Succeeds() { // Arrange string rootDir = TestUtils.CreateTestSpecificFolder(this.TestContext); using (InitializeNonTeamBuildEnvironment(rootDir)) { string binDir = CalculateBinDir(rootDir); Directory.CreateDirectory(binDir); DummyExeHelper.CreateDummyPostProcessor(binDir, 0 /* success exit code */); MockBuildAgentUpdater mockUpdater = CreateValidUpdater(binDir, "http://h:9000"); // Act TestLogger logger = CheckExecutionSucceeds(mockUpdater, "end", "other params", "yet.more.params"); // Assert mockUpdater.AssertUpdateNotAttempted(); mockUpdater.AssertVersionNotChecked(); logger.AssertWarningsLogged(0); // The bootstrapper pass through any parameters it doesn't recognise so the post-processor // can decide whether to handle them or not string logPath = DummyExeHelper.AssertDummyPostProcLogExists(binDir, this.TestContext); DummyExeHelper.AssertExpectedLogContents(logPath, "other params", "yet.more.params"); } }
public void Exe_PostProc_Fails() { // Arrange string rootDir = TestUtils.CreateTestSpecificFolder(this.TestContext); using (InitializeNonTeamBuildEnvironment(rootDir)) { string binDir = CalculateBinDir(rootDir); Directory.CreateDirectory(binDir); DummyExeHelper.CreateDummyPostProcessor(binDir, 1 /* post-proc fails */); MockBuildAgentUpdater mockUpdater = CreateValidUpdater(binDir, "http://h:9000"); // Act TestLogger logger = CheckExecutionFails(mockUpdater, "end"); // Assert mockUpdater.AssertUpdateNotAttempted(); mockUpdater.AssertVersionNotChecked(); logger.AssertWarningsLogged(0); string logPath = DummyExeHelper.AssertDummyPostProcLogExists(binDir, this.TestContext); DummyExeHelper.AssertExpectedLogContents(logPath, null); } }
public void ProcRunner_ArgumentQuotingForwardedByBatchScript() { // Checks arguments passed to a batch script which itself passes them on are correctly escaped // Arrange var testDir = TestUtils.CreateTestSpecificFolder(TestContext); // Create a dummy exe that will produce a log file showing any input args var exeName = DummyExeHelper.CreateDummyPostProcessor(testDir, 0); var batchName = TestUtils.WriteBatchFileForTest(TestContext, "\"" + exeName + "\" %*"); var logger = new TestLogger(); var args = new ProcessRunnerArguments(batchName, true); var expected = new[] { "unquoted", "\"quoted\"", "\"quoted with spaces\"", "/test:\"quoted arg\"", "unquoted with spaces", "quote in \"the middle", "quotes \"& ampersands", "\"multiple \"\"\" quotes \" ", "trailing backslash \\", "all special chars: \\ / : * ? \" < > | %", "injection \" > foo.txt", "injection \" & echo haha", "double escaping \\\" > foo.txt" }; args.CmdLineArgs = expected; var runner = new ProcessRunner(logger); // Act var success = runner.Execute(args); // Assert Assert.IsTrue(success, "Expecting the process to have succeeded"); Assert.AreEqual(0, runner.ExitCode, "Unexpected exit code"); // Check that the public and private arguments are passed to the child process var exeLogFile = DummyExeHelper.AssertDummyPostProcLogExists(testDir, TestContext); DummyExeHelper.AssertExpectedLogContents(exeLogFile, expected); }
public void ProcRunner_ArgumentQuoting() { // Checks arguments passed to the child process are correctly quoted // 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(); ProcessRunnerArguments args = new ProcessRunnerArguments(exeName, logger); args.CmdLineArgs = new string[] { "unquoted", "\"quoted\"", "\"quoted with spaces\"", "/test:\"quoted arg\"", "unquoted with spaces", "quote in \"the middle", "quotes \"& ampersands", "\"multiple \"\"\" quotes \" " }; ProcessRunner runner = new ProcessRunner(); // Act bool success = runner.Execute(args); // Assert Assert.IsTrue(success, "Expecting the process to have succeeded"); Assert.AreEqual(0, runner.ExitCode, "Unexpected exit code"); // Check that the public and private arguments are passed to the child process string exeLogFile = DummyExeHelper.AssertDummyPostProcLogExists(testDir, this.TestContext); DummyExeHelper.AssertExpectedLogContents(exeLogFile, "unquoted", "\"quoted\"", "\"quoted with spaces\"", "/test:\"quoted arg\"", "unquoted with spaces", "quote in \"the middle", "quotes \"& ampersands", "\"multiple \"\"\" quotes \" "); }
public void ProcRunner_ArgumentQuoting() { // Checks arguments passed to the child process are correctly quoted // Arrange var testDir = TestUtils.CreateTestSpecificFolder(TestContext); // Create a dummy exe that will produce a log file showing any input args var exeName = DummyExeHelper.CreateDummyPostProcessor(testDir, 0); var logger = new TestLogger(); var args = new ProcessRunnerArguments(exeName, false); var expected = new[] { "unquoted", "\"quoted\"", "\"quoted with spaces\"", "/test:\"quoted arg\"", "unquoted with spaces", "quote in \"the middle", "quotes \"& ampersands", "\"multiple \"\"\" quotes \" ", "trailing backslash \\", "all special chars: \\ / : * ? \" < > | %", "injection \" > foo.txt", "injection \" & echo haha", "double escaping \\\" > foo.txt" }; args.CmdLineArgs = expected; var runner = new ProcessRunner(logger); // Act var success = runner.Execute(args); // Assert success.Should().BeTrue("Expecting the process to have succeeded"); runner.ExitCode.Should().Be(0, "Unexpected exit code"); // Check that the public and private arguments are passed to the child process var exeLogFile = DummyExeHelper.AssertDummyPostProcLogExists(testDir, TestContext); DummyExeHelper.AssertExpectedLogContents(exeLogFile, expected); }
[WorkItem(126)] // Exclude secrets from log data: http://jira.sonarsource.com/browse/SONARMSBRU-126 public void ProcRunner_DoNotLogSensitiveData() { // Arrange var testDir = TestUtils.CreateTestSpecificFolder(TestContext); // Create a dummy exe that will produce a log file showing any input args var exeName = DummyExeHelper.CreateDummyPostProcessor(testDir, 0); var logger = new TestLogger(); // Public args - should appear in the log var publicArgs = new string[] { "public1", "public2", "/d:sonar.projectKey=my.key" }; var 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" }; var allArgs = sensitiveArgs.Union(publicArgs).ToArray(); var runnerArgs = new ProcessRunnerArguments(exeName, false) { CmdLineArgs = allArgs }; var runner = new ProcessRunner(logger); // Act var 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 (var arg in publicArgs) { logger.AssertSingleDebugMessageExists(arg); } logger.AssertSingleDebugMessageExists("<sensitive data removed>"); AssertTextDoesNotAppearInLog("secret", logger); // Check that the public and private arguments are passed to the child process var exeLogFile = DummyExeHelper.AssertDummyPostProcLogExists(testDir, TestContext); DummyExeHelper.AssertExpectedLogContents(exeLogFile, allArgs); }
public void Exe__Version0_9Compatibility() { // Tests compatibility with the bootstrapper API used in v0.9 // The pre-processor should be called if any arguments are passed. // The post-processor should be called if no arguments are passed. // Default settings: // There must be a default settings file next to the bootstrapper exe to supply // the necessary settings, and the bootstrapper should pass this settings path // to the pre-processor (since the pre-process is downloaded to a different // directory). // Arrange string rootDir = TestUtils.CreateTestSpecificFolder(this.TestContext); using (InitializeNonTeamBuildEnvironment(rootDir)) { string binDir = CalculateBinDir(rootDir); MockBuildAgentUpdater mockUpdater = CreateValidUpdater(binDir, "http://host"); mockUpdater.Updating += (sender, args) => { Assert.IsTrue(Directory.Exists(args.TargetDir), "Expecting the target directory to have been created"); DummyExeHelper.CreateDummyPreProcessor(args.TargetDir, 0 /* post-proc succeeds */); DummyExeHelper.CreateDummyPostProcessor(args.TargetDir, 0 /* post-proc succeeds */); }; // Create a default properties file next to the exe AnalysisProperties defaultProperties = new AnalysisProperties(); defaultProperties.Add(new Property() { Id = SonarProperties.HostUrl, Value = "http://host" }); string defaultPropertiesFilePath = CreateDefaultPropertiesFile(defaultProperties); // Act try { // Call the pre-processor TestLogger logger = CheckExecutionSucceeds(mockUpdater, "/v:version", "/n:name", "/k:key"); logger.AssertWarningsLogged(1); // Should be warned once about the missing "begin" / "end" logger.AssertSingleWarningExists(ArgumentProcessor.BeginVerb, ArgumentProcessor.EndVerb); mockUpdater.AssertUpdateAttempted(); mockUpdater.AssertVersionChecked(); string logPath = DummyExeHelper.AssertDummyPreProcLogExists(binDir, this.TestContext); DummyExeHelper.AssertExpectedLogContents(logPath, "/v:version", "/n:name", "/k:key", "/s:" + defaultPropertiesFilePath); DummyExeHelper.AssertDummyPostProcLogDoesNotExist(binDir); // Call the post-process (no arguments) logger = CheckExecutionSucceeds(mockUpdater); logPath = DummyExeHelper.AssertDummyPostProcLogExists(binDir, this.TestContext); DummyExeHelper.AssertExpectedLogContents(logPath, null); logger.AssertWarningsLogged(1); // Should be warned once about the missing "begin" / "end" logger.AssertSingleWarningExists(ArgumentProcessor.BeginVerb, ArgumentProcessor.EndVerb); } finally { File.Delete(defaultPropertiesFilePath); } } }