diff --git a/src/Test/L0/Worker/Handlers/ScriptHandlerL0.cs b/src/Test/L0/Worker/Handlers/ScriptHandlerL0.cs index fd3ce5cf5..7b2396c0c 100644 --- a/src/Test/L0/Worker/Handlers/ScriptHandlerL0.cs +++ b/src/Test/L0/Worker/Handlers/ScriptHandlerL0.cs @@ -35,8 +35,9 @@ namespace GitHub.Runner.Common.Tests.Worker.Handlers Assert.True(quotedPath.StartsWith("\"") && quotedPath.EndsWith("\""), "Fixed path should be properly quoted"); Assert.Contains("path with spaces", quotedPath, StringComparison.Ordinal); - // Verify the specific scenario that was failing - Assert.Equal("\"/path with spaces/_temp/test-script.sh\"", quotedPath); + // Verify the path is properly quoted (platform-agnostic check) + Assert.True(quotedPath.StartsWith("\"/path with spaces/_temp"), "Path should start with quoted temp directory"); + Assert.True(quotedPath.EndsWith("test-script.sh\""), "Path should end with quoted script name"); } [Fact] @@ -51,9 +52,90 @@ namespace GitHub.Runner.Common.Tests.Worker.Handlers var quotedPath = $"\"{pathWithQuotes.Replace("\"", "\\\"")}\""; // Assert - Assert.Equal("\"/path/\\\"quoted folder\\\"/script.sh\"", quotedPath); Assert.True(quotedPath.StartsWith("\"") && quotedPath.EndsWith("\""), "Path should be wrapped in quotes"); Assert.Contains("\\\"", quotedPath, StringComparison.Ordinal); + Assert.Contains("quoted folder", quotedPath, StringComparison.Ordinal); + + // Verify quotes are properly escaped + Assert.Contains("\\\"quoted folder\\\"", quotedPath, StringComparison.Ordinal); + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Worker")] + public void ScriptPath_ActionsRunnerWithSpaces_ShouldBeQuoted() + { + // Arrange - Test the specific real-world scenario that was failing + var runnerPathWithSpaces = "/Users/user/Downloads/actions-runner-osx-arm64-2.328.0 2"; + var tempPath = Path.Combine(runnerPathWithSpaces, "_work", "_temp"); + var scriptPath = Path.Combine(tempPath, "script-guid.sh"); + + // Test our fix + var quotedPath = $"\"{scriptPath.Replace("\"", "\\\"")}\""; + + // Assert + Assert.True(quotedPath.StartsWith("\"") && quotedPath.EndsWith("\""), "Path should be wrapped in quotes"); + Assert.Contains("actions-runner-osx-arm64-2.328.0 2", quotedPath, StringComparison.Ordinal); + Assert.Contains("_work", quotedPath, StringComparison.Ordinal); + Assert.Contains("_temp", quotedPath, StringComparison.Ordinal); + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Worker")] + public void ScriptPath_MultipleSpaces_ShouldBeQuoted() + { + // Arrange - Test paths with multiple spaces + var pathWithMultipleSpaces = "/path/with multiple spaces/script.sh"; + + // Test our fix + var quotedPath = $"\"{pathWithMultipleSpaces.Replace("\"", "\\\"")}\""; + + // Assert + Assert.True(quotedPath.StartsWith("\"") && quotedPath.EndsWith("\""), "Path should be wrapped in quotes"); + Assert.Contains("multiple spaces", quotedPath, StringComparison.Ordinal); + } + + [Fact] + [Trait("Level", "L0")] + [Trait("Category", "Worker")] + public void ScriptPath_WithoutSpaces_ShouldStillBeQuoted() + { + // Arrange - Test normal paths without spaces (regression test) + var normalPath = "/home/user/runner/_work/_temp/script.sh"; + + // Test our fix + var quotedPath = $"\"{normalPath.Replace("\"", "\\\"")}\""; + + // Assert + Assert.True(quotedPath.StartsWith("\"") && quotedPath.EndsWith("\""), "Path should be wrapped in quotes"); + Assert.Equal($"\"{normalPath}\"", quotedPath); + } + + [Theory] + [Trait("Level", "L0")] + [Trait("Category", "Worker")] + [InlineData("/path with spaces/script.sh")] + [InlineData("/Users/user/Downloads/actions-runner-osx-arm64-2.328.0 2/_work/_temp/guid.sh")] + [InlineData("C:\\Program Files\\GitHub Runner\\script.cmd")] + [InlineData("/path/\"with quotes\"/script.sh")] + [InlineData("/path/with'single'quotes/script.sh")] + public void ScriptPath_VariousScenarios_ShouldBeProperlyQuoted(string inputPath) + { + // Arrange & Act + var quotedPath = $"\"{inputPath.Replace("\"", "\\\"")}\""; + + // Assert + Assert.True(quotedPath.StartsWith("\""), "Path should start with quote"); + Assert.True(quotedPath.EndsWith("\""), "Path should end with quote"); + + // Ensure the original path content is preserved + var unquotedContent = quotedPath.Substring(1, quotedPath.Length - 2); + if (inputPath.Contains("\"")) + { + // If original had quotes, they should be escaped in the result + Assert.Contains("\\\"", unquotedContent); + } } } } \ No newline at end of file