mirror of
https://github.com/actions/runner.git
synced 2025-12-10 12:36:23 +00:00
Runner cleanup - continuation (#209)
* Agent/AgentCredential -> Runner/RunnerCredential * Test trait rename: Agent -> Runner * Enable remaining RunnerL0 tests * Remove job message PII variable masking code * Remove unused Agent.ToolsDirectory variable * Misc test Agent -> Runner renaming * Some more misc cleaning
This commit is contained in:
@@ -208,14 +208,6 @@ namespace GitHub.Runner.Common
|
|||||||
public static readonly string StepDebug = "ACTIONS_STEP_DEBUG";
|
public static readonly string StepDebug = "ACTIONS_STEP_DEBUG";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Agent
|
|
||||||
{
|
|
||||||
//
|
|
||||||
// Keep alphabetical
|
|
||||||
//
|
|
||||||
public static readonly string ToolsDirectory = "agent.ToolsDirectory";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class System
|
public static class System
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -190,25 +190,6 @@ namespace GitHub.Runner.Listener
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !OS_WINDOWS
|
|
||||||
// Fix the work folder setting on Linux
|
|
||||||
if (settings.WorkFolder.Contains("vsts", StringComparison.OrdinalIgnoreCase))
|
|
||||||
{
|
|
||||||
var workFolder = "/runner/work";
|
|
||||||
var unix = HostContext.GetService<IUnixUtil>();
|
|
||||||
|
|
||||||
// create new work folder /runner/work
|
|
||||||
await unix.ExecAsync(HostContext.GetDirectory(WellKnownDirectory.Root), "sh", $"-c \"sudo mkdir -p {workFolder}\"");
|
|
||||||
|
|
||||||
// fix permission
|
|
||||||
await unix.ExecAsync(HostContext.GetDirectory(WellKnownDirectory.Root), "sh", $"-c \"sudo chown -R $USER {workFolder}\"");
|
|
||||||
|
|
||||||
// update settings
|
|
||||||
settings.WorkFolder = workFolder;
|
|
||||||
store.SaveSettings(settings);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Trace.Info($"Set runner startup type - {startType}");
|
Trace.Info($"Set runner startup type - {startType}");
|
||||||
HostContext.StartupType = startType;
|
HostContext.StartupType = startType;
|
||||||
|
|
||||||
@@ -75,36 +75,6 @@ namespace GitHub.Runner.Worker
|
|||||||
|
|
||||||
public string System_PhaseDisplayName => Get(Constants.Variables.System.PhaseDisplayName);
|
public string System_PhaseDisplayName => Get(Constants.Variables.System.PhaseDisplayName);
|
||||||
|
|
||||||
public string System_TFCollectionUrl => Get(WellKnownDistributedTaskVariables.TFCollectionUrl);
|
|
||||||
|
|
||||||
public static readonly HashSet<string> PiiVariables = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
|
|
||||||
{
|
|
||||||
"Build.AuthorizeAs",
|
|
||||||
"Build.QueuedBy",
|
|
||||||
"Build.RequestedFor",
|
|
||||||
"Build.RequestedForEmail",
|
|
||||||
"Build.SourceBranch",
|
|
||||||
"Build.SourceBranchName",
|
|
||||||
"Build.SourceTfvcShelveset",
|
|
||||||
"Build.SourceVersion",
|
|
||||||
"Build.SourceVersionAuthor",
|
|
||||||
"Job.AuthorizeAs",
|
|
||||||
"Release.Deployment.RequestedFor",
|
|
||||||
"Release.Deployment.RequestedForEmail",
|
|
||||||
"Release.RequestedFor",
|
|
||||||
"Release.RequestedForEmail",
|
|
||||||
};
|
|
||||||
|
|
||||||
public static readonly string PiiArtifactVariablePrefix = "Release.Artifacts";
|
|
||||||
|
|
||||||
public static readonly List<string> PiiArtifactVariableSuffixes = new List<string>()
|
|
||||||
{
|
|
||||||
"SourceBranch",
|
|
||||||
"SourceBranchName",
|
|
||||||
"SourceVersion",
|
|
||||||
"RequestedFor"
|
|
||||||
};
|
|
||||||
|
|
||||||
public string Get(string name)
|
public string Get(string name)
|
||||||
{
|
{
|
||||||
Variable variable;
|
Variable variable;
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ namespace GitHub.Runner.Worker
|
|||||||
SetCulture(jobMessage);
|
SetCulture(jobMessage);
|
||||||
|
|
||||||
// Start the job.
|
// Start the job.
|
||||||
Trace.Info($"Job message:{Environment.NewLine} {StringUtil.ConvertToJson(WorkerUtilities.ScrubPiiData(jobMessage))}");
|
Trace.Info($"Job message:{Environment.NewLine} {StringUtil.ConvertToJson(jobMessage)}");
|
||||||
Task<TaskResult> jobRunnerTask = jobRunner.RunAsync(jobMessage, jobRequestCancellationToken.Token);
|
Task<TaskResult> jobRunnerTask = jobRunner.RunAsync(jobMessage, jobRequestCancellationToken.Token);
|
||||||
|
|
||||||
// Start listening for a cancel message from the channel.
|
// Start listening for a cancel message from the channel.
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
using GitHub.DistributedTask.Pipelines.ContextData;
|
|
||||||
using GitHub.DistributedTask.WebApi;
|
|
||||||
using Pipelines = GitHub.DistributedTask.Pipelines;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using GitHub.Runner.Sdk;
|
|
||||||
|
|
||||||
namespace GitHub.Runner.Worker
|
|
||||||
{
|
|
||||||
public class WorkerUtilities
|
|
||||||
{
|
|
||||||
public static Pipelines.AgentJobRequestMessage ScrubPiiData(Pipelines.AgentJobRequestMessage message)
|
|
||||||
{
|
|
||||||
ArgUtil.NotNull(message, nameof(message));
|
|
||||||
|
|
||||||
var scrubbedVariables = new Dictionary<string, VariableValue>();
|
|
||||||
|
|
||||||
// Scrub the known PII variables
|
|
||||||
foreach (var variable in message.Variables)
|
|
||||||
{
|
|
||||||
if (Variables.PiiVariables.Contains(variable.Key) ||
|
|
||||||
(variable.Key.StartsWith(Variables.PiiArtifactVariablePrefix, StringComparison.OrdinalIgnoreCase)
|
|
||||||
&& Variables.PiiArtifactVariableSuffixes.Any(varSuffix => variable.Key.EndsWith(varSuffix, StringComparison.OrdinalIgnoreCase))))
|
|
||||||
{
|
|
||||||
scrubbedVariables[variable.Key] = "[PII]";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scrubbedVariables[variable.Key] = variable.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var scrubbedRepositories = new List<Pipelines.RepositoryResource>();
|
|
||||||
|
|
||||||
// Scrub the repository resources
|
|
||||||
foreach (var repository in message.Resources.Repositories)
|
|
||||||
{
|
|
||||||
Pipelines.RepositoryResource scrubbedRepository = repository.Clone();
|
|
||||||
|
|
||||||
var versionInfo = repository.Properties.Get<Pipelines.VersionInfo>(Pipelines.RepositoryPropertyNames.VersionInfo);
|
|
||||||
|
|
||||||
if (versionInfo != null)
|
|
||||||
{
|
|
||||||
scrubbedRepository.Properties.Set(
|
|
||||||
Pipelines.RepositoryPropertyNames.VersionInfo,
|
|
||||||
new Pipelines.VersionInfo()
|
|
||||||
{
|
|
||||||
Author = "[PII]",
|
|
||||||
Message = versionInfo.Message
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
scrubbedRepositories.Add(scrubbedRepository);
|
|
||||||
}
|
|
||||||
|
|
||||||
var scrubbedJobResources = new Pipelines.JobResources();
|
|
||||||
|
|
||||||
scrubbedJobResources.Containers.AddRange(message.Resources.Containers);
|
|
||||||
scrubbedJobResources.Endpoints.AddRange(message.Resources.Endpoints);
|
|
||||||
scrubbedJobResources.Repositories.AddRange(scrubbedRepositories);
|
|
||||||
scrubbedJobResources.SecureFiles.AddRange(message.Resources.SecureFiles);
|
|
||||||
|
|
||||||
var contextData = new DictionaryContextData();
|
|
||||||
if (message.ContextData?.Count > 0)
|
|
||||||
{
|
|
||||||
foreach (var pair in message.ContextData)
|
|
||||||
{
|
|
||||||
contextData[pair.Key] = pair.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reconstitute a new agent job request message from the scrubbed parts
|
|
||||||
return new Pipelines.AgentJobRequestMessage(
|
|
||||||
plan: message.Plan,
|
|
||||||
timeline: message.Timeline,
|
|
||||||
jobId: message.JobId,
|
|
||||||
jobDisplayName: message.JobDisplayName,
|
|
||||||
jobName: message.JobName,
|
|
||||||
jobContainer: message.JobContainer,
|
|
||||||
jobServiceContainers: message.JobServiceContainers,
|
|
||||||
environmentVariables: message.EnvironmentVariables,
|
|
||||||
variables: scrubbedVariables,
|
|
||||||
maskHints: message.MaskHints,
|
|
||||||
jobResources: scrubbedJobResources,
|
|
||||||
contextData: contextData,
|
|
||||||
workspaceOptions: message.Workspace,
|
|
||||||
steps: message.Steps,
|
|
||||||
scopes: message.Scopes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,7 +9,7 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public void BuildConstantGenerateSucceed()
|
public void BuildConstantGenerateSucceed()
|
||||||
{
|
{
|
||||||
List<string> validPackageNames = new List<string>()
|
List<string> validPackageNames = new List<string>()
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async Task EnsureDotnetsdkBashDownloadScriptUpToDate()
|
public async Task EnsureDotnetsdkBashDownloadScriptUpToDate()
|
||||||
{
|
{
|
||||||
string shDownloadUrl = "https://dot.net/v1/dotnet-install.sh";
|
string shDownloadUrl = "https://dot.net/v1/dotnet-install.sh";
|
||||||
@@ -33,7 +33,7 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async Task EnsureDotnetsdkPowershellDownloadScriptUpToDate()
|
public async Task EnsureDotnetsdkPowershellDownloadScriptUpToDate()
|
||||||
{
|
{
|
||||||
string ps1DownloadUrl = "https://dot.net/v1/dotnet-install.ps1";
|
string ps1DownloadUrl = "https://dot.net/v1/dotnet-install.ps1";
|
||||||
|
|||||||
@@ -1,574 +0,0 @@
|
|||||||
// using GitHub.DistributedTask.WebApi;
|
|
||||||
// using GitHub.Runner.Listener;
|
|
||||||
// using GitHub.Runner.Listener.Configuration;
|
|
||||||
// using Moq;
|
|
||||||
// using System;
|
|
||||||
// using System.Collections.Generic;
|
|
||||||
// using System.Threading;
|
|
||||||
// using System.Threading.Tasks;
|
|
||||||
// using Xunit;
|
|
||||||
// using GitHub.Services.WebApi;
|
|
||||||
// using Pipelines = GitHub.DistributedTask.Pipelines;
|
|
||||||
// using GitHub.Runner.Common.Util;
|
|
||||||
|
|
||||||
// namespace GitHub.Runner.Common.Tests.Listener
|
|
||||||
// {
|
|
||||||
// public sealed class AgentL0
|
|
||||||
// {
|
|
||||||
// private Mock<IConfigurationManager> _configurationManager;
|
|
||||||
// private Mock<IJobNotification> _jobNotification;
|
|
||||||
// private Mock<IMessageListener> _messageListener;
|
|
||||||
// private Mock<IPromptManager> _promptManager;
|
|
||||||
// private Mock<IJobDispatcher> _jobDispatcher;
|
|
||||||
// private Mock<IRunnerServer> _agentServer;
|
|
||||||
// private Mock<ITerminal> _term;
|
|
||||||
// private Mock<IConfigurationStore> _configStore;
|
|
||||||
// private Mock<IRunnerWebProxy> _proxy;
|
|
||||||
// private Mock<IRunnerCertificateManager> _cert;
|
|
||||||
// private Mock<ISelfUpdater> _updater;
|
|
||||||
|
|
||||||
// public AgentL0()
|
|
||||||
// {
|
|
||||||
// _configurationManager = new Mock<IConfigurationManager>();
|
|
||||||
// _jobNotification = new Mock<IJobNotification>();
|
|
||||||
// _messageListener = new Mock<IMessageListener>();
|
|
||||||
// _promptManager = new Mock<IPromptManager>();
|
|
||||||
// _jobDispatcher = new Mock<IJobDispatcher>();
|
|
||||||
// _agentServer = new Mock<IRunnerServer>();
|
|
||||||
// _term = new Mock<ITerminal>();
|
|
||||||
// _configStore = new Mock<IConfigurationStore>();
|
|
||||||
// _proxy = new Mock<IRunnerWebProxy>();
|
|
||||||
// _cert = new Mock<IRunnerCertificateManager>();
|
|
||||||
// _updater = new Mock<ISelfUpdater>();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private AgentJobRequestMessage CreateJobRequestMessage(string jobName)
|
|
||||||
// {
|
|
||||||
// TaskOrchestrationPlanReference plan = new TaskOrchestrationPlanReference();
|
|
||||||
// TimelineReference timeline = null;
|
|
||||||
// JobEnvironment environment = new JobEnvironment();
|
|
||||||
// List<TaskInstance> tasks = new List<TaskInstance>();
|
|
||||||
// Guid JobId = Guid.NewGuid();
|
|
||||||
// var jobRequest = new AgentJobRequestMessage(plan, timeline, JobId, jobName, jobName, environment, tasks);
|
|
||||||
// return jobRequest as AgentJobRequestMessage;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// private JobCancelMessage CreateJobCancelMessage()
|
|
||||||
// {
|
|
||||||
// var message = new JobCancelMessage(Guid.NewGuid(), TimeSpan.FromSeconds(0));
|
|
||||||
// return message;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Fact]
|
|
||||||
// [Trait("Level", "L0")]
|
|
||||||
// [Trait("Category", "Agent")]
|
|
||||||
// //process 2 new job messages, and one cancel message
|
|
||||||
// public async void TestRunAsync()
|
|
||||||
// {
|
|
||||||
// using (var hc = new TestHostContext(this))
|
|
||||||
// {
|
|
||||||
// //Arrange
|
|
||||||
// var agent = new Runner.Listener.Runner();
|
|
||||||
// hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
|
||||||
// hc.SetSingleton<IJobNotification>(_jobNotification.Object);
|
|
||||||
// hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
|
||||||
// hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
|
||||||
// hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
|
||||||
// hc.SetSingleton<IRunnerWebProxy>(_proxy.Object);
|
|
||||||
// hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
|
||||||
// hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
|
||||||
// agent.Initialize(hc);
|
|
||||||
// var settings = new RunnerSettings
|
|
||||||
// {
|
|
||||||
// PoolId = 43242
|
|
||||||
// };
|
|
||||||
|
|
||||||
// var message = new TaskAgentMessage()
|
|
||||||
// {
|
|
||||||
// Body = JsonUtility.ToString(CreateJobRequestMessage("job1")),
|
|
||||||
// MessageId = 4234,
|
|
||||||
// MessageType = JobRequestMessageTypes.AgentJobRequest
|
|
||||||
// };
|
|
||||||
|
|
||||||
// var messages = new Queue<TaskAgentMessage>();
|
|
||||||
// messages.Enqueue(message);
|
|
||||||
// var signalWorkerComplete = new SemaphoreSlim(0, 1);
|
|
||||||
// _configurationManager.Setup(x => x.LoadSettings())
|
|
||||||
// .Returns(settings);
|
|
||||||
// _configurationManager.Setup(x => x.IsConfigured())
|
|
||||||
// .Returns(true);
|
|
||||||
// _messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(Task.FromResult<bool>(true));
|
|
||||||
// _messageListener.Setup(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(async () =>
|
|
||||||
// {
|
|
||||||
// if (0 == messages.Count)
|
|
||||||
// {
|
|
||||||
// signalWorkerComplete.Release();
|
|
||||||
// await Task.Delay(2000, hc.RunnerShutdownToken);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return messages.Dequeue();
|
|
||||||
// });
|
|
||||||
// _messageListener.Setup(x => x.DeleteSessionAsync())
|
|
||||||
// .Returns(Task.CompletedTask);
|
|
||||||
// _messageListener.Setup(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()))
|
|
||||||
// .Returns(Task.CompletedTask);
|
|
||||||
// _jobDispatcher.Setup(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), It.IsAny<bool>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
|
|
||||||
// });
|
|
||||||
// _jobNotification.Setup(x => x.StartClient(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
|
|
||||||
// });
|
|
||||||
// _jobNotification.Setup(x => x.StartClient(It.IsAny<String>(), It.IsAny<String>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// hc.EnqueueInstance<IJobDispatcher>(_jobDispatcher.Object);
|
|
||||||
|
|
||||||
// _configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
|
|
||||||
// //Act
|
|
||||||
// var command = new CommandSettings(hc, new string[] { "run" });
|
|
||||||
// Task agentTask = agent.ExecuteCommand(command);
|
|
||||||
|
|
||||||
// //Assert
|
|
||||||
// //wait for the agent to run one job
|
|
||||||
// if (!await signalWorkerComplete.WaitAsync(2000))
|
|
||||||
// {
|
|
||||||
// Assert.True(false, $"{nameof(_messageListener.Object.GetNextMessageAsync)} was not invoked.");
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// //Act
|
|
||||||
// hc.ShutdownRunner(ShutdownReason.UserCancelled); //stop Agent
|
|
||||||
|
|
||||||
// //Assert
|
|
||||||
// Task[] taskToWait2 = { agentTask, Task.Delay(2000) };
|
|
||||||
// //wait for the Agent to exit
|
|
||||||
// await Task.WhenAny(taskToWait2);
|
|
||||||
|
|
||||||
// Assert.True(agentTask.IsCompleted, $"{nameof(agent.ExecuteCommand)} timed out.");
|
|
||||||
// Assert.True(!agentTask.IsFaulted, agentTask.Exception?.ToString());
|
|
||||||
// Assert.True(agentTask.IsCanceled);
|
|
||||||
|
|
||||||
// _jobDispatcher.Verify(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), It.IsAny<bool>()), Times.Once(),
|
|
||||||
// $"{nameof(_jobDispatcher.Object.Run)} was not invoked.");
|
|
||||||
// _messageListener.Verify(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()), Times.AtLeastOnce());
|
|
||||||
// _messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
|
||||||
// _messageListener.Verify(x => x.DeleteSessionAsync(), Times.Once());
|
|
||||||
// _messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()), Times.AtLeastOnce());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public static TheoryData<string[], bool, Times> RunAsServiceTestData = new TheoryData<string[], bool, Times>()
|
|
||||||
// {
|
|
||||||
// // staring with run command, configured as run as service, should start the agent
|
|
||||||
// { new [] { "run" }, true, Times.Once() },
|
|
||||||
// // starting with no argument, configured not to run as service, should start agent interactively
|
|
||||||
// { new [] { "run" }, false, Times.Once() }
|
|
||||||
// };
|
|
||||||
// [Theory]
|
|
||||||
// [MemberData("RunAsServiceTestData")]
|
|
||||||
// [Trait("Level", "L0")]
|
|
||||||
// [Trait("Category", "Agent")]
|
|
||||||
// public async void TestExecuteCommandForRunAsService(string[] args, bool configureAsService, Times expectedTimes)
|
|
||||||
// {
|
|
||||||
// using (var hc = new TestHostContext(this))
|
|
||||||
// {
|
|
||||||
// hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
|
||||||
// hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
|
||||||
// hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
|
||||||
// hc.SetSingleton<IRunnerWebProxy>(_proxy.Object);
|
|
||||||
// hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
|
||||||
// hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
|
||||||
|
|
||||||
// var command = new CommandSettings(hc, args);
|
|
||||||
|
|
||||||
// _configurationManager.Setup(x => x.IsConfigured()).Returns(true);
|
|
||||||
// _configurationManager.Setup(x => x.LoadSettings())
|
|
||||||
// .Returns(new RunnerSettings { });
|
|
||||||
|
|
||||||
// _configStore.Setup(x => x.IsServiceConfigured()).Returns(configureAsService);
|
|
||||||
|
|
||||||
// _messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(Task.FromResult(false));
|
|
||||||
|
|
||||||
// var agent = new Runner.Listener.Runner();
|
|
||||||
// agent.Initialize(hc);
|
|
||||||
// await agent.ExecuteCommand(command);
|
|
||||||
|
|
||||||
// _messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), expectedTimes);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Fact]
|
|
||||||
// [Trait("Level", "L0")]
|
|
||||||
// [Trait("Category", "Agent")]
|
|
||||||
// //process 2 new job messages, and one cancel message
|
|
||||||
// public async void TestMachineProvisionerCLI()
|
|
||||||
// {
|
|
||||||
// using (var hc = new TestHostContext(this))
|
|
||||||
// {
|
|
||||||
// hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
|
||||||
// hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
|
||||||
// hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
|
||||||
// hc.SetSingleton<IRunnerWebProxy>(_proxy.Object);
|
|
||||||
// hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
|
||||||
// hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
|
||||||
|
|
||||||
// var command = new CommandSettings(hc, new[] { "run" });
|
|
||||||
|
|
||||||
// _configurationManager.Setup(x => x.IsConfigured()).
|
|
||||||
// Returns(true);
|
|
||||||
// _configurationManager.Setup(x => x.LoadSettings())
|
|
||||||
// .Returns(new RunnerSettings { });
|
|
||||||
|
|
||||||
// _configStore.Setup(x => x.IsServiceConfigured())
|
|
||||||
// .Returns(false);
|
|
||||||
|
|
||||||
// _messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(Task.FromResult(false));
|
|
||||||
|
|
||||||
// var agent = new Runner.Listener.Runner();
|
|
||||||
// agent.Initialize(hc);
|
|
||||||
// await agent.ExecuteCommand(command);
|
|
||||||
|
|
||||||
// _messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Fact]
|
|
||||||
// [Trait("Level", "L0")]
|
|
||||||
// [Trait("Category", "Agent")]
|
|
||||||
// //process 2 new job messages, and one cancel message
|
|
||||||
// public async void TestMachineProvisionerCLICompat()
|
|
||||||
// {
|
|
||||||
// using (var hc = new TestHostContext(this))
|
|
||||||
// {
|
|
||||||
// hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
|
||||||
// hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
|
||||||
// hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
|
||||||
// hc.SetSingleton<IRunnerWebProxy>(_proxy.Object);
|
|
||||||
// hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
|
||||||
// hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
|
||||||
|
|
||||||
// var command = new CommandSettings(hc, new string[] { });
|
|
||||||
|
|
||||||
// _configurationManager.Setup(x => x.IsConfigured()).
|
|
||||||
// Returns(true);
|
|
||||||
// _configurationManager.Setup(x => x.LoadSettings())
|
|
||||||
// .Returns(new RunnerSettings { });
|
|
||||||
|
|
||||||
// _configStore.Setup(x => x.IsServiceConfigured())
|
|
||||||
// .Returns(false);
|
|
||||||
|
|
||||||
// _messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(Task.FromResult(false));
|
|
||||||
|
|
||||||
// var agent = new Runner.Listener.Runner();
|
|
||||||
// agent.Initialize(hc);
|
|
||||||
// await agent.ExecuteCommand(command);
|
|
||||||
|
|
||||||
// _messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Fact]
|
|
||||||
// [Trait("Level", "L0")]
|
|
||||||
// [Trait("Category", "Agent")]
|
|
||||||
// public async void TestRunOnce()
|
|
||||||
// {
|
|
||||||
// using (var hc = new TestHostContext(this))
|
|
||||||
// {
|
|
||||||
// //Arrange
|
|
||||||
// var agent = new Runner.Listener.Runner();
|
|
||||||
// hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
|
||||||
// hc.SetSingleton<IJobNotification>(_jobNotification.Object);
|
|
||||||
// hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
|
||||||
// hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
|
||||||
// hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
|
||||||
// hc.SetSingleton<IRunnerWebProxy>(_proxy.Object);
|
|
||||||
// hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
|
||||||
// hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
|
||||||
// agent.Initialize(hc);
|
|
||||||
// var settings = new RunnerSettings
|
|
||||||
// {
|
|
||||||
// PoolId = 43242
|
|
||||||
// };
|
|
||||||
|
|
||||||
// var message = new TaskAgentMessage()
|
|
||||||
// {
|
|
||||||
// Body = JsonUtility.ToString(CreateJobRequestMessage("job1")),
|
|
||||||
// MessageId = 4234,
|
|
||||||
// MessageType = JobRequestMessageTypes.AgentJobRequest
|
|
||||||
// };
|
|
||||||
|
|
||||||
// var messages = new Queue<TaskAgentMessage>();
|
|
||||||
// messages.Enqueue(message);
|
|
||||||
// _configurationManager.Setup(x => x.LoadSettings())
|
|
||||||
// .Returns(settings);
|
|
||||||
// _configurationManager.Setup(x => x.IsConfigured())
|
|
||||||
// .Returns(true);
|
|
||||||
// _messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(Task.FromResult<bool>(true));
|
|
||||||
// _messageListener.Setup(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(async () =>
|
|
||||||
// {
|
|
||||||
// if (0 == messages.Count)
|
|
||||||
// {
|
|
||||||
// await Task.Delay(2000);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return messages.Dequeue();
|
|
||||||
// });
|
|
||||||
// _messageListener.Setup(x => x.DeleteSessionAsync())
|
|
||||||
// .Returns(Task.CompletedTask);
|
|
||||||
// _messageListener.Setup(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()))
|
|
||||||
// .Returns(Task.CompletedTask);
|
|
||||||
|
|
||||||
// var runOnceJobCompleted = new TaskCompletionSource<bool>();
|
|
||||||
// _jobDispatcher.Setup(x => x.RunOnceJobCompleted)
|
|
||||||
// .Returns(runOnceJobCompleted);
|
|
||||||
// _jobDispatcher.Setup(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), It.IsAny<bool>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
// runOnceJobCompleted.TrySetResult(true);
|
|
||||||
// });
|
|
||||||
// _jobNotification.Setup(x => x.StartClient(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
|
|
||||||
// });
|
|
||||||
// _jobNotification.Setup(x => x.StartClient(It.IsAny<String>(), It.IsAny<String>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// hc.EnqueueInstance<IJobDispatcher>(_jobDispatcher.Object);
|
|
||||||
|
|
||||||
// _configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
|
|
||||||
// //Act
|
|
||||||
// var command = new CommandSettings(hc, new string[] { "run", "--once" });
|
|
||||||
// Task<int> agentTask = agent.ExecuteCommand(command);
|
|
||||||
|
|
||||||
// //Assert
|
|
||||||
// //wait for the agent to run one job and exit
|
|
||||||
// await Task.WhenAny(agentTask, Task.Delay(30000));
|
|
||||||
|
|
||||||
// Assert.True(agentTask.IsCompleted, $"{nameof(agent.ExecuteCommand)} timed out.");
|
|
||||||
// Assert.True(!agentTask.IsFaulted, agentTask.Exception?.ToString());
|
|
||||||
// Assert.True(agentTask.Result == Constants.Runner.ReturnCode.Success);
|
|
||||||
|
|
||||||
// _jobDispatcher.Verify(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), true), Times.Once(),
|
|
||||||
// $"{nameof(_jobDispatcher.Object.Run)} was not invoked.");
|
|
||||||
// _messageListener.Verify(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()), Times.AtLeastOnce());
|
|
||||||
// _messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
|
||||||
// _messageListener.Verify(x => x.DeleteSessionAsync(), Times.Once());
|
|
||||||
// _messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()), Times.AtLeastOnce());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Fact]
|
|
||||||
// [Trait("Level", "L0")]
|
|
||||||
// [Trait("Category", "Agent")]
|
|
||||||
// public async void TestRunOnceOnlyTakeOneJobMessage()
|
|
||||||
// {
|
|
||||||
// using (var hc = new TestHostContext(this))
|
|
||||||
// {
|
|
||||||
// //Arrange
|
|
||||||
// var agent = new Runner.Listener.Runner();
|
|
||||||
// hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
|
||||||
// hc.SetSingleton<IJobNotification>(_jobNotification.Object);
|
|
||||||
// hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
|
||||||
// hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
|
||||||
// hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
|
||||||
// hc.SetSingleton<IRunnerWebProxy>(_proxy.Object);
|
|
||||||
// hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
|
||||||
// hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
|
||||||
// agent.Initialize(hc);
|
|
||||||
// var settings = new RunnerSettings
|
|
||||||
// {
|
|
||||||
// PoolId = 43242
|
|
||||||
// };
|
|
||||||
|
|
||||||
// var message1 = new TaskAgentMessage()
|
|
||||||
// {
|
|
||||||
// Body = JsonUtility.ToString(CreateJobRequestMessage("job1")),
|
|
||||||
// MessageId = 4234,
|
|
||||||
// MessageType = JobRequestMessageTypes.AgentJobRequest
|
|
||||||
// };
|
|
||||||
// var message2 = new TaskAgentMessage()
|
|
||||||
// {
|
|
||||||
// Body = JsonUtility.ToString(CreateJobRequestMessage("job1")),
|
|
||||||
// MessageId = 4235,
|
|
||||||
// MessageType = JobRequestMessageTypes.AgentJobRequest
|
|
||||||
// };
|
|
||||||
|
|
||||||
// var messages = new Queue<TaskAgentMessage>();
|
|
||||||
// messages.Enqueue(message1);
|
|
||||||
// messages.Enqueue(message2);
|
|
||||||
// _configurationManager.Setup(x => x.LoadSettings())
|
|
||||||
// .Returns(settings);
|
|
||||||
// _configurationManager.Setup(x => x.IsConfigured())
|
|
||||||
// .Returns(true);
|
|
||||||
// _messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(Task.FromResult<bool>(true));
|
|
||||||
// _messageListener.Setup(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(async () =>
|
|
||||||
// {
|
|
||||||
// if (0 == messages.Count)
|
|
||||||
// {
|
|
||||||
// await Task.Delay(2000);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return messages.Dequeue();
|
|
||||||
// });
|
|
||||||
// _messageListener.Setup(x => x.DeleteSessionAsync())
|
|
||||||
// .Returns(Task.CompletedTask);
|
|
||||||
// _messageListener.Setup(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()))
|
|
||||||
// .Returns(Task.CompletedTask);
|
|
||||||
|
|
||||||
// var runOnceJobCompleted = new TaskCompletionSource<bool>();
|
|
||||||
// _jobDispatcher.Setup(x => x.RunOnceJobCompleted)
|
|
||||||
// .Returns(runOnceJobCompleted);
|
|
||||||
// _jobDispatcher.Setup(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), It.IsAny<bool>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
// runOnceJobCompleted.TrySetResult(true);
|
|
||||||
// });
|
|
||||||
// _jobNotification.Setup(x => x.StartClient(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
|
|
||||||
// });
|
|
||||||
// _jobNotification.Setup(x => x.StartClient(It.IsAny<String>(), It.IsAny<String>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// hc.EnqueueInstance<IJobDispatcher>(_jobDispatcher.Object);
|
|
||||||
|
|
||||||
// _configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
|
|
||||||
// //Act
|
|
||||||
// var command = new CommandSettings(hc, new string[] { "run", "--once" });
|
|
||||||
// Task<int> agentTask = agent.ExecuteCommand(command);
|
|
||||||
|
|
||||||
// //Assert
|
|
||||||
// //wait for the agent to run one job and exit
|
|
||||||
// await Task.WhenAny(agentTask, Task.Delay(30000));
|
|
||||||
|
|
||||||
// Assert.True(agentTask.IsCompleted, $"{nameof(agent.ExecuteCommand)} timed out.");
|
|
||||||
// Assert.True(!agentTask.IsFaulted, agentTask.Exception?.ToString());
|
|
||||||
// Assert.True(agentTask.Result == Constants.Runner.ReturnCode.Success);
|
|
||||||
|
|
||||||
// _jobDispatcher.Verify(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), true), Times.Once(),
|
|
||||||
// $"{nameof(_jobDispatcher.Object.Run)} was not invoked.");
|
|
||||||
// _messageListener.Verify(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()), Times.AtLeastOnce());
|
|
||||||
// _messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
|
||||||
// _messageListener.Verify(x => x.DeleteSessionAsync(), Times.Once());
|
|
||||||
// _messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()), Times.Once());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// [Fact]
|
|
||||||
// [Trait("Level", "L0")]
|
|
||||||
// [Trait("Category", "Agent")]
|
|
||||||
// public async void TestRunOnceHandleUpdateMessage()
|
|
||||||
// {
|
|
||||||
// using (var hc = new TestHostContext(this))
|
|
||||||
// {
|
|
||||||
// //Arrange
|
|
||||||
// var agent = new Runner.Listener.Runner();
|
|
||||||
// hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
|
||||||
// hc.SetSingleton<IJobNotification>(_jobNotification.Object);
|
|
||||||
// hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
|
||||||
// hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
|
||||||
// hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
|
||||||
// hc.SetSingleton<IRunnerWebProxy>(_proxy.Object);
|
|
||||||
// hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
|
||||||
// hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
|
||||||
// hc.SetSingleton<ISelfUpdater>(_updater.Object);
|
|
||||||
|
|
||||||
// agent.Initialize(hc);
|
|
||||||
// var settings = new RunnerSettings
|
|
||||||
// {
|
|
||||||
// PoolId = 43242,
|
|
||||||
// AgentId = 5678
|
|
||||||
// };
|
|
||||||
|
|
||||||
// var message1 = new TaskAgentMessage()
|
|
||||||
// {
|
|
||||||
// Body = JsonUtility.ToString(new AgentRefreshMessage(settings.AgentId, "2.123.0")),
|
|
||||||
// MessageId = 4234,
|
|
||||||
// MessageType = AgentRefreshMessage.MessageType
|
|
||||||
// };
|
|
||||||
|
|
||||||
// var messages = new Queue<TaskAgentMessage>();
|
|
||||||
// messages.Enqueue(message1);
|
|
||||||
// _updater.Setup(x => x.SelfUpdate(It.IsAny<AgentRefreshMessage>(), It.IsAny<IJobDispatcher>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(Task.FromResult(true));
|
|
||||||
// _configurationManager.Setup(x => x.LoadSettings())
|
|
||||||
// .Returns(settings);
|
|
||||||
// _configurationManager.Setup(x => x.IsConfigured())
|
|
||||||
// .Returns(true);
|
|
||||||
// _messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(Task.FromResult<bool>(true));
|
|
||||||
// _messageListener.Setup(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()))
|
|
||||||
// .Returns(async () =>
|
|
||||||
// {
|
|
||||||
// if (0 == messages.Count)
|
|
||||||
// {
|
|
||||||
// await Task.Delay(2000);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return messages.Dequeue();
|
|
||||||
// });
|
|
||||||
// _messageListener.Setup(x => x.DeleteSessionAsync())
|
|
||||||
// .Returns(Task.CompletedTask);
|
|
||||||
// _messageListener.Setup(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()))
|
|
||||||
// .Returns(Task.CompletedTask);
|
|
||||||
// _jobNotification.Setup(x => x.StartClient(It.IsAny<String>(), It.IsAny<String>(), It.IsAny<CancellationToken>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
|
|
||||||
// });
|
|
||||||
// _jobNotification.Setup(x => x.StartClient(It.IsAny<String>(), It.IsAny<String>()))
|
|
||||||
// .Callback(() =>
|
|
||||||
// {
|
|
||||||
|
|
||||||
// });
|
|
||||||
|
|
||||||
// hc.EnqueueInstance<IJobDispatcher>(_jobDispatcher.Object);
|
|
||||||
|
|
||||||
// _configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
|
|
||||||
// //Act
|
|
||||||
// var command = new CommandSettings(hc, new string[] { "run", "--once" });
|
|
||||||
// Task<int> agentTask = agent.ExecuteCommand(command);
|
|
||||||
|
|
||||||
// //Assert
|
|
||||||
// //wait for the agent to exit with right return code
|
|
||||||
// await Task.WhenAny(agentTask, Task.Delay(30000));
|
|
||||||
|
|
||||||
// Assert.True(agentTask.IsCompleted, $"{nameof(agent.ExecuteCommand)} timed out.");
|
|
||||||
// Assert.True(!agentTask.IsFaulted, agentTask.Exception?.ToString());
|
|
||||||
// Assert.True(agentTask.Result == Constants.Runner.ReturnCode.RunOnceRunnerUpdating);
|
|
||||||
|
|
||||||
// _updater.Verify(x => x.SelfUpdate(It.IsAny<AgentRefreshMessage>(), It.IsAny<IJobDispatcher>(), false, It.IsAny<CancellationToken>()), Times.Once);
|
|
||||||
// _jobDispatcher.Verify(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), true), Times.Never());
|
|
||||||
// _messageListener.Verify(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()), Times.AtLeastOnce());
|
|
||||||
// _messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
|
||||||
// _messageListener.Verify(x => x.DeleteSessionAsync(), Times.Once());
|
|
||||||
// _messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()), Times.Once());
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
@@ -20,7 +20,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
|||||||
{
|
{
|
||||||
public class ConfigurationManagerL0
|
public class ConfigurationManagerL0
|
||||||
{
|
{
|
||||||
private Mock<IRunnerServer> _agentServer;
|
private Mock<IRunnerServer> _runnerServer;
|
||||||
private Mock<ILocationServer> _locationServer;
|
private Mock<ILocationServer> _locationServer;
|
||||||
private Mock<ICredentialManager> _credMgr;
|
private Mock<ICredentialManager> _credMgr;
|
||||||
private Mock<IPromptManager> _promptManager;
|
private Mock<IPromptManager> _promptManager;
|
||||||
@@ -50,7 +50,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
|||||||
|
|
||||||
public ConfigurationManagerL0()
|
public ConfigurationManagerL0()
|
||||||
{
|
{
|
||||||
_agentServer = new Mock<IRunnerServer>();
|
_runnerServer = new Mock<IRunnerServer>();
|
||||||
_locationServer = new Mock<ILocationServer>();
|
_locationServer = new Mock<ILocationServer>();
|
||||||
_credMgr = new Mock<ICredentialManager>();
|
_credMgr = new Mock<ICredentialManager>();
|
||||||
_promptManager = new Mock<IPromptManager>();
|
_promptManager = new Mock<IPromptManager>();
|
||||||
@@ -81,15 +81,9 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
|||||||
DeploymentType = DeploymentFlags.Hosted,
|
DeploymentType = DeploymentFlags.Hosted,
|
||||||
DeploymentId = Guid.NewGuid()
|
DeploymentId = Guid.NewGuid()
|
||||||
};
|
};
|
||||||
_agentServer.Setup(x => x.ConnectAsync(It.IsAny<Uri>(), It.IsAny<VssCredentials>())).Returns(Task.FromResult<object>(null));
|
_runnerServer.Setup(x => x.ConnectAsync(It.IsAny<Uri>(), It.IsAny<VssCredentials>())).Returns(Task.FromResult<object>(null));
|
||||||
_locationServer.Setup(x => x.ConnectAsync(It.IsAny<VssConnection>())).Returns(Task.FromResult<object>(null));
|
_locationServer.Setup(x => x.ConnectAsync(It.IsAny<VssConnection>())).Returns(Task.FromResult<object>(null));
|
||||||
_locationServer.Setup(x => x.GetConnectionDataAsync()).Returns(Task.FromResult<ConnectionData>(connectionData));
|
_locationServer.Setup(x => x.GetConnectionDataAsync()).Returns(Task.FromResult<ConnectionData>(connectionData));
|
||||||
// _machineGroupServer.Setup(x => x.ConnectAsync(It.IsAny<VssConnection>())).Returns(Task.FromResult<object>(null));
|
|
||||||
// _machineGroupServer.Setup(x => x.UpdateDeploymentTargetsAsync(It.IsAny<Guid>(), It.IsAny<int>(), It.IsAny<List<DeploymentMachine>>()));
|
|
||||||
// _machineGroupServer.Setup(x => x.AddDeploymentTargetAsync(It.IsAny<Guid>(), It.IsAny<int>(), It.IsAny<DeploymentMachine>())).Returns(Task.FromResult(expectedDeploymentMachine));
|
|
||||||
// _machineGroupServer.Setup(x => x.ReplaceDeploymentTargetAsync(It.IsAny<Guid>(), It.IsAny<int>(), It.IsAny<int>(), It.IsAny<DeploymentMachine>())).Returns(Task.FromResult(expectedDeploymentMachine));
|
|
||||||
// _machineGroupServer.Setup(x => x.GetDeploymentTargetsAsync(It.IsAny<Guid>(), It.IsAny<int>(), It.IsAny<string>())).Returns(Task.FromResult(new List<DeploymentMachine>() { }));
|
|
||||||
// _machineGroupServer.Setup(x => x.DeleteDeploymentTargetAsync(It.IsAny<string>(), It.IsAny<int>(), It.IsAny<int>())).Returns(Task.FromResult<object>(null));
|
|
||||||
|
|
||||||
_store.Setup(x => x.IsConfigured()).Returns(false);
|
_store.Setup(x => x.IsConfigured()).Returns(false);
|
||||||
_store.Setup(x => x.HasCredentials()).Returns(false);
|
_store.Setup(x => x.HasCredentials()).Returns(false);
|
||||||
@@ -101,20 +95,20 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
|||||||
_configMgrAgentSettings = settings;
|
_configMgrAgentSettings = settings;
|
||||||
});
|
});
|
||||||
|
|
||||||
_credMgr.Setup(x => x.GetCredentialProvider(It.IsAny<string>())).Returns(new TestAgentCredential());
|
_credMgr.Setup(x => x.GetCredentialProvider(It.IsAny<string>())).Returns(new TestRunnerCredential());
|
||||||
|
|
||||||
#if !OS_WINDOWS
|
#if !OS_WINDOWS
|
||||||
_serviceControlManager.Setup(x => x.GenerateScripts(It.IsAny<RunnerSettings>()));
|
_serviceControlManager.Setup(x => x.GenerateScripts(It.IsAny<RunnerSettings>()));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
var expectedPools = new List<TaskAgentPool>() { new TaskAgentPool(_expectedPoolName) { Id = _expectedPoolId } };
|
var expectedPools = new List<TaskAgentPool>() { new TaskAgentPool(_expectedPoolName) { Id = _expectedPoolId } };
|
||||||
_agentServer.Setup(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.IsAny<TaskAgentPoolType>())).Returns(Task.FromResult(expectedPools));
|
_runnerServer.Setup(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.IsAny<TaskAgentPoolType>())).Returns(Task.FromResult(expectedPools));
|
||||||
|
|
||||||
var expectedAgents = new List<TaskAgent>();
|
var expectedAgents = new List<TaskAgent>();
|
||||||
_agentServer.Setup(x => x.GetAgentsAsync(It.IsAny<int>(), It.IsAny<string>())).Returns(Task.FromResult(expectedAgents));
|
_runnerServer.Setup(x => x.GetAgentsAsync(It.IsAny<int>(), It.IsAny<string>())).Returns(Task.FromResult(expectedAgents));
|
||||||
|
|
||||||
_agentServer.Setup(x => x.AddAgentAsync(It.IsAny<int>(), It.IsAny<TaskAgent>())).Returns(Task.FromResult(expectedAgent));
|
_runnerServer.Setup(x => x.AddAgentAsync(It.IsAny<int>(), It.IsAny<TaskAgent>())).Returns(Task.FromResult(expectedAgent));
|
||||||
_agentServer.Setup(x => x.ReplaceAgentAsync(It.IsAny<int>(), It.IsAny<TaskAgent>())).Returns(Task.FromResult(expectedAgent));
|
_runnerServer.Setup(x => x.ReplaceAgentAsync(It.IsAny<int>(), It.IsAny<TaskAgent>())).Returns(Task.FromResult(expectedAgent));
|
||||||
|
|
||||||
rsa = new RSACryptoServiceProvider(2048);
|
rsa = new RSACryptoServiceProvider(2048);
|
||||||
|
|
||||||
@@ -128,7 +122,7 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
|||||||
tc.SetSingleton<IPromptManager>(_promptManager.Object);
|
tc.SetSingleton<IPromptManager>(_promptManager.Object);
|
||||||
tc.SetSingleton<IConfigurationStore>(_store.Object);
|
tc.SetSingleton<IConfigurationStore>(_store.Object);
|
||||||
tc.SetSingleton<IExtensionManager>(_extnMgr.Object);
|
tc.SetSingleton<IExtensionManager>(_extnMgr.Object);
|
||||||
tc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
tc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
tc.SetSingleton<ILocationServer>(_locationServer.Object);
|
tc.SetSingleton<ILocationServer>(_locationServer.Object);
|
||||||
tc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
tc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
||||||
|
|
||||||
@@ -190,9 +184,9 @@ namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
|||||||
Assert.True(s.WorkFolder.Equals(_expectedWorkFolder));
|
Assert.True(s.WorkFolder.Equals(_expectedWorkFolder));
|
||||||
|
|
||||||
// validate GetAgentPoolsAsync gets called once with automation pool type
|
// validate GetAgentPoolsAsync gets called once with automation pool type
|
||||||
_agentServer.Verify(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.Is<TaskAgentPoolType>(p => p == TaskAgentPoolType.Automation)), Times.Once);
|
_runnerServer.Verify(x => x.GetAgentPoolsAsync(It.IsAny<string>(), It.Is<TaskAgentPoolType>(p => p == TaskAgentPoolType.Automation)), Times.Once);
|
||||||
|
|
||||||
_agentServer.Verify(x => x.AddAgentAsync(It.IsAny<int>(), It.Is<TaskAgent>(a => a.Labels.Contains("self-hosted") && a.Labels.Contains(VarUtil.OS) && a.Labels.Contains(VarUtil.OSArchitecture))), Times.Once);
|
_runnerServer.Verify(x => x.AddAgentAsync(It.IsAny<int>(), It.Is<TaskAgent>(a => a.Labels.Contains("self-hosted") && a.Labels.Contains(VarUtil.OS) && a.Labels.Contains(VarUtil.OSArchitecture))), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ using GitHub.Services.Common;
|
|||||||
|
|
||||||
namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
namespace GitHub.Runner.Common.Tests.Listener.Configuration
|
||||||
{
|
{
|
||||||
public class TestAgentCredential : CredentialProvider
|
public class TestRunnerCredential : CredentialProvider
|
||||||
{
|
{
|
||||||
public TestAgentCredential(): base("TEST") {}
|
public TestRunnerCredential(): base("TEST") {}
|
||||||
public override VssCredentials GetVssCredentials(IHostContext context)
|
public override VssCredentials GetVssCredentials(IHostContext context)
|
||||||
{
|
{
|
||||||
Tracing trace = context.GetTrace("PersonalAccessToken");
|
Tracing trace = context.GetTrace("PersonalAccessToken");
|
||||||
@@ -17,14 +17,14 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
{
|
{
|
||||||
private Mock<IProcessChannel> _processChannel;
|
private Mock<IProcessChannel> _processChannel;
|
||||||
private Mock<IProcessInvoker> _processInvoker;
|
private Mock<IProcessInvoker> _processInvoker;
|
||||||
private Mock<IRunnerServer> _agentServer;
|
private Mock<IRunnerServer> _runnerServer;
|
||||||
private Mock<IConfigurationStore> _configurationStore;
|
private Mock<IConfigurationStore> _configurationStore;
|
||||||
|
|
||||||
public JobDispatcherL0()
|
public JobDispatcherL0()
|
||||||
{
|
{
|
||||||
_processChannel = new Mock<IProcessChannel>();
|
_processChannel = new Mock<IProcessChannel>();
|
||||||
_processInvoker = new Mock<IProcessInvoker>();
|
_processInvoker = new Mock<IProcessInvoker>();
|
||||||
_agentServer = new Mock<IRunnerServer>();
|
_runnerServer = new Mock<IRunnerServer>();
|
||||||
_configurationStore = new Mock<IConfigurationStore>();
|
_configurationStore = new Mock<IConfigurationStore>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void DispatchesJobRequest()
|
public async void DispatchesJobRequest()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
@@ -51,7 +51,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
{
|
{
|
||||||
var jobDispatcher = new JobDispatcher();
|
var jobDispatcher = new JobDispatcher();
|
||||||
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
||||||
hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
|
|
||||||
hc.EnqueueInstance<IProcessChannel>(_processChannel.Object);
|
hc.EnqueueInstance<IProcessChannel>(_processChannel.Object);
|
||||||
hc.EnqueueInstance<IProcessInvoker>(_processInvoker.Object);
|
hc.EnqueueInstance<IProcessInvoker>(_processInvoker.Object);
|
||||||
@@ -76,9 +76,9 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(sessionIdProperty);
|
Assert.NotNull(sessionIdProperty);
|
||||||
sessionIdProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
sessionIdProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
||||||
|
|
||||||
_agentServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult<TaskAgentJobRequest>(request));
|
_runnerServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult<TaskAgentJobRequest>(request));
|
||||||
|
|
||||||
_agentServer.Setup(x => x.FinishAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<DateTime>(), It.IsAny<TaskResult>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult<TaskAgentJobRequest>(new TaskAgentJobRequest()));
|
_runnerServer.Setup(x => x.FinishAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<DateTime>(), It.IsAny<TaskResult>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult<TaskAgentJobRequest>(new TaskAgentJobRequest()));
|
||||||
|
|
||||||
|
|
||||||
//Actt
|
//Actt
|
||||||
@@ -93,7 +93,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void DispatcherRenewJobRequest()
|
public async void DispatcherRenewJobRequest()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
@@ -112,10 +112,10 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(lockUntilProperty);
|
Assert.NotNull(lockUntilProperty);
|
||||||
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
||||||
|
|
||||||
hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
||||||
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
||||||
_agentServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
_runnerServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
||||||
.Returns(() =>
|
.Returns(() =>
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@@ -145,13 +145,13 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
await jobDispatcher.RenewJobRequestAsync(poolId, requestId, Guid.Empty, firstJobRequestRenewed, cancellationTokenSource.Token);
|
await jobDispatcher.RenewJobRequestAsync(poolId, requestId, Guid.Empty, firstJobRequestRenewed, cancellationTokenSource.Token);
|
||||||
|
|
||||||
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully);
|
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully);
|
||||||
_agentServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(5));
|
_runnerServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void DispatcherRenewJobRequestStopOnJobNotFoundExceptions()
|
public async void DispatcherRenewJobRequestStopOnJobNotFoundExceptions()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
@@ -170,10 +170,10 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(lockUntilProperty);
|
Assert.NotNull(lockUntilProperty);
|
||||||
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
||||||
|
|
||||||
hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
||||||
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
||||||
_agentServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
_runnerServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
||||||
.Returns(() =>
|
.Returns(() =>
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@@ -204,13 +204,13 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should succeed.");
|
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should succeed.");
|
||||||
Assert.False(cancellationTokenSource.IsCancellationRequested);
|
Assert.False(cancellationTokenSource.IsCancellationRequested);
|
||||||
_agentServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(5));
|
_runnerServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void DispatcherRenewJobRequestStopOnJobTokenExpiredExceptions()
|
public async void DispatcherRenewJobRequestStopOnJobTokenExpiredExceptions()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
@@ -229,10 +229,10 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(lockUntilProperty);
|
Assert.NotNull(lockUntilProperty);
|
||||||
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
||||||
|
|
||||||
hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
||||||
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
||||||
_agentServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
_runnerServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
||||||
.Returns(() =>
|
.Returns(() =>
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@@ -263,13 +263,13 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should succeed.");
|
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should succeed.");
|
||||||
Assert.False(cancellationTokenSource.IsCancellationRequested);
|
Assert.False(cancellationTokenSource.IsCancellationRequested);
|
||||||
_agentServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(5));
|
_runnerServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(5));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void DispatcherRenewJobRequestRecoverFromExceptions()
|
public async void DispatcherRenewJobRequestRecoverFromExceptions()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
@@ -288,10 +288,10 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(lockUntilProperty);
|
Assert.NotNull(lockUntilProperty);
|
||||||
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
||||||
|
|
||||||
hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
||||||
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
||||||
_agentServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
_runnerServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
||||||
.Returns(() =>
|
.Returns(() =>
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@@ -322,15 +322,15 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should succeed.");
|
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should succeed.");
|
||||||
Assert.True(cancellationTokenSource.IsCancellationRequested);
|
Assert.True(cancellationTokenSource.IsCancellationRequested);
|
||||||
_agentServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(8));
|
_runnerServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(8));
|
||||||
_agentServer.Verify(x => x.RefreshConnectionAsync(RunnerConnectionType.JobRequest, It.IsAny<TimeSpan>()), Times.Exactly(3));
|
_runnerServer.Verify(x => x.RefreshConnectionAsync(RunnerConnectionType.JobRequest, It.IsAny<TimeSpan>()), Times.Exactly(3));
|
||||||
_agentServer.Verify(x => x.SetConnectionTimeout(RunnerConnectionType.JobRequest, It.IsAny<TimeSpan>()), Times.Once);
|
_runnerServer.Verify(x => x.SetConnectionTimeout(RunnerConnectionType.JobRequest, It.IsAny<TimeSpan>()), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void DispatcherRenewJobRequestFirstRenewRetrySixTimes()
|
public async void DispatcherRenewJobRequestFirstRenewRetrySixTimes()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
@@ -349,10 +349,10 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(lockUntilProperty);
|
Assert.NotNull(lockUntilProperty);
|
||||||
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
||||||
|
|
||||||
hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
||||||
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
||||||
_agentServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
_runnerServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
||||||
.Returns(() =>
|
.Returns(() =>
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@@ -379,13 +379,13 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
Assert.False(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should failed.");
|
Assert.False(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should failed.");
|
||||||
Assert.False(cancellationTokenSource.IsCancellationRequested);
|
Assert.False(cancellationTokenSource.IsCancellationRequested);
|
||||||
_agentServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(6));
|
_runnerServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(6));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void DispatcherRenewJobRequestStopOnExpiredRequest()
|
public async void DispatcherRenewJobRequestStopOnExpiredRequest()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
@@ -404,10 +404,10 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(lockUntilProperty);
|
Assert.NotNull(lockUntilProperty);
|
||||||
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
lockUntilProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
||||||
|
|
||||||
hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
||||||
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
_configurationStore.Setup(x => x.GetSettings()).Returns(new RunnerSettings() { PoolId = 1 });
|
||||||
_agentServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
_runnerServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()))
|
||||||
.Returns(() =>
|
.Returns(() =>
|
||||||
{
|
{
|
||||||
count++;
|
count++;
|
||||||
@@ -443,15 +443,15 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should succeed.");
|
Assert.True(firstJobRequestRenewed.Task.IsCompletedSuccessfully, "First renew should succeed.");
|
||||||
Assert.False(cancellationTokenSource.IsCancellationRequested);
|
Assert.False(cancellationTokenSource.IsCancellationRequested);
|
||||||
_agentServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(5));
|
_runnerServer.Verify(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>()), Times.Exactly(5));
|
||||||
_agentServer.Verify(x => x.RefreshConnectionAsync(RunnerConnectionType.JobRequest, It.IsAny<TimeSpan>()), Times.Exactly(3));
|
_runnerServer.Verify(x => x.RefreshConnectionAsync(RunnerConnectionType.JobRequest, It.IsAny<TimeSpan>()), Times.Exactly(3));
|
||||||
_agentServer.Verify(x => x.SetConnectionTimeout(RunnerConnectionType.JobRequest, It.IsAny<TimeSpan>()), Times.Never);
|
_runnerServer.Verify(x => x.SetConnectionTimeout(RunnerConnectionType.JobRequest, It.IsAny<TimeSpan>()), Times.Never);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void DispatchesOneTimeJobRequest()
|
public async void DispatchesOneTimeJobRequest()
|
||||||
{
|
{
|
||||||
//Arrange
|
//Arrange
|
||||||
@@ -459,7 +459,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
{
|
{
|
||||||
var jobDispatcher = new JobDispatcher();
|
var jobDispatcher = new JobDispatcher();
|
||||||
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
hc.SetSingleton<IConfigurationStore>(_configurationStore.Object);
|
||||||
hc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
|
|
||||||
hc.EnqueueInstance<IProcessChannel>(_processChannel.Object);
|
hc.EnqueueInstance<IProcessChannel>(_processChannel.Object);
|
||||||
hc.EnqueueInstance<IProcessInvoker>(_processInvoker.Object);
|
hc.EnqueueInstance<IProcessInvoker>(_processInvoker.Object);
|
||||||
@@ -484,9 +484,9 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(sessionIdProperty);
|
Assert.NotNull(sessionIdProperty);
|
||||||
sessionIdProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
sessionIdProperty.SetValue(request, DateTime.UtcNow.AddMinutes(5));
|
||||||
|
|
||||||
_agentServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult<TaskAgentJobRequest>(request));
|
_runnerServer.Setup(x => x.RenewAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult<TaskAgentJobRequest>(request));
|
||||||
|
|
||||||
_agentServer.Setup(x => x.FinishAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<DateTime>(), It.IsAny<TaskResult>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult<TaskAgentJobRequest>(new TaskAgentJobRequest()));
|
_runnerServer.Setup(x => x.FinishAgentRequestAsync(It.IsAny<int>(), It.IsAny<long>(), It.IsAny<Guid>(), It.IsAny<DateTime>(), It.IsAny<TaskResult>(), It.IsAny<CancellationToken>())).Returns(Task.FromResult<TaskAgentJobRequest>(new TaskAgentJobRequest()));
|
||||||
|
|
||||||
//Act
|
//Act
|
||||||
jobDispatcher.Run(message, true);
|
jobDispatcher.Run(message, true);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
{
|
{
|
||||||
private RunnerSettings _settings;
|
private RunnerSettings _settings;
|
||||||
private Mock<IConfigurationManager> _config;
|
private Mock<IConfigurationManager> _config;
|
||||||
private Mock<IRunnerServer> _agentServer;
|
private Mock<IRunnerServer> _runnerServer;
|
||||||
private Mock<ICredentialManager> _credMgr;
|
private Mock<ICredentialManager> _credMgr;
|
||||||
|
|
||||||
public MessageListenerL0()
|
public MessageListenerL0()
|
||||||
@@ -26,7 +26,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
_settings = new RunnerSettings { AgentId = 1, AgentName = "myagent", PoolId = 123, PoolName = "default", ServerUrl = "http://myserver", WorkFolder = "_work" };
|
_settings = new RunnerSettings { AgentId = 1, AgentName = "myagent", PoolId = 123, PoolName = "default", ServerUrl = "http://myserver", WorkFolder = "_work" };
|
||||||
_config = new Mock<IConfigurationManager>();
|
_config = new Mock<IConfigurationManager>();
|
||||||
_config.Setup(x => x.LoadSettings()).Returns(_settings);
|
_config.Setup(x => x.LoadSettings()).Returns(_settings);
|
||||||
_agentServer = new Mock<IRunnerServer>();
|
_runnerServer = new Mock<IRunnerServer>();
|
||||||
_credMgr = new Mock<ICredentialManager>();
|
_credMgr = new Mock<ICredentialManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,14 +34,14 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
{
|
{
|
||||||
TestHostContext tc = new TestHostContext(this, testName);
|
TestHostContext tc = new TestHostContext(this, testName);
|
||||||
tc.SetSingleton<IConfigurationManager>(_config.Object);
|
tc.SetSingleton<IConfigurationManager>(_config.Object);
|
||||||
tc.SetSingleton<IRunnerServer>(_agentServer.Object);
|
tc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
tc.SetSingleton<ICredentialManager>(_credMgr.Object);
|
tc.SetSingleton<ICredentialManager>(_credMgr.Object);
|
||||||
return tc;
|
return tc;
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void CreatesSession()
|
public async void CreatesSession()
|
||||||
{
|
{
|
||||||
using (TestHostContext tc = CreateTestContext())
|
using (TestHostContext tc = CreateTestContext())
|
||||||
@@ -51,7 +51,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
// Arrange.
|
// Arrange.
|
||||||
var expectedSession = new TaskAgentSession();
|
var expectedSession = new TaskAgentSession();
|
||||||
_agentServer
|
_runnerServer
|
||||||
.Setup(x => x.CreateAgentSessionAsync(
|
.Setup(x => x.CreateAgentSessionAsync(
|
||||||
_settings.PoolId,
|
_settings.PoolId,
|
||||||
It.Is<TaskAgentSession>(y => y != null),
|
It.Is<TaskAgentSession>(y => y != null),
|
||||||
@@ -69,7 +69,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
// Assert.
|
// Assert.
|
||||||
Assert.True(result);
|
Assert.True(result);
|
||||||
_agentServer
|
_runnerServer
|
||||||
.Verify(x => x.CreateAgentSessionAsync(
|
.Verify(x => x.CreateAgentSessionAsync(
|
||||||
_settings.PoolId,
|
_settings.PoolId,
|
||||||
It.Is<TaskAgentSession>(y => y != null),
|
It.Is<TaskAgentSession>(y => y != null),
|
||||||
@@ -79,7 +79,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void DeleteSession()
|
public async void DeleteSession()
|
||||||
{
|
{
|
||||||
using (TestHostContext tc = CreateTestContext())
|
using (TestHostContext tc = CreateTestContext())
|
||||||
@@ -93,7 +93,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(sessionIdProperty);
|
Assert.NotNull(sessionIdProperty);
|
||||||
sessionIdProperty.SetValue(expectedSession, Guid.NewGuid());
|
sessionIdProperty.SetValue(expectedSession, Guid.NewGuid());
|
||||||
|
|
||||||
_agentServer
|
_runnerServer
|
||||||
.Setup(x => x.CreateAgentSessionAsync(
|
.Setup(x => x.CreateAgentSessionAsync(
|
||||||
_settings.PoolId,
|
_settings.PoolId,
|
||||||
It.Is<TaskAgentSession>(y => y != null),
|
It.Is<TaskAgentSession>(y => y != null),
|
||||||
@@ -109,14 +109,14 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
bool result = await listener.CreateSessionAsync(tokenSource.Token);
|
bool result = await listener.CreateSessionAsync(tokenSource.Token);
|
||||||
Assert.True(result);
|
Assert.True(result);
|
||||||
|
|
||||||
_agentServer
|
_runnerServer
|
||||||
.Setup(x => x.DeleteAgentSessionAsync(
|
.Setup(x => x.DeleteAgentSessionAsync(
|
||||||
_settings.PoolId, expectedSession.SessionId, It.IsAny<CancellationToken>()))
|
_settings.PoolId, expectedSession.SessionId, It.IsAny<CancellationToken>()))
|
||||||
.Returns(Task.CompletedTask);
|
.Returns(Task.CompletedTask);
|
||||||
await listener.DeleteSessionAsync();
|
await listener.DeleteSessionAsync();
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
_agentServer
|
_runnerServer
|
||||||
.Verify(x => x.DeleteAgentSessionAsync(
|
.Verify(x => x.DeleteAgentSessionAsync(
|
||||||
_settings.PoolId, expectedSession.SessionId, It.IsAny<CancellationToken>()), Times.Once());
|
_settings.PoolId, expectedSession.SessionId, It.IsAny<CancellationToken>()), Times.Once());
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public async void GetNextMessage()
|
public async void GetNextMessage()
|
||||||
{
|
{
|
||||||
using (TestHostContext tc = CreateTestContext())
|
using (TestHostContext tc = CreateTestContext())
|
||||||
@@ -138,7 +138,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.NotNull(sessionIdProperty);
|
Assert.NotNull(sessionIdProperty);
|
||||||
sessionIdProperty.SetValue(expectedSession, Guid.NewGuid());
|
sessionIdProperty.SetValue(expectedSession, Guid.NewGuid());
|
||||||
|
|
||||||
_agentServer
|
_runnerServer
|
||||||
.Setup(x => x.CreateAgentSessionAsync(
|
.Setup(x => x.CreateAgentSessionAsync(
|
||||||
_settings.PoolId,
|
_settings.PoolId,
|
||||||
It.Is<TaskAgentSession>(y => y != null),
|
It.Is<TaskAgentSession>(y => y != null),
|
||||||
@@ -179,7 +179,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
};
|
};
|
||||||
var messages = new Queue<TaskAgentMessage>(arMessages);
|
var messages = new Queue<TaskAgentMessage>(arMessages);
|
||||||
|
|
||||||
_agentServer
|
_runnerServer
|
||||||
.Setup(x => x.GetAgentMessageAsync(
|
.Setup(x => x.GetAgentMessageAsync(
|
||||||
_settings.PoolId, expectedSession.SessionId, It.IsAny<long?>(), tokenSource.Token))
|
_settings.PoolId, expectedSession.SessionId, It.IsAny<long?>(), tokenSource.Token))
|
||||||
.Returns(async (Int32 poolId, Guid sessionId, Int64? lastMessageId, CancellationToken cancellationToken) =>
|
.Returns(async (Int32 poolId, Guid sessionId, Int64? lastMessageId, CancellationToken cancellationToken) =>
|
||||||
@@ -195,7 +195,7 @@ namespace GitHub.Runner.Common.Tests.Listener
|
|||||||
Assert.Equal(arMessages[4], message3);
|
Assert.Equal(arMessages[4], message3);
|
||||||
|
|
||||||
//Assert
|
//Assert
|
||||||
_agentServer
|
_runnerServer
|
||||||
.Verify(x => x.GetAgentMessageAsync(
|
.Verify(x => x.GetAgentMessageAsync(
|
||||||
_settings.PoolId, expectedSession.SessionId, It.IsAny<long?>(), tokenSource.Token), Times.Exactly(arMessages.Length));
|
_settings.PoolId, expectedSession.SessionId, It.IsAny<long?>(), tokenSource.Token), Times.Exactly(arMessages.Length));
|
||||||
}
|
}
|
||||||
|
|||||||
509
src/Test/L0/Listener/RunnerL0.cs
Normal file
509
src/Test/L0/Listener/RunnerL0.cs
Normal file
@@ -0,0 +1,509 @@
|
|||||||
|
using GitHub.DistributedTask.WebApi;
|
||||||
|
using GitHub.Runner.Listener;
|
||||||
|
using GitHub.Runner.Listener.Configuration;
|
||||||
|
using Moq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Xunit;
|
||||||
|
using GitHub.Services.WebApi;
|
||||||
|
using Pipelines = GitHub.DistributedTask.Pipelines;
|
||||||
|
using GitHub.Runner.Common.Util;
|
||||||
|
|
||||||
|
namespace GitHub.Runner.Common.Tests.Listener
|
||||||
|
{
|
||||||
|
public sealed class RunnerL0
|
||||||
|
{
|
||||||
|
private Mock<IConfigurationManager> _configurationManager;
|
||||||
|
private Mock<IJobNotification> _jobNotification;
|
||||||
|
private Mock<IMessageListener> _messageListener;
|
||||||
|
private Mock<IPromptManager> _promptManager;
|
||||||
|
private Mock<IJobDispatcher> _jobDispatcher;
|
||||||
|
private Mock<IRunnerServer> _runnerServer;
|
||||||
|
private Mock<ITerminal> _term;
|
||||||
|
private Mock<IConfigurationStore> _configStore;
|
||||||
|
private Mock<IRunnerCertificateManager> _cert;
|
||||||
|
private Mock<ISelfUpdater> _updater;
|
||||||
|
|
||||||
|
public RunnerL0()
|
||||||
|
{
|
||||||
|
_configurationManager = new Mock<IConfigurationManager>();
|
||||||
|
_jobNotification = new Mock<IJobNotification>();
|
||||||
|
_messageListener = new Mock<IMessageListener>();
|
||||||
|
_promptManager = new Mock<IPromptManager>();
|
||||||
|
_jobDispatcher = new Mock<IJobDispatcher>();
|
||||||
|
_runnerServer = new Mock<IRunnerServer>();
|
||||||
|
_term = new Mock<ITerminal>();
|
||||||
|
_configStore = new Mock<IConfigurationStore>();
|
||||||
|
_cert = new Mock<IRunnerCertificateManager>();
|
||||||
|
_updater = new Mock<ISelfUpdater>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private AgentJobRequestMessage CreateJobRequestMessage(string jobName)
|
||||||
|
{
|
||||||
|
TaskOrchestrationPlanReference plan = new TaskOrchestrationPlanReference();
|
||||||
|
TimelineReference timeline = null;
|
||||||
|
JobEnvironment environment = new JobEnvironment();
|
||||||
|
List<TaskInstance> tasks = new List<TaskInstance>();
|
||||||
|
Guid JobId = Guid.NewGuid();
|
||||||
|
var jobRequest = new AgentJobRequestMessage(plan, timeline, JobId, jobName, jobName, environment, tasks);
|
||||||
|
return jobRequest as AgentJobRequestMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private JobCancelMessage CreateJobCancelMessage()
|
||||||
|
{
|
||||||
|
var message = new JobCancelMessage(Guid.NewGuid(), TimeSpan.FromSeconds(0));
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Runner")]
|
||||||
|
//process 2 new job messages, and one cancel message
|
||||||
|
public async void TestRunAsync()
|
||||||
|
{
|
||||||
|
using (var hc = new TestHostContext(this))
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
var runner = new Runner.Listener.Runner();
|
||||||
|
hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
||||||
|
hc.SetSingleton<IJobNotification>(_jobNotification.Object);
|
||||||
|
hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
||||||
|
hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
||||||
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
|
hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
||||||
|
hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
||||||
|
runner.Initialize(hc);
|
||||||
|
var settings = new RunnerSettings
|
||||||
|
{
|
||||||
|
PoolId = 43242
|
||||||
|
};
|
||||||
|
|
||||||
|
var message = new TaskAgentMessage()
|
||||||
|
{
|
||||||
|
Body = JsonUtility.ToString(CreateJobRequestMessage("job1")),
|
||||||
|
MessageId = 4234,
|
||||||
|
MessageType = JobRequestMessageTypes.PipelineAgentJobRequest
|
||||||
|
};
|
||||||
|
|
||||||
|
var messages = new Queue<TaskAgentMessage>();
|
||||||
|
messages.Enqueue(message);
|
||||||
|
var signalWorkerComplete = new SemaphoreSlim(0, 1);
|
||||||
|
_configurationManager.Setup(x => x.LoadSettings())
|
||||||
|
.Returns(settings);
|
||||||
|
_configurationManager.Setup(x => x.IsConfigured())
|
||||||
|
.Returns(true);
|
||||||
|
_messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(Task.FromResult<bool>(true));
|
||||||
|
_messageListener.Setup(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(async () =>
|
||||||
|
{
|
||||||
|
if (0 == messages.Count)
|
||||||
|
{
|
||||||
|
signalWorkerComplete.Release();
|
||||||
|
await Task.Delay(2000, hc.RunnerShutdownToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages.Dequeue();
|
||||||
|
});
|
||||||
|
_messageListener.Setup(x => x.DeleteSessionAsync())
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
_messageListener.Setup(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
_jobDispatcher.Setup(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), It.IsAny<bool>()))
|
||||||
|
.Callback(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
});
|
||||||
|
_jobNotification.Setup(x => x.StartClient(It.IsAny<String>()))
|
||||||
|
.Callback(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
hc.EnqueueInstance<IJobDispatcher>(_jobDispatcher.Object);
|
||||||
|
|
||||||
|
_configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
|
||||||
|
//Act
|
||||||
|
var command = new CommandSettings(hc, new string[] { "run" });
|
||||||
|
Task runnerTask = runner.ExecuteCommand(command);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
//wait for the runner to run one job
|
||||||
|
if (!await signalWorkerComplete.WaitAsync(2000))
|
||||||
|
{
|
||||||
|
Assert.True(false, $"{nameof(_messageListener.Object.GetNextMessageAsync)} was not invoked.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//Act
|
||||||
|
hc.ShutdownRunner(ShutdownReason.UserCancelled); //stop Runner
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
Task[] taskToWait2 = { runnerTask, Task.Delay(2000) };
|
||||||
|
//wait for the runner to exit
|
||||||
|
await Task.WhenAny(taskToWait2);
|
||||||
|
|
||||||
|
Assert.True(runnerTask.IsCompleted, $"{nameof(runner.ExecuteCommand)} timed out.");
|
||||||
|
Assert.True(!runnerTask.IsFaulted, runnerTask.Exception?.ToString());
|
||||||
|
Assert.True(runnerTask.IsCanceled);
|
||||||
|
|
||||||
|
_jobDispatcher.Verify(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), It.IsAny<bool>()), Times.Once(),
|
||||||
|
$"{nameof(_jobDispatcher.Object.Run)} was not invoked.");
|
||||||
|
_messageListener.Verify(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()), Times.AtLeastOnce());
|
||||||
|
_messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
||||||
|
_messageListener.Verify(x => x.DeleteSessionAsync(), Times.Once());
|
||||||
|
_messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()), Times.AtLeastOnce());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TheoryData<string[], bool, Times> RunAsServiceTestData = new TheoryData<string[], bool, Times>()
|
||||||
|
{
|
||||||
|
// staring with run command, configured as run as service, should start the runner
|
||||||
|
{ new [] { "run" }, true, Times.Once() },
|
||||||
|
// starting with no argument, configured not to run as service, should start runner interactively
|
||||||
|
{ new [] { "run" }, false, Times.Once() }
|
||||||
|
};
|
||||||
|
[Theory]
|
||||||
|
[MemberData(nameof(RunAsServiceTestData))]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Runner")]
|
||||||
|
public async void TestExecuteCommandForRunAsService(string[] args, bool configureAsService, Times expectedTimes)
|
||||||
|
{
|
||||||
|
using (var hc = new TestHostContext(this))
|
||||||
|
{
|
||||||
|
hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
||||||
|
hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
||||||
|
hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
||||||
|
hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
||||||
|
hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
||||||
|
|
||||||
|
var command = new CommandSettings(hc, args);
|
||||||
|
|
||||||
|
_configurationManager.Setup(x => x.IsConfigured()).Returns(true);
|
||||||
|
_configurationManager.Setup(x => x.LoadSettings())
|
||||||
|
.Returns(new RunnerSettings { });
|
||||||
|
|
||||||
|
_configStore.Setup(x => x.IsServiceConfigured()).Returns(configureAsService);
|
||||||
|
|
||||||
|
_messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(Task.FromResult(false));
|
||||||
|
|
||||||
|
var runner = new Runner.Listener.Runner();
|
||||||
|
runner.Initialize(hc);
|
||||||
|
await runner.ExecuteCommand(command);
|
||||||
|
|
||||||
|
_messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), expectedTimes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Runner")]
|
||||||
|
public async void TestMachineProvisionerCLI()
|
||||||
|
{
|
||||||
|
using (var hc = new TestHostContext(this))
|
||||||
|
{
|
||||||
|
hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
||||||
|
hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
||||||
|
hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
||||||
|
hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
||||||
|
hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
||||||
|
|
||||||
|
var command = new CommandSettings(hc, new[] { "run" });
|
||||||
|
|
||||||
|
_configurationManager.Setup(x => x.IsConfigured()).
|
||||||
|
Returns(true);
|
||||||
|
_configurationManager.Setup(x => x.LoadSettings())
|
||||||
|
.Returns(new RunnerSettings { });
|
||||||
|
|
||||||
|
_configStore.Setup(x => x.IsServiceConfigured())
|
||||||
|
.Returns(false);
|
||||||
|
|
||||||
|
_messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(Task.FromResult(false));
|
||||||
|
|
||||||
|
var runner = new Runner.Listener.Runner();
|
||||||
|
runner.Initialize(hc);
|
||||||
|
await runner.ExecuteCommand(command);
|
||||||
|
|
||||||
|
_messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Runner")]
|
||||||
|
public async void TestRunOnce()
|
||||||
|
{
|
||||||
|
using (var hc = new TestHostContext(this))
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
var runner = new Runner.Listener.Runner();
|
||||||
|
hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
||||||
|
hc.SetSingleton<IJobNotification>(_jobNotification.Object);
|
||||||
|
hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
||||||
|
hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
||||||
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
|
hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
||||||
|
hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
||||||
|
runner.Initialize(hc);
|
||||||
|
var settings = new RunnerSettings
|
||||||
|
{
|
||||||
|
PoolId = 43242
|
||||||
|
};
|
||||||
|
|
||||||
|
var message = new TaskAgentMessage()
|
||||||
|
{
|
||||||
|
Body = JsonUtility.ToString(CreateJobRequestMessage("job1")),
|
||||||
|
MessageId = 4234,
|
||||||
|
MessageType = JobRequestMessageTypes.PipelineAgentJobRequest
|
||||||
|
};
|
||||||
|
|
||||||
|
var messages = new Queue<TaskAgentMessage>();
|
||||||
|
messages.Enqueue(message);
|
||||||
|
_configurationManager.Setup(x => x.LoadSettings())
|
||||||
|
.Returns(settings);
|
||||||
|
_configurationManager.Setup(x => x.IsConfigured())
|
||||||
|
.Returns(true);
|
||||||
|
_messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(Task.FromResult<bool>(true));
|
||||||
|
_messageListener.Setup(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(async () =>
|
||||||
|
{
|
||||||
|
if (0 == messages.Count)
|
||||||
|
{
|
||||||
|
await Task.Delay(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages.Dequeue();
|
||||||
|
});
|
||||||
|
_messageListener.Setup(x => x.DeleteSessionAsync())
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
_messageListener.Setup(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var runOnceJobCompleted = new TaskCompletionSource<bool>();
|
||||||
|
_jobDispatcher.Setup(x => x.RunOnceJobCompleted)
|
||||||
|
.Returns(runOnceJobCompleted);
|
||||||
|
_jobDispatcher.Setup(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), It.IsAny<bool>()))
|
||||||
|
.Callback(() =>
|
||||||
|
{
|
||||||
|
runOnceJobCompleted.TrySetResult(true);
|
||||||
|
});
|
||||||
|
_jobNotification.Setup(x => x.StartClient(It.IsAny<String>()))
|
||||||
|
.Callback(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
hc.EnqueueInstance<IJobDispatcher>(_jobDispatcher.Object);
|
||||||
|
|
||||||
|
_configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
|
||||||
|
//Act
|
||||||
|
var command = new CommandSettings(hc, new string[] { "run", "--once" });
|
||||||
|
Task<int> runnerTask = runner.ExecuteCommand(command);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
//wait for the runner to run one job and exit
|
||||||
|
await Task.WhenAny(runnerTask, Task.Delay(30000));
|
||||||
|
|
||||||
|
Assert.True(runnerTask.IsCompleted, $"{nameof(runner.ExecuteCommand)} timed out.");
|
||||||
|
Assert.True(!runnerTask.IsFaulted, runnerTask.Exception?.ToString());
|
||||||
|
Assert.True(runnerTask.Result == Constants.Runner.ReturnCode.Success);
|
||||||
|
|
||||||
|
_jobDispatcher.Verify(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), true), Times.Once(),
|
||||||
|
$"{nameof(_jobDispatcher.Object.Run)} was not invoked.");
|
||||||
|
_messageListener.Verify(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()), Times.AtLeastOnce());
|
||||||
|
_messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
||||||
|
_messageListener.Verify(x => x.DeleteSessionAsync(), Times.Once());
|
||||||
|
_messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()), Times.AtLeastOnce());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Runner")]
|
||||||
|
public async void TestRunOnceOnlyTakeOneJobMessage()
|
||||||
|
{
|
||||||
|
using (var hc = new TestHostContext(this))
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
var runner = new Runner.Listener.Runner();
|
||||||
|
hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
||||||
|
hc.SetSingleton<IJobNotification>(_jobNotification.Object);
|
||||||
|
hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
||||||
|
hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
||||||
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
|
hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
||||||
|
hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
||||||
|
runner.Initialize(hc);
|
||||||
|
var settings = new RunnerSettings
|
||||||
|
{
|
||||||
|
PoolId = 43242
|
||||||
|
};
|
||||||
|
|
||||||
|
var message1 = new TaskAgentMessage()
|
||||||
|
{
|
||||||
|
Body = JsonUtility.ToString(CreateJobRequestMessage("job1")),
|
||||||
|
MessageId = 4234,
|
||||||
|
MessageType = JobRequestMessageTypes.PipelineAgentJobRequest
|
||||||
|
};
|
||||||
|
var message2 = new TaskAgentMessage()
|
||||||
|
{
|
||||||
|
Body = JsonUtility.ToString(CreateJobRequestMessage("job1")),
|
||||||
|
MessageId = 4235,
|
||||||
|
MessageType = JobRequestMessageTypes.PipelineAgentJobRequest
|
||||||
|
};
|
||||||
|
|
||||||
|
var messages = new Queue<TaskAgentMessage>();
|
||||||
|
messages.Enqueue(message1);
|
||||||
|
messages.Enqueue(message2);
|
||||||
|
_configurationManager.Setup(x => x.LoadSettings())
|
||||||
|
.Returns(settings);
|
||||||
|
_configurationManager.Setup(x => x.IsConfigured())
|
||||||
|
.Returns(true);
|
||||||
|
_messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(Task.FromResult<bool>(true));
|
||||||
|
_messageListener.Setup(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(async () =>
|
||||||
|
{
|
||||||
|
if (0 == messages.Count)
|
||||||
|
{
|
||||||
|
await Task.Delay(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages.Dequeue();
|
||||||
|
});
|
||||||
|
_messageListener.Setup(x => x.DeleteSessionAsync())
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
_messageListener.Setup(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
|
||||||
|
var runOnceJobCompleted = new TaskCompletionSource<bool>();
|
||||||
|
_jobDispatcher.Setup(x => x.RunOnceJobCompleted)
|
||||||
|
.Returns(runOnceJobCompleted);
|
||||||
|
_jobDispatcher.Setup(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), It.IsAny<bool>()))
|
||||||
|
.Callback(() =>
|
||||||
|
{
|
||||||
|
runOnceJobCompleted.TrySetResult(true);
|
||||||
|
});
|
||||||
|
_jobNotification.Setup(x => x.StartClient(It.IsAny<String>()))
|
||||||
|
.Callback(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
hc.EnqueueInstance<IJobDispatcher>(_jobDispatcher.Object);
|
||||||
|
|
||||||
|
_configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
|
||||||
|
//Act
|
||||||
|
var command = new CommandSettings(hc, new string[] { "run", "--once" });
|
||||||
|
Task<int> runnerTask = runner.ExecuteCommand(command);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
//wait for the runner to run one job and exit
|
||||||
|
await Task.WhenAny(runnerTask, Task.Delay(30000));
|
||||||
|
|
||||||
|
Assert.True(runnerTask.IsCompleted, $"{nameof(runner.ExecuteCommand)} timed out.");
|
||||||
|
Assert.True(!runnerTask.IsFaulted, runnerTask.Exception?.ToString());
|
||||||
|
Assert.True(runnerTask.Result == Constants.Runner.ReturnCode.Success);
|
||||||
|
|
||||||
|
_jobDispatcher.Verify(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), true), Times.Once(),
|
||||||
|
$"{nameof(_jobDispatcher.Object.Run)} was not invoked.");
|
||||||
|
_messageListener.Verify(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()), Times.AtLeastOnce());
|
||||||
|
_messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
||||||
|
_messageListener.Verify(x => x.DeleteSessionAsync(), Times.Once());
|
||||||
|
_messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()), Times.Once());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
[Trait("Level", "L0")]
|
||||||
|
[Trait("Category", "Runner")]
|
||||||
|
public async void TestRunOnceHandleUpdateMessage()
|
||||||
|
{
|
||||||
|
using (var hc = new TestHostContext(this))
|
||||||
|
{
|
||||||
|
//Arrange
|
||||||
|
var runner = new Runner.Listener.Runner();
|
||||||
|
hc.SetSingleton<IConfigurationManager>(_configurationManager.Object);
|
||||||
|
hc.SetSingleton<IJobNotification>(_jobNotification.Object);
|
||||||
|
hc.SetSingleton<IMessageListener>(_messageListener.Object);
|
||||||
|
hc.SetSingleton<IPromptManager>(_promptManager.Object);
|
||||||
|
hc.SetSingleton<IRunnerServer>(_runnerServer.Object);
|
||||||
|
hc.SetSingleton<IRunnerCertificateManager>(_cert.Object);
|
||||||
|
hc.SetSingleton<IConfigurationStore>(_configStore.Object);
|
||||||
|
hc.SetSingleton<ISelfUpdater>(_updater.Object);
|
||||||
|
|
||||||
|
runner.Initialize(hc);
|
||||||
|
var settings = new RunnerSettings
|
||||||
|
{
|
||||||
|
PoolId = 43242,
|
||||||
|
AgentId = 5678
|
||||||
|
};
|
||||||
|
|
||||||
|
var message1 = new TaskAgentMessage()
|
||||||
|
{
|
||||||
|
Body = JsonUtility.ToString(new AgentRefreshMessage(settings.AgentId, "2.123.0")),
|
||||||
|
MessageId = 4234,
|
||||||
|
MessageType = AgentRefreshMessage.MessageType
|
||||||
|
};
|
||||||
|
|
||||||
|
var messages = new Queue<TaskAgentMessage>();
|
||||||
|
messages.Enqueue(message1);
|
||||||
|
_updater.Setup(x => x.SelfUpdate(It.IsAny<AgentRefreshMessage>(), It.IsAny<IJobDispatcher>(), It.IsAny<bool>(), It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(Task.FromResult(true));
|
||||||
|
_configurationManager.Setup(x => x.LoadSettings())
|
||||||
|
.Returns(settings);
|
||||||
|
_configurationManager.Setup(x => x.IsConfigured())
|
||||||
|
.Returns(true);
|
||||||
|
_messageListener.Setup(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(Task.FromResult<bool>(true));
|
||||||
|
_messageListener.Setup(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()))
|
||||||
|
.Returns(async () =>
|
||||||
|
{
|
||||||
|
if (0 == messages.Count)
|
||||||
|
{
|
||||||
|
await Task.Delay(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
return messages.Dequeue();
|
||||||
|
});
|
||||||
|
_messageListener.Setup(x => x.DeleteSessionAsync())
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
_messageListener.Setup(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()))
|
||||||
|
.Returns(Task.CompletedTask);
|
||||||
|
_jobNotification.Setup(x => x.StartClient(It.IsAny<String>()))
|
||||||
|
.Callback(() =>
|
||||||
|
{
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
hc.EnqueueInstance<IJobDispatcher>(_jobDispatcher.Object);
|
||||||
|
|
||||||
|
_configStore.Setup(x => x.IsServiceConfigured()).Returns(false);
|
||||||
|
//Act
|
||||||
|
var command = new CommandSettings(hc, new string[] { "run", "--once" });
|
||||||
|
Task<int> runnerTask = runner.ExecuteCommand(command);
|
||||||
|
|
||||||
|
//Assert
|
||||||
|
//wait for the runner to exit with right return code
|
||||||
|
await Task.WhenAny(runnerTask, Task.Delay(30000));
|
||||||
|
|
||||||
|
Assert.True(runnerTask.IsCompleted, $"{nameof(runner.ExecuteCommand)} timed out.");
|
||||||
|
Assert.True(!runnerTask.IsFaulted, runnerTask.Exception?.ToString());
|
||||||
|
Assert.True(runnerTask.Result == Constants.Runner.ReturnCode.RunOnceRunnerUpdating);
|
||||||
|
|
||||||
|
_updater.Verify(x => x.SelfUpdate(It.IsAny<AgentRefreshMessage>(), It.IsAny<IJobDispatcher>(), false, It.IsAny<CancellationToken>()), Times.Once);
|
||||||
|
_jobDispatcher.Verify(x => x.Run(It.IsAny<Pipelines.AgentJobRequestMessage>(), true), Times.Never());
|
||||||
|
_messageListener.Verify(x => x.GetNextMessageAsync(It.IsAny<CancellationToken>()), Times.AtLeastOnce());
|
||||||
|
_messageListener.Verify(x => x.CreateSessionAsync(It.IsAny<CancellationToken>()), Times.Once());
|
||||||
|
_messageListener.Verify(x => x.DeleteSessionAsync(), Times.Once());
|
||||||
|
_messageListener.Verify(x => x.DeleteMessageAsync(It.IsAny<TaskAgentMessage>()), Times.Once());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,8 +14,8 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
{
|
{
|
||||||
[Fact]
|
[Fact]
|
||||||
[Trait("Level", "L0")]
|
[Trait("Level", "L0")]
|
||||||
[Trait("Category", "Agent")]
|
[Trait("Category", "Runner")]
|
||||||
public void AgentInterfacesSpecifyDefaultImplementation()
|
public void RunnerInterfacesSpecifyDefaultImplementation()
|
||||||
{
|
{
|
||||||
// Validate all interfaces in the Listener assembly define a valid service locator attribute.
|
// Validate all interfaces in the Listener assembly define a valid service locator attribute.
|
||||||
// Otherwise, the interface needs to whitelisted.
|
// Otherwise, the interface needs to whitelisted.
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
private readonly ITraceManager _traceManager;
|
private readonly ITraceManager _traceManager;
|
||||||
private readonly Terminal _term;
|
private readonly Terminal _term;
|
||||||
private readonly SecretMasker _secretMasker;
|
private readonly SecretMasker _secretMasker;
|
||||||
private CancellationTokenSource _agentShutdownTokenSource = new CancellationTokenSource();
|
private CancellationTokenSource _runnerShutdownTokenSource = new CancellationTokenSource();
|
||||||
private string _suiteName;
|
private string _suiteName;
|
||||||
private string _testName;
|
private string _testName;
|
||||||
private Tracing _trace;
|
private Tracing _trace;
|
||||||
@@ -30,7 +30,7 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
private string _tempDirectoryRoot = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("D"));
|
private string _tempDirectoryRoot = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("D"));
|
||||||
private StartupType _startupType;
|
private StartupType _startupType;
|
||||||
public event EventHandler Unloading;
|
public event EventHandler Unloading;
|
||||||
public CancellationToken RunnerShutdownToken => _agentShutdownTokenSource.Token;
|
public CancellationToken RunnerShutdownToken => _runnerShutdownTokenSource.Token;
|
||||||
public ShutdownReason RunnerShutdownReason { get; private set; }
|
public ShutdownReason RunnerShutdownReason { get; private set; }
|
||||||
public ISecretMasker SecretMasker => _secretMasker;
|
public ISecretMasker SecretMasker => _secretMasker;
|
||||||
public TestHostContext(object testClass, [CallerMemberName] string testName = "")
|
public TestHostContext(object testClass, [CallerMemberName] string testName = "")
|
||||||
@@ -306,7 +306,7 @@ namespace GitHub.Runner.Common.Tests
|
|||||||
{
|
{
|
||||||
ArgUtil.NotNull(reason, nameof(reason));
|
ArgUtil.NotNull(reason, nameof(reason));
|
||||||
RunnerShutdownReason = reason;
|
RunnerShutdownReason = reason;
|
||||||
_agentShutdownTokenSource.Cancel();
|
_runnerShutdownTokenSource.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WritePerfCounter(string counter)
|
public void WritePerfCounter(string counter)
|
||||||
|
|||||||
@@ -183,62 +183,6 @@ namespace GitHub.Runner.Common.Tests.Worker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
|
||||||
[Trait("Level", "L0")]
|
|
||||||
[Trait("Category", "Worker")]
|
|
||||||
public void VerifyJobRequestMessagePiiDataIsScrubbed()
|
|
||||||
{
|
|
||||||
// Arrange
|
|
||||||
Pipelines.AgentJobRequestMessage message = CreateJobRequestMessage("jobwithpiidata");
|
|
||||||
|
|
||||||
// Populate PII variables
|
|
||||||
foreach (string piiVariable in Variables.PiiVariables)
|
|
||||||
{
|
|
||||||
message.Variables.Add(piiVariable, "MyPiiVariable");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string piiVariableSuffix in Variables.PiiArtifactVariableSuffixes)
|
|
||||||
{
|
|
||||||
message.Variables.Add($"{Variables.PiiArtifactVariablePrefix}.MyArtifact.{piiVariableSuffix}", "MyPiiVariable");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Populate the repository PII data
|
|
||||||
Pipelines.RepositoryResource repository = new Pipelines.RepositoryResource();
|
|
||||||
|
|
||||||
repository.Properties.Set(
|
|
||||||
Pipelines.RepositoryPropertyNames.VersionInfo,
|
|
||||||
new Pipelines.VersionInfo()
|
|
||||||
{
|
|
||||||
Author = "MyAuthor",
|
|
||||||
Message = "MyMessage"
|
|
||||||
});
|
|
||||||
|
|
||||||
message.Resources.Repositories.Add(repository);
|
|
||||||
|
|
||||||
// Act
|
|
||||||
Pipelines.AgentJobRequestMessage scrubbedMessage = WorkerUtilities.ScrubPiiData(message);
|
|
||||||
|
|
||||||
// Assert
|
|
||||||
foreach (string piiVariable in Variables.PiiVariables)
|
|
||||||
{
|
|
||||||
scrubbedMessage.Variables.TryGetValue(piiVariable, out VariableValue value);
|
|
||||||
|
|
||||||
Assert.Equal("[PII]", value.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (string piiVariableSuffix in Variables.PiiArtifactVariableSuffixes)
|
|
||||||
{
|
|
||||||
scrubbedMessage.Variables.TryGetValue($"{Variables.PiiArtifactVariablePrefix}.MyArtifact.{piiVariableSuffix}", out VariableValue value);
|
|
||||||
|
|
||||||
Assert.Equal("[PII]", value.Value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Pipelines.RepositoryResource scrubbedRepo = scrubbedMessage.Resources.Repositories[0];
|
|
||||||
Pipelines.VersionInfo scrubbedInfo = scrubbedRepo.Properties.Get<Pipelines.VersionInfo>(Pipelines.RepositoryPropertyNames.VersionInfo);
|
|
||||||
|
|
||||||
Assert.Equal("[PII]", scrubbedInfo.Author);
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool IsMessageIdentical(Pipelines.AgentJobRequestMessage source, Pipelines.AgentJobRequestMessage target)
|
private bool IsMessageIdentical(Pipelines.AgentJobRequestMessage source, Pipelines.AgentJobRequestMessage target)
|
||||||
{
|
{
|
||||||
if (source == null && target == null)
|
if (source == null && target == null)
|
||||||
|
|||||||
Reference in New Issue
Block a user