Refactor healthcheck logic to separate method to enable unit testing.

This commit is contained in:
JoannaaKL
2022-09-14 08:10:03 +00:00
parent b8aafc4ff1
commit 826cec2775
2 changed files with 51 additions and 12 deletions

View File

@@ -99,6 +99,11 @@ namespace GitHub.Runner.Worker
await StartContainerAsync(executionContext, container); await StartContainerAsync(executionContext, container);
} }
await RunContainersHealthcheck(executionContext, containers);
}
public async Task RunContainersHealthcheck(IExecutionContext executionContext, List<ContainerInfo> containers)
{
executionContext.Output("##[group]Waiting for all services to be ready"); executionContext.Output("##[group]Waiting for all services to be ready");
var unhealthyContainers = new List<ContainerInfo>(); var unhealthyContainers = new List<ContainerInfo>();
@@ -423,7 +428,7 @@ namespace GitHub.Runner.Worker
} }
} }
public async Task<string> Healthcheck(IExecutionContext executionContext, ContainerInfo container) private async Task<string> Healthcheck(IExecutionContext executionContext, ContainerInfo container)
{ {
string healthCheck = "--format=\"{{if .Config.Healthcheck}}{{print .State.Health.Status}}{{end}}\""; string healthCheck = "--format=\"{{if .Config.Healthcheck}}{{print .State.Health.Status}}{{end}}\"";
string serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault(); string serviceHealth = (await _dockerManager.DockerInspect(context: executionContext, dockerObject: container.ContainerId, options: healthCheck)).FirstOrDefault();
@@ -444,7 +449,7 @@ namespace GitHub.Runner.Worker
return serviceHealth; return serviceHealth;
} }
public async Task ContainerErrorLogs(IExecutionContext executionContext, ContainerInfo container) private async Task ContainerErrorLogs(IExecutionContext executionContext, ContainerInfo container)
{ {
await _dockerManager.DockerLogs(context: executionContext, containerId: container.ContainerId); await _dockerManager.DockerLogs(context: executionContext, containerId: container.ContainerId);
executionContext.Error($"Failed to initialize container {container.ContainerImage}"); executionContext.Error($"Failed to initialize container {container.ContainerImage}");

View File

@@ -6,6 +6,8 @@ using GitHub.Runner.Worker.Container.ContainerHooks;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using GitHub.DistributedTask.WebApi;
using System;
namespace GitHub.Runner.Common.Tests.Worker namespace GitHub.Runner.Common.Tests.Worker
{ {
@@ -18,37 +20,69 @@ namespace GitHub.Runner.Common.Tests.Worker
private Mock<IDockerCommandManager> _dockerManager; private Mock<IDockerCommandManager> _dockerManager;
private Mock<IContainerHookManager> _containerHookManager; private Mock<IContainerHookManager> _containerHookManager;
private ContainerOperationProvider containerOperationProvider; private ContainerOperationProvider containerOperationProvider;
private Mock<IJobServerQueue> serverQueue; private Mock<IJobServerQueue> serverQueue;
private Mock<IPagingLogger> pagingLogger; private Mock<IPagingLogger> pagingLogger;
private List<string> healthyDockerStatus = new List<string> { "healthy" }; private List<string> healthyDockerStatus = new List<string> { "healthy" };
private List<string> unhealthyDockerStatus = new List<string> { "unhealthy" };
private List<string> dockerLogs = new List<string> { "log1", "log2", "log3" }; private List<string> dockerLogs = new List<string> { "log1", "log2", "log3" };
private ContainerInfo containerInfo; List<ContainerInfo> containers = new List<ContainerInfo>();
[Fact] [Fact]
[Trait("Level", "L0")] [Trait("Level", "L0")]
[Trait("Category", "Worker")] [Trait("Category", "Worker")]
public async void Healthchecktest_healthyDocker() public async void RunServiceContainersHealthcheck_UnhealthyServiceContainer_AssertExceptionThrown()
{
//Arrange
Setup();
_dockerManager.Setup(x => x.DockerInspect(_ec.Object, It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(unhealthyDockerStatus));
//Act and Assert
await Assert.ThrowsAsync<InvalidOperationException>(() => containerOperationProvider.RunContainersHealthcheck(_ec.Object, containers));
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async void RunServiceContainersHealthcheck_UnhealthyServiceContainer_AssertFailedTask()
{
//Arrange
Setup();
_dockerManager.Setup(x => x.DockerInspect(_ec.Object, It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(unhealthyDockerStatus));
//Act
try
{
await containerOperationProvider.RunContainersHealthcheck(_ec.Object, containers);
}
catch (InvalidOperationException) { }
//Assert
Assert.Equal(TaskResult.Failed, _ec.Object.Result ?? TaskResult.Failed);
}
[Fact]
[Trait("Level", "L0")]
[Trait("Category", "Worker")]
public async void RunServiceContainersHealthcheck_healthyServiceContainer_AssertSucceededTask()
{ {
//Arrange //Arrange
Setup(); Setup();
_dockerManager.Setup(x => x.DockerInspect(_ec.Object, It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(healthyDockerStatus)); _dockerManager.Setup(x => x.DockerInspect(_ec.Object, It.IsAny<string>(), It.IsAny<string>())).Returns(Task.FromResult(healthyDockerStatus));
//Act //Act
var result = await containerOperationProvider.Healthcheck(_ec.Object, containerInfo); await containerOperationProvider.RunContainersHealthcheck(_ec.Object, containers);
//Assert //Assert
_dockerManager.Verify(dm => dm.DockerLogs(It.IsAny<IExecutionContext>(), It.IsAny<string>()), Times.Never()); Assert.Equal(TaskResult.Succeeded, _ec.Object.Result ?? TaskResult.Succeeded);
} }
private void Setup([CallerMemberName] string testName = "") private void Setup([CallerMemberName] string testName = "")
{ {
containerInfo = new ContainerInfo() { ContainerImage = "ubuntu:16.04" }; containers.Add(new ContainerInfo() { ContainerImage = "ubuntu:16.04" });
_hc = new TestHostContext(this, "name"); _hc = new TestHostContext(this, "name");
_ec = new Mock<IExecutionContext>(); _ec = new Mock<IExecutionContext>();
serverQueue = new Mock<IJobServerQueue>(); serverQueue = new Mock<IJobServerQueue>();