mirror of
https://github.com/actions/runner.git
synced 2025-12-11 04:46:58 +00:00
commands translate file path from container action (#331)
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using GitHub.DistributedTask.Pipelines;
|
using GitHub.DistributedTask.Pipelines;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Common.Util;
|
using GitHub.Runner.Common.Util;
|
||||||
|
using GitHub.Runner.Worker.Container;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -15,14 +16,14 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
void EnablePluginInternalCommand();
|
void EnablePluginInternalCommand();
|
||||||
void DisablePluginInternalCommand();
|
void DisablePluginInternalCommand();
|
||||||
bool TryProcessCommand(IExecutionContext context, string input);
|
bool TryProcessCommand(IExecutionContext context, string input, ContainerInfo container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class ActionCommandManager : RunnerService, IActionCommandManager
|
public sealed class ActionCommandManager : RunnerService, IActionCommandManager
|
||||||
{
|
{
|
||||||
private const string _stopCommand = "stop-commands";
|
private const string _stopCommand = "stop-commands";
|
||||||
private readonly Dictionary<string, IActionCommandExtension> _commandExtensions = new Dictionary<string, IActionCommandExtension>(StringComparer.OrdinalIgnoreCase);
|
private readonly Dictionary<string, IActionCommandExtension> _commandExtensions = new Dictionary<string, IActionCommandExtension>(StringComparer.OrdinalIgnoreCase);
|
||||||
private HashSet<string> _registeredCommands = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
private readonly HashSet<string> _registeredCommands = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
private readonly object _commandSerializeLock = new object();
|
private readonly object _commandSerializeLock = new object();
|
||||||
private bool _stopProcessCommand = false;
|
private bool _stopProcessCommand = false;
|
||||||
private string _stopToken = null;
|
private string _stopToken = null;
|
||||||
@@ -58,7 +59,7 @@ namespace GitHub.Runner.Worker
|
|||||||
_registeredCommands.Remove("internal-set-repo-path");
|
_registeredCommands.Remove("internal-set-repo-path");
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryProcessCommand(IExecutionContext context, string input)
|
public bool TryProcessCommand(IExecutionContext context, string input, ContainerInfo container)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(input))
|
if (string.IsNullOrEmpty(input))
|
||||||
{
|
{
|
||||||
@@ -114,7 +115,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
extension.ProcessCommand(context, input, actionCommand);
|
extension.ProcessCommand(context, input, actionCommand, container);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -140,7 +141,7 @@ namespace GitHub.Runner.Worker
|
|||||||
string Command { get; }
|
string Command { get; }
|
||||||
bool OmitEcho { get; }
|
bool OmitEcho { get; }
|
||||||
|
|
||||||
void ProcessCommand(IExecutionContext context, string line, ActionCommand command);
|
void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class InternalPluginSetRepoPathCommandExtension : RunnerService, IActionCommandExtension
|
public sealed class InternalPluginSetRepoPathCommandExtension : RunnerService, IActionCommandExtension
|
||||||
@@ -150,7 +151,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
if (!command.Properties.TryGetValue(SetRepoPathCommandProperties.repoFullName, out string repoFullName) || string.IsNullOrEmpty(repoFullName))
|
if (!command.Properties.TryGetValue(SetRepoPathCommandProperties.repoFullName, out string repoFullName) || string.IsNullOrEmpty(repoFullName))
|
||||||
{
|
{
|
||||||
@@ -180,7 +181,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
if (!command.Properties.TryGetValue(SetEnvCommandProperties.Name, out string envName) || string.IsNullOrEmpty(envName))
|
if (!command.Properties.TryGetValue(SetEnvCommandProperties.Name, out string envName) || string.IsNullOrEmpty(envName))
|
||||||
{
|
{
|
||||||
@@ -205,7 +206,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
if (!command.Properties.TryGetValue(SetOutputCommandProperties.Name, out string outputName) || string.IsNullOrEmpty(outputName))
|
if (!command.Properties.TryGetValue(SetOutputCommandProperties.Name, out string outputName) || string.IsNullOrEmpty(outputName))
|
||||||
{
|
{
|
||||||
@@ -229,7 +230,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
if (!command.Properties.TryGetValue(SaveStateCommandProperties.Name, out string stateName) || string.IsNullOrEmpty(stateName))
|
if (!command.Properties.TryGetValue(SaveStateCommandProperties.Name, out string stateName) || string.IsNullOrEmpty(stateName))
|
||||||
{
|
{
|
||||||
@@ -253,7 +254,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(command.Data))
|
if (string.IsNullOrWhiteSpace(command.Data))
|
||||||
{
|
{
|
||||||
@@ -279,7 +280,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
ArgUtil.NotNullOrEmpty(command.Data, "path");
|
ArgUtil.NotNullOrEmpty(command.Data, "path");
|
||||||
context.PrependPath.RemoveAll(x => string.Equals(x, command.Data, StringComparison.CurrentCulture));
|
context.PrependPath.RemoveAll(x => string.Equals(x, command.Data, StringComparison.CurrentCulture));
|
||||||
@@ -294,7 +295,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
var file = command.Data;
|
var file = command.Data;
|
||||||
|
|
||||||
@@ -306,9 +307,9 @@ namespace GitHub.Runner.Worker
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Translate file path back from container path
|
// Translate file path back from container path
|
||||||
if (context.Container != null)
|
if (container != null)
|
||||||
{
|
{
|
||||||
file = context.Container.TranslateToHostPath(file);
|
file = container.TranslateToHostPath(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Root the path
|
// Root the path
|
||||||
@@ -341,7 +342,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
command.Properties.TryGetValue(RemoveMatcherCommandProperties.Owner, out string owner);
|
command.Properties.TryGetValue(RemoveMatcherCommandProperties.Owner, out string owner);
|
||||||
var file = command.Data;
|
var file = command.Data;
|
||||||
@@ -369,9 +370,9 @@ namespace GitHub.Runner.Worker
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Translate file path back from container path
|
// Translate file path back from container path
|
||||||
if (context.Container != null)
|
if (container != null)
|
||||||
{
|
{
|
||||||
file = context.Container.TranslateToHostPath(file);
|
file = container.TranslateToHostPath(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Root the path
|
// Root the path
|
||||||
@@ -409,7 +410,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
context.Debug(command.Data);
|
context.Debug(command.Data);
|
||||||
}
|
}
|
||||||
@@ -437,7 +438,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string inputLine, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
command.Properties.TryGetValue(IssueCommandProperties.File, out string file);
|
command.Properties.TryGetValue(IssueCommandProperties.File, out string file);
|
||||||
command.Properties.TryGetValue(IssueCommandProperties.Line, out string line);
|
command.Properties.TryGetValue(IssueCommandProperties.Line, out string line);
|
||||||
@@ -454,10 +455,10 @@ namespace GitHub.Runner.Worker
|
|||||||
{
|
{
|
||||||
issue.Category = "Code";
|
issue.Category = "Code";
|
||||||
|
|
||||||
if (context.Container != null)
|
if (container != null)
|
||||||
{
|
{
|
||||||
// Translate file path back from container path
|
// Translate file path back from container path
|
||||||
file = context.Container.TranslateToHostPath(file);
|
file = container.TranslateToHostPath(file);
|
||||||
command.Properties[IssueCommandProperties.File] = file;
|
command.Properties[IssueCommandProperties.File] = file;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,7 +518,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
var data = this is GroupCommandExtension ? command.Data : string.Empty;
|
var data = this is GroupCommandExtension ? command.Data : string.Empty;
|
||||||
context.Output($"##[{Command}]{data}");
|
context.Output($"##[{Command}]{data}");
|
||||||
@@ -531,7 +532,7 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public Type ExtensionType => typeof(IActionCommandExtension);
|
public Type ExtensionType => typeof(IActionCommandExtension);
|
||||||
|
|
||||||
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command)
|
public void ProcessCommand(IExecutionContext context, string line, ActionCommand command, ContainerInfo container)
|
||||||
{
|
{
|
||||||
ArgUtil.NotNullOrEmpty(command.Data, "value");
|
ArgUtil.NotNullOrEmpty(command.Data, "value");
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ namespace GitHub.Runner.Worker.Handlers
|
|||||||
{
|
{
|
||||||
// This does not need to be inside of a critical section.
|
// This does not need to be inside of a critical section.
|
||||||
// The logging queues and command handlers are thread-safe.
|
// The logging queues and command handlers are thread-safe.
|
||||||
if (_commandManager.TryProcessCommand(_executionContext, line))
|
if (_commandManager.TryProcessCommand(_executionContext, line, _container))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using GitHub.DistributedTask.WebApi;
|
using GitHub.DistributedTask.WebApi;
|
||||||
using GitHub.Runner.Worker;
|
using GitHub.Runner.Worker;
|
||||||
|
using GitHub.Runner.Worker.Container;
|
||||||
using Moq;
|
using Moq;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
@@ -11,47 +13,35 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
{
|
{
|
||||||
public sealed class ActionCommandManagerL0
|
public sealed class ActionCommandManagerL0
|
||||||
{
|
{
|
||||||
|
private ActionCommandManager _commandManager;
|
||||||
|
private Mock<IExecutionContext> _ec;
|
||||||
|
private Mock<IExtensionManager> _extensionManager;
|
||||||
|
private Mock<IPipelineDirectoryManager> _pipelineDirectoryManager;
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void EnablePluginInternalCommand()
|
public void EnablePluginInternalCommand()
|
||||||
{
|
{
|
||||||
using (TestHostContext _hc = new TestHostContext(this))
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
var extensionManger = new Mock<IExtensionManager>();
|
|
||||||
var directoryManager = new Mock<IPipelineDirectoryManager>();
|
|
||||||
|
|
||||||
var pluginCommand = new InternalPluginSetRepoPathCommandExtension();
|
|
||||||
pluginCommand.Initialize(_hc);
|
|
||||||
|
|
||||||
var envCommand = new SetEnvCommandExtension();
|
|
||||||
envCommand.Initialize(_hc);
|
|
||||||
|
|
||||||
extensionManger.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
|
||||||
.Returns(new List<IActionCommandExtension>() { pluginCommand, envCommand });
|
|
||||||
_hc.SetSingleton<IExtensionManager>(extensionManger.Object);
|
|
||||||
_hc.SetSingleton<IPipelineDirectoryManager>(directoryManager.Object);
|
|
||||||
|
|
||||||
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
_hc.GetTrace().Info($"{tag} {line}");
|
hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
||||||
.Callback((Issue issue, string message) =>
|
.Callback((Issue issue, string message) =>
|
||||||
{
|
{
|
||||||
_hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
||||||
});
|
});
|
||||||
ActionCommandManager commandManager = new ActionCommandManager();
|
|
||||||
commandManager.Initialize(_hc);
|
|
||||||
|
|
||||||
commandManager.EnablePluginInternalCommand();
|
_commandManager.EnablePluginInternalCommand();
|
||||||
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath"));
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath", null));
|
||||||
|
|
||||||
directoryManager.Verify(x => x.UpdateRepositoryDirectory(_ec.Object, "actions/runner", "somepath", true), Times.Once);
|
_pipelineDirectoryManager.Verify(x => x.UpdateRepositoryDirectory(_ec.Object, "actions/runner", "somepath", true), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,47 +50,29 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void DisablePluginInternalCommand()
|
public void DisablePluginInternalCommand()
|
||||||
{
|
{
|
||||||
using (TestHostContext _hc = new TestHostContext(this))
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
var extensionManger = new Mock<IExtensionManager>();
|
|
||||||
var directoryManager = new Mock<IPipelineDirectoryManager>();
|
|
||||||
|
|
||||||
var pluginCommand = new InternalPluginSetRepoPathCommandExtension();
|
|
||||||
pluginCommand.Initialize(_hc);
|
|
||||||
|
|
||||||
var envCommand = new SetEnvCommandExtension();
|
|
||||||
envCommand.Initialize(_hc);
|
|
||||||
|
|
||||||
extensionManger.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
|
||||||
.Returns(new List<IActionCommandExtension>() { pluginCommand, envCommand });
|
|
||||||
|
|
||||||
_hc.SetSingleton<IExtensionManager>(extensionManger.Object);
|
|
||||||
_hc.SetSingleton<IPipelineDirectoryManager>(directoryManager.Object);
|
|
||||||
|
|
||||||
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
_hc.GetTrace().Info($"{tag} {line}");
|
hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
||||||
.Callback((Issue issue, string message) =>
|
.Callback((Issue issue, string message) =>
|
||||||
{
|
{
|
||||||
_hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
||||||
});
|
});
|
||||||
ActionCommandManager commandManager = new ActionCommandManager();
|
|
||||||
commandManager.Initialize(_hc);
|
|
||||||
|
|
||||||
commandManager.EnablePluginInternalCommand();
|
_commandManager.EnablePluginInternalCommand();
|
||||||
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath"));
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath", null));
|
||||||
|
|
||||||
commandManager.DisablePluginInternalCommand();
|
_commandManager.DisablePluginInternalCommand();
|
||||||
|
|
||||||
Assert.False(commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath"));
|
Assert.False(_commandManager.TryProcessCommand(_ec.Object, "##[internal-set-repo-path repoFullName=actions/runner;workspaceRepo=true]somepath", null));
|
||||||
|
|
||||||
directoryManager.Verify(x => x.UpdateRepositoryDirectory(_ec.Object, "actions/runner", "somepath", true), Times.Once);
|
_pipelineDirectoryManager.Verify(x => x.UpdateRepositoryDirectory(_ec.Object, "actions/runner", "somepath", true), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,42 +81,27 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void StopProcessCommand()
|
public void StopProcessCommand()
|
||||||
{
|
{
|
||||||
using (TestHostContext _hc = new TestHostContext(this))
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
var extensionManger = new Mock<IExtensionManager>();
|
|
||||||
var pluginCommand = new InternalPluginSetRepoPathCommandExtension();
|
|
||||||
pluginCommand.Initialize(_hc);
|
|
||||||
|
|
||||||
var envCommand = new SetEnvCommandExtension();
|
|
||||||
envCommand.Initialize(_hc);
|
|
||||||
|
|
||||||
extensionManger.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
|
||||||
.Returns(new List<IActionCommandExtension>() { pluginCommand, envCommand });
|
|
||||||
_hc.SetSingleton<IExtensionManager>(extensionManger.Object);
|
|
||||||
|
|
||||||
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
_hc.GetTrace().Info($"{tag} {line}");
|
hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
_ec.Setup(x => x.AddIssue(It.IsAny<Issue>(), It.IsAny<string>()))
|
||||||
.Callback((Issue issue, string message) =>
|
.Callback((Issue issue, string message) =>
|
||||||
{
|
{
|
||||||
_hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
hc.GetTrace().Info($"{issue.Type} {issue.Message} {message ?? string.Empty}");
|
||||||
});
|
});
|
||||||
|
|
||||||
_ec.Setup(x => x.EnvironmentVariables).Returns(new Dictionary<string, string>());
|
_ec.Setup(x => x.EnvironmentVariables).Returns(new Dictionary<string, string>());
|
||||||
|
|
||||||
ActionCommandManager commandManager = new ActionCommandManager();
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[stop-commands]stopToken", null));
|
||||||
commandManager.Initialize(_hc);
|
Assert.False(_commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar", null));
|
||||||
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[stopToken]", null));
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[stop-commands]stopToken"));
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar", null));
|
||||||
Assert.False(commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar"));
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[stopToken]"));
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "##[set-env name=foo]bar"));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,41 +110,29 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void EchoProcessCommand()
|
public void EchoProcessCommand()
|
||||||
{
|
{
|
||||||
using (TestHostContext _hc = new TestHostContext(this))
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
var extensionManager = new Mock<IExtensionManager>();
|
|
||||||
var echoCommand = new EchoCommandExtension();
|
|
||||||
echoCommand.Initialize(_hc);
|
|
||||||
|
|
||||||
extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
|
||||||
.Returns(new List<IActionCommandExtension>() { echoCommand });
|
|
||||||
_hc.SetSingleton<IExtensionManager>(extensionManager.Object);
|
|
||||||
|
|
||||||
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
_hc.GetTrace().Info($"{tag} {line}");
|
hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
_ec.SetupAllProperties();
|
_ec.SetupAllProperties();
|
||||||
|
|
||||||
ActionCommandManager commandManager = new ActionCommandManager();
|
|
||||||
commandManager.Initialize(_hc);
|
|
||||||
|
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::on"));
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::on", null));
|
||||||
Assert.True(_ec.Object.EchoOnActionCommand);
|
Assert.True(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::off"));
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::off", null));
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::ON"));
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::ON", null));
|
||||||
Assert.True(_ec.Object.EchoOnActionCommand);
|
Assert.True(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::Off "));
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::Off ", null));
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,7 +142,7 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void EchoProcessCommandDebugOn()
|
public void EchoProcessCommandDebugOn()
|
||||||
{
|
{
|
||||||
using (TestHostContext _hc = new TestHostContext(this))
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
// Set up a few things
|
// Set up a few things
|
||||||
// 1. Job request message (with ACTIONS_STEP_DEBUG = true)
|
// 1. Job request message (with ACTIONS_STEP_DEBUG = true)
|
||||||
@@ -219,84 +164,135 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
var jobServerQueue = new Mock<IJobServerQueue>();
|
var jobServerQueue = new Mock<IJobServerQueue>();
|
||||||
jobServerQueue.Setup(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.IsAny<TimelineRecord>()));
|
jobServerQueue.Setup(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.IsAny<TimelineRecord>()));
|
||||||
|
|
||||||
_hc.SetSingleton(jobServerQueue.Object);
|
hc.SetSingleton(jobServerQueue.Object);
|
||||||
|
|
||||||
var extensionManager = new Mock<IExtensionManager>();
|
|
||||||
var echoCommand = new EchoCommandExtension();
|
|
||||||
echoCommand.Initialize(_hc);
|
|
||||||
|
|
||||||
extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
|
||||||
.Returns(new List<IActionCommandExtension>() { echoCommand });
|
|
||||||
_hc.SetSingleton<IExtensionManager>(extensionManager.Object);
|
|
||||||
|
|
||||||
var configurationStore = new Mock<IConfigurationStore>();
|
var configurationStore = new Mock<IConfigurationStore>();
|
||||||
configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings());
|
configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings());
|
||||||
_hc.SetSingleton(configurationStore.Object);
|
hc.SetSingleton(configurationStore.Object);
|
||||||
|
|
||||||
var pagingLogger = new Mock<IPagingLogger>();
|
var pagingLogger = new Mock<IPagingLogger>();
|
||||||
_hc.EnqueueInstance(pagingLogger.Object);
|
hc.EnqueueInstance(pagingLogger.Object);
|
||||||
|
|
||||||
ActionCommandManager commandManager = new ActionCommandManager();
|
|
||||||
commandManager.Initialize(_hc);
|
|
||||||
|
|
||||||
var _ec = new Runner.Worker.ExecutionContext();
|
|
||||||
_ec.Initialize(_hc);
|
|
||||||
|
|
||||||
// Initialize the job (to exercise logic that sets EchoOnActionCommand)
|
// Initialize the job (to exercise logic that sets EchoOnActionCommand)
|
||||||
_ec.InitializeJob(jobRequest, System.Threading.CancellationToken.None);
|
var ec = new Runner.Worker.ExecutionContext();
|
||||||
|
ec.Initialize(hc);
|
||||||
|
ec.InitializeJob(jobRequest, System.Threading.CancellationToken.None);
|
||||||
|
|
||||||
_ec.Complete();
|
ec.Complete();
|
||||||
|
|
||||||
Assert.True(_ec.EchoOnActionCommand);
|
Assert.True(ec.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec, "::echo::off"));
|
Assert.True(_commandManager.TryProcessCommand(ec, "::echo::off", null));
|
||||||
Assert.False(_ec.EchoOnActionCommand);
|
Assert.False(ec.EchoOnActionCommand);
|
||||||
|
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec, "::echo::on"));
|
Assert.True(_commandManager.TryProcessCommand(ec, "::echo::on", null));
|
||||||
Assert.True(_ec.EchoOnActionCommand);
|
Assert.True(ec.EchoOnActionCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Worker")]
|
[Trait("Category", "Worker")]
|
||||||
public void EchoProcessCommandInvalid()
|
public void EchoProcessCommandInvalid()
|
||||||
{
|
{
|
||||||
using (TestHostContext _hc = new TestHostContext(this))
|
using (TestHostContext hc = CreateTestContext())
|
||||||
{
|
{
|
||||||
var extensionManager = new Mock<IExtensionManager>();
|
|
||||||
var echoCommand = new EchoCommandExtension();
|
|
||||||
echoCommand.Initialize(_hc);
|
|
||||||
|
|
||||||
extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
|
||||||
.Returns(new List<IActionCommandExtension>() { echoCommand });
|
|
||||||
_hc.SetSingleton<IExtensionManager>(extensionManager.Object);
|
|
||||||
|
|
||||||
Mock<IExecutionContext> _ec = new Mock<IExecutionContext>();
|
|
||||||
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
|
||||||
.Returns((string tag, string line) =>
|
.Returns((string tag, string line) =>
|
||||||
{
|
{
|
||||||
_hc.GetTrace().Info($"{tag} {line}");
|
hc.GetTrace().Info($"{tag} {line}");
|
||||||
return 1;
|
return 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
_ec.SetupAllProperties();
|
_ec.SetupAllProperties();
|
||||||
|
|
||||||
ActionCommandManager commandManager = new ActionCommandManager();
|
|
||||||
commandManager.Initialize(_hc);
|
|
||||||
|
|
||||||
// Echo commands below are considered "processed", but are invalid
|
// Echo commands below are considered "processed", but are invalid
|
||||||
// 1. Invalid echo value
|
// 1. Invalid echo value
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::invalid"));
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::invalid", null));
|
||||||
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
|
|
||||||
// 2. No value
|
// 2. No value
|
||||||
Assert.True(commandManager.TryProcessCommand(_ec.Object, "::echo::"));
|
Assert.True(_commandManager.TryProcessCommand(_ec.Object, "::echo::", null));
|
||||||
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
Assert.Equal(TaskResult.Failed, _ec.Object.CommandResult);
|
||||||
Assert.False(_ec.Object.EchoOnActionCommand);
|
Assert.False(_ec.Object.EchoOnActionCommand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Worker")]
|
||||||
|
public void AddMatcherTranslatesFilePath()
|
||||||
|
{
|
||||||
|
using (TestHostContext hc = CreateTestContext())
|
||||||
|
{
|
||||||
|
// Create a problem matcher config file
|
||||||
|
var hostDirectory = hc.GetDirectory(WellKnownDirectory.Temp);
|
||||||
|
var hostFile = Path.Combine(hostDirectory, "my-matcher.json");
|
||||||
|
Directory.CreateDirectory(hostDirectory);
|
||||||
|
var content = @"
|
||||||
|
{
|
||||||
|
""problemMatcher"": [
|
||||||
|
{
|
||||||
|
""owner"": ""my-matcher"",
|
||||||
|
""pattern"": [
|
||||||
|
{
|
||||||
|
""regexp"": ""^ERROR: (.+)$"",
|
||||||
|
""message"": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}";
|
||||||
|
File.WriteAllText(hostFile, content);
|
||||||
|
|
||||||
|
// Setup translation info
|
||||||
|
var container = new ContainerInfo();
|
||||||
|
var containerDirectory = "/some-container-directory";
|
||||||
|
var containerFile = Path.Combine(containerDirectory, "my-matcher.json");
|
||||||
|
container.AddPathTranslateMapping(hostDirectory, containerDirectory);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
_commandManager.TryProcessCommand(_ec.Object, $"::add-matcher::{containerFile}", container);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
_ec.Verify(x => x.AddMatchers(It.IsAny<IssueMatchersConfig>()), Times.Once);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private TestHostContext CreateTestContext([CallerMemberName] string testName = "")
|
||||||
|
{
|
||||||
|
var hostContext = new TestHostContext(this, testName);
|
||||||
|
|
||||||
|
// Mock extension manager
|
||||||
|
_extensionManager = new Mock<IExtensionManager>();
|
||||||
|
var commands = new IActionCommandExtension[]
|
||||||
|
{
|
||||||
|
new AddMatcherCommandExtension(),
|
||||||
|
new EchoCommandExtension(),
|
||||||
|
new InternalPluginSetRepoPathCommandExtension(),
|
||||||
|
new SetEnvCommandExtension(),
|
||||||
|
};
|
||||||
|
foreach (var command in commands)
|
||||||
|
{
|
||||||
|
command.Initialize(hostContext);
|
||||||
|
}
|
||||||
|
_extensionManager.Setup(x => x.GetExtensions<IActionCommandExtension>())
|
||||||
|
.Returns(new List<IActionCommandExtension>(commands));
|
||||||
|
hostContext.SetSingleton<IExtensionManager>(_extensionManager.Object);
|
||||||
|
|
||||||
|
// Mock pipeline directory manager
|
||||||
|
_pipelineDirectoryManager = new Mock<IPipelineDirectoryManager>();
|
||||||
|
hostContext.SetSingleton<IPipelineDirectoryManager>(_pipelineDirectoryManager.Object);
|
||||||
|
|
||||||
|
// Execution context
|
||||||
|
_ec = new Mock<IExecutionContext>();
|
||||||
|
|
||||||
|
// Command manager
|
||||||
|
_commandManager = new ActionCommandManager();
|
||||||
|
_commandManager.Initialize(hostContext);
|
||||||
|
|
||||||
|
return hostContext;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -973,8 +973,8 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
});
|
});
|
||||||
|
|
||||||
_commandManager = new Mock<IActionCommandManager>();
|
_commandManager = new Mock<IActionCommandManager>();
|
||||||
_commandManager.Setup(x => x.TryProcessCommand(It.IsAny<IExecutionContext>(), It.IsAny<string>()))
|
_commandManager.Setup(x => x.TryProcessCommand(It.IsAny<IExecutionContext>(), It.IsAny<string>(), It.IsAny<ContainerInfo>()))
|
||||||
.Returns((IExecutionContext executionContext, string line) =>
|
.Returns((IExecutionContext executionContext, string line, ContainerInfo container) =>
|
||||||
{
|
{
|
||||||
if (line.IndexOf("##[some-command]") >= 0)
|
if (line.IndexOf("##[some-command]") >= 0)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user