Fixed/simplified unit tests.

Close-over KeyValuePairs passed via IssueMetadata to ensure no deferred evaluation.
(An `IEnumerable<KeyValuePair<string, string>>` could very well be a mutable dictionary, so we want to capture its content in the moment -- not some future version of it.)
This commit is contained in:
John Wesley Walker III
2023-02-08 13:33:26 +00:00
parent 4eb9adc958
commit 14096a7ee4
10 changed files with 38 additions and 85 deletions

View File

@@ -586,14 +586,13 @@ namespace GitHub.Runner.Worker
var result = new Issue() {
Type = issueType,
Category = metadata?.Category,
IsInfrastructureIssue = metadata?.IsInfrastructureIssue ?? false,
Message = refinedMessage,
};
if (metadata != null)
{
result.Category = metadata.Category;
result.IsInfrastructureIssue = metadata.IsInfrastructureIssue;
foreach (var kvp in metadata.Data)
{
result[kvp.Key] = kvp.Value;

View File

@@ -21,7 +21,10 @@ namespace GitHub.Runner.Worker
this.Category = category;
this.IsInfrastructureIssue = infrastructureIssue;
this.LogMessageOverride = logMessageOverride;
this.Data = data;
// Close-over the incoming IEnumerable to force immediate evaluation.
var empty = Enumerable.Empty<KeyValuePair<string, string>>();
this.Data = new Dictionary<string, string>(data ?? empty);
}
public readonly string Category;

View File

@@ -2,6 +2,8 @@
using Xunit;
using GitHub.Runner.Sdk;
using System.Runtime.CompilerServices;
using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Worker;
namespace GitHub.Runner.Common.Tests
{
@@ -41,5 +43,26 @@ namespace GitHub.Runner.Common.Tests
Assert.True(Directory.Exists(testDataDir));
return testDataDir;
}
public static IReadOnlyIssue CreateTestIssue(IssueType type, string message, IssueMetadata metadata, bool writeToLog)
{
var result = new Issue()
{
Type = type,
Message = message,
};
if (metadata != null)
{
result.Category = metadata.Category;
result.IsInfrastructureIssue = metadata.IsInfrastructureIssue;
foreach (var kvp in metadata.Data)
{
result[kvp.Key] = kvp.Value;
}
}
return result;
}
}
}

View File

@@ -6,7 +6,6 @@ using GitHub.DistributedTask.Pipelines.ContextData;
using GitHub.DistributedTask.WebApi;
using GitHub.Runner.Worker;
using GitHub.Runner.Worker.Container;
using GitHub.Services.Common;
using Moq;
using Xunit;
using Pipelines = GitHub.DistributedTask.Pipelines;
@@ -94,19 +93,7 @@ namespace GitHub.Runner.Common.Tests.Worker
});
_ec.Setup(x => x.CreateIssue(It.IsAny<IssueType>(), It.IsAny<string>(), It.IsAny<IssueMetadata>(), It.IsAny<bool>()))
.Returns((IssueType type, string message, IssueMetadata metadata, bool writeToLog) =>
{
var result = new Issue()
{
Type = type,
Message = message,
Category = metadata?.Category,
IsInfrastructureIssue = metadata?.IsInfrastructureIssue ?? false
};
result.Data.AddRangeIfRangeNotNull(metadata?.Data);
return result;
});
.Returns(TestUtil.CreateTestIssue);
_ec.Setup(x => x.AddIssue(It.IsAny<IReadOnlyIssue>()))
.Callback((IReadOnlyIssue issue) =>
{

View File

@@ -2148,18 +2148,7 @@ runs:
_ec.Object.Global.Plan = new TaskOrchestrationPlanReference();
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>())).Callback((string tag, string message) => { _hc.GetTrace().Info($"[{tag}]{message}"); });
_ec.Setup(x => x.CreateIssue(It.IsAny<IssueType>(), It.IsAny<string>(), It.IsAny<IssueMetadata>(), It.IsAny<bool>()))
.Returns((IssueType type, string message, IssueMetadata metadata, bool writeToLog) =>
{
var result = new Issue()
{
Type = type,
Message = message,
Category = metadata?.Category,
IsInfrastructureIssue = metadata?.IsInfrastructureIssue ?? false
};
result.Data.AddRangeIfRangeNotNull(metadata?.Data);
return result;
});
.Returns(TestUtil.CreateTestIssue);
_ec.Setup(x => x.AddIssue(It.IsAny<IReadOnlyIssue>())).Callback((IReadOnlyIssue issue) => { _hc.GetTrace().Info($"[{issue.Type}]{issue.Message}"); });
_ec.Setup(x => x.GetGitHubContext("workspace")).Returns(Path.Combine(_workFolder, "actions", "actions"));

View File

@@ -862,19 +862,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>())).Callback((string tag, string message) => { _hc.GetTrace().Info($"{tag}{message}"); });
_ec.Setup(x => x.CreateIssue(It.IsAny<IssueType>(), It.IsAny<string>(), It.IsAny<IssueMetadata>(), It.IsAny<bool>()))
.Returns((IssueType type, string message, IssueMetadata metadata, bool writeToLog) =>
{
var result = new Issue()
{
Type = type,
Message = message,
Category = metadata?.Category,
IsInfrastructureIssue = metadata?.IsInfrastructureIssue ?? false
};
result.Data.AddRangeIfRangeNotNull(metadata?.Data);
return result;
});
.Returns(TestUtil.CreateTestIssue);
_ec.Setup(x => x.AddIssue(It.IsAny<IReadOnlyIssue>())).Callback((IReadOnlyIssue issue) => { _hc.GetTrace().Info($"[{issue.Type}]{issue.Message}"); });
}

