Some checks failed
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Export Center CI / export-ci (push) Has been cancelled
devportal-offline / build-offline (push) Has been cancelled
134 lines
5.1 KiB
C#
134 lines
5.1 KiB
C#
using Microsoft.Extensions.Logging.Abstractions;
|
|
using Microsoft.Extensions.Options;
|
|
using StellaOps.TaskRunner.Core.Execution;
|
|
using StellaOps.TaskRunner.Core.Planning;
|
|
using StellaOps.TaskRunner.Infrastructure.Execution;
|
|
using StellaOps.TaskRunner.Worker.Services;
|
|
|
|
namespace StellaOps.TaskRunner.Tests;
|
|
|
|
public sealed class BundleIngestionStepExecutorTests
|
|
{
|
|
[Fact]
|
|
public async Task ExecuteAsync_ValidBundle_CopiesAndSucceeds()
|
|
{
|
|
using var temp = new TempDirectory();
|
|
var source = Path.Combine(temp.Path, "bundle.tgz");
|
|
await File.WriteAllTextAsync(source, "bundle-data");
|
|
var checksum = "3e25960a79dbc69b674cd4ec67a72c62b3aa32b1d4d216177a5ffcc6f46673b5"; // sha256 of "bundle-data"
|
|
|
|
var options = Options.Create(new PackRunWorkerOptions { ArtifactsPath = temp.Path });
|
|
var executor = new BundleIngestionStepExecutor(options, NullLogger<BundleIngestionStepExecutor>.Instance);
|
|
|
|
var step = CreateStep("builtin:bundle.ingest", new Dictionary<string, TaskPackPlanParameterValue>
|
|
{
|
|
["path"] = Value(source),
|
|
["checksum"] = Value(checksum)
|
|
});
|
|
|
|
var result = await executor.ExecuteAsync(step, step.Parameters, CancellationToken.None);
|
|
|
|
Assert.True(result.Succeeded);
|
|
var staged = Path.Combine(temp.Path, "bundles", checksum, "bundle.tgz");
|
|
Assert.True(File.Exists(staged));
|
|
Assert.Equal(await File.ReadAllBytesAsync(source), await File.ReadAllBytesAsync(staged));
|
|
|
|
var metadataPath = Path.Combine(temp.Path, "bundles", checksum, "metadata.json");
|
|
Assert.True(File.Exists(metadataPath));
|
|
var metadata = await File.ReadAllTextAsync(metadataPath);
|
|
Assert.Contains(checksum, metadata, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExecuteAsync_ChecksumMismatch_Fails()
|
|
{
|
|
using var temp = new TempDirectory();
|
|
var source = Path.Combine(temp.Path, "bundle.tgz");
|
|
await File.WriteAllTextAsync(source, "bundle-data");
|
|
|
|
var options = Options.Create(new PackRunWorkerOptions { ArtifactsPath = temp.Path });
|
|
var executor = new BundleIngestionStepExecutor(options, NullLogger<BundleIngestionStepExecutor>.Instance);
|
|
|
|
var step = CreateStep("builtin:bundle.ingest", new Dictionary<string, TaskPackPlanParameterValue>
|
|
{
|
|
["path"] = Value(source),
|
|
["checksum"] = Value("deadbeef")
|
|
});
|
|
|
|
var result = await executor.ExecuteAsync(step, step.Parameters, CancellationToken.None);
|
|
|
|
Assert.False(result.Succeeded);
|
|
Assert.Contains("Checksum mismatch", result.Error, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExecuteAsync_MissingChecksum_Fails()
|
|
{
|
|
using var temp = new TempDirectory();
|
|
var source = Path.Combine(temp.Path, "bundle.tgz");
|
|
await File.WriteAllTextAsync(source, "bundle-data");
|
|
|
|
var options = Options.Create(new PackRunWorkerOptions { ArtifactsPath = temp.Path });
|
|
var executor = new BundleIngestionStepExecutor(options, NullLogger<BundleIngestionStepExecutor>.Instance);
|
|
|
|
var step = CreateStep("builtin:bundle.ingest", new Dictionary<string, TaskPackPlanParameterValue>
|
|
{
|
|
["path"] = Value(source)
|
|
});
|
|
|
|
var result = await executor.ExecuteAsync(step, step.Parameters, CancellationToken.None);
|
|
|
|
Assert.False(result.Succeeded);
|
|
Assert.Contains("Checksum is required", result.Error, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task ExecuteAsync_UnknownUses_NoOpSuccess()
|
|
{
|
|
var executor = new BundleIngestionStepExecutor(
|
|
Options.Create(new PackRunWorkerOptions { ArtifactsPath = Path.GetTempPath() }),
|
|
NullLogger<BundleIngestionStepExecutor>.Instance);
|
|
|
|
var step = CreateStep("builtin:noop", new Dictionary<string, TaskPackPlanParameterValue>());
|
|
var result = await executor.ExecuteAsync(step, step.Parameters, CancellationToken.None);
|
|
|
|
Assert.True(result.Succeeded);
|
|
}
|
|
|
|
private static TaskPackPlanParameterValue Value(string literal)
|
|
=> new(JsonValue.Create(literal), null, null, false);
|
|
|
|
private static PackRunExecutionStep CreateStep(string uses, IReadOnlyDictionary<string, TaskPackPlanParameterValue> parameters)
|
|
=> new(
|
|
id: "ingest",
|
|
templateId: "ingest",
|
|
kind: PackRunStepKind.Run,
|
|
enabled: true,
|
|
uses: uses,
|
|
parameters: parameters,
|
|
approvalId: null,
|
|
gateMessage: null,
|
|
maxParallel: null,
|
|
continueOnError: false,
|
|
children: PackRunExecutionStep.EmptyChildren);
|
|
|
|
private sealed class TempDirectory : IDisposable
|
|
{
|
|
public TempDirectory()
|
|
{
|
|
Path = System.IO.Path.Combine(System.IO.Path.GetTempPath(), Guid.NewGuid().ToString("n"));
|
|
Directory.CreateDirectory(Path);
|
|
}
|
|
|
|
public string Path { get; }
|
|
|
|
public void Dispose()
|
|
{
|
|
if (Directory.Exists(Path))
|
|
{
|
|
Directory.Delete(Path, recursive: true);
|
|
}
|
|
}
|
|
}
|
|
}
|