View File

@@ -445,19 +445,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_ec.Object.Global.Variables = new Variables(_hc, new Dictionary<string, VariableValue>());
_ec.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>())).Callback((string tag, string message) => { _hc.GetTrace().Info($"[{tag}]{message}"); });
_ec.Setup(x => x.CreateIssue(It.IsAny<IssueType>(), It.IsAny<string>(), It.IsAny<IssueMetadata>(), It.IsAny<bool>()))
.Returns((IssueType type, string message, IssueMetadata metadata, bool writeToLog) =>
{
var result = new Issue()
{
Type = type,
Message = message,
Category = metadata?.Category,
IsInfrastructureIssue = metadata?.IsInfrastructureIssue ?? false
};
result.Data.AddRangeIfRangeNotNull(metadata?.Data);
return result;
});
.Returns(TestUtil.CreateTestIssue);
_ec.Setup(x => x.AddIssue(It.IsAny<IReadOnlyIssue>())).Callback((IReadOnlyIssue issue) => { _hc.GetTrace().Info($"[{issue.Type}]{issue.Message}"); });
_hc.SetSingleton<IActionManager>(_actionManager.Object);

View File

@@ -255,19 +255,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_trace.Info($"Issue '{issue.Type}': {issue.Message}");
});
_executionContext.Setup(x => x.CreateIssue(It.IsAny<IssueType>(), It.IsAny<string>(), It.IsAny<IssueMetadata>(), It.IsAny<bool>()))
.Returns((IssueType type, string message, IssueMetadata metadata, bool writeToLog) =>
{
var result = new Issue()
{
Type = type,
Message = message,
Category = metadata?.Category,
IsInfrastructureIssue = metadata?.IsInfrastructureIssue ?? false
};
result.Data.AddRangeIfRangeNotNull(metadata?.Data);
return result;
});
.Returns(TestUtil.CreateTestIssue);
_executionContext.Setup(x => x.Write(It.IsAny<string>(), It.IsAny<string>()))
.Callback((string tag, string message) =>
{

View File

@@ -246,9 +246,9 @@ namespace GitHub.Runner.Common.Tests.Worker
embeddedStep.AddIssue(embeddedStep.CreateIssue(IssueType.Warning, "warning annotation that should have step and line number information", null, true));
embeddedStep.AddIssue(embeddedStep.CreateIssue(IssueType.Notice, "notice annotation that should have step and line number information", null, true));
jobServerQueue.Verify(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.Is<TimelineRecord>(t => t.Issues.Where(i => i.Data.ContainsKey("stepNumber") && i.Data.ContainsKey("logFileLineNumber") && i.Type == IssueType.Error).Count() == 1)), Times.AtLeastOnce);
jobServerQueue.Verify(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.Is<TimelineRecord>(t => t.Issues.Where(i => i.Data.ContainsKey("stepNumber") && i.Data.ContainsKey("logFileLineNumber") && i.Type == IssueType.Warning).Count() == 1)), Times.AtLeastOnce);
jobServerQueue.Verify(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.Is<TimelineRecord>(t => t.Issues.Where(i => i.Data.ContainsKey("stepNumber") && i.Data.ContainsKey("logFileLineNumber") && i.Type == IssueType.Notice).Count() == 1)), Times.AtLeastOnce);
jobServerQueue.Verify(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.Is<TimelineRecord>(t => t.Issues.Where(i => i["stepNumber"] != null && i["logFileLineNumber"] != null && i.Type == IssueType.Error).Count() == 1)), Times.AtLeastOnce);
jobServerQueue.Verify(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.Is<TimelineRecord>(t => t.Issues.Where(i => i["stepNumber"] != null && i["logFileLineNumber"] != null && i.Type == IssueType.Warning).Count() == 1)), Times.AtLeastOnce);
jobServerQueue.Verify(x => x.QueueTimelineRecordUpdate(It.IsAny<Guid>(), It.Is<TimelineRecord>(t => t.Issues.Where(i => i["stepNumber"] != null && i["logFileLineNumber"] != null && i.Type == IssueType.Notice).Count() == 1)), Times.AtLeastOnce);
}
}

View File

@@ -984,19 +984,7 @@ namespace GitHub.Runner.Common.Tests.Worker
_onMatcherChanged = handler;
});
_executionContext.Setup(x => x.CreateIssue(It.IsAny<DTWebApi.IssueType>(), It.IsAny<string>(), It.IsAny<IssueMetadata>(), It.IsAny<bool>()))
.Returns((DTWebApi.IssueType type, string message, IssueMetadata metadata, bool writeToLog) =>
{
var result = new DTWebApi.Issue()
{
Type = type,
Message = message,
Category = metadata?.Category,
IsInfrastructureIssue = metadata?.IsInfrastructureIssue ?? false
};
result.Data.AddRangeIfRangeNotNull(metadata?.Data);
return result;
});
.Returns(TestUtil.CreateTestIssue);
_executionContext.Setup(x => x.AddIssue(It.IsAny<DTWebApi.IReadOnlyIssue>()))
.Callback((DTWebApi.IReadOnlyIssue issue) =>
{