audit remarks work

This commit is contained in:
master
2025-12-30 16:10:34 +02:00
parent e6ee092c7a
commit c706b3d3e0
72 changed files with 9997 additions and 5323 deletions

View File

@@ -1,5 +1,6 @@
using System;
using System.IO;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
@@ -54,8 +55,20 @@ public sealed class ScannerDownloadVerifyTests
internal static class CommandHandlersTestShim
{
public static Task VerifyBundlePublicAsync(string path, ILogger logger, CancellationToken token)
=> typeof(CommandHandlers)
.GetMethod("VerifyBundleAsync", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Static)!
.Invoke(null, new object[] { path, logger, token }) as Task
?? Task.CompletedTask;
{
var method = typeof(CommandHandlers).GetMethod(
"VerifyBundleAsync",
BindingFlags.NonPublic | BindingFlags.Static,
binder: null,
types: new[] { typeof(string), typeof(ILogger), typeof(CancellationToken) },
modifiers: null);
if (method is null)
{
throw new MissingMethodException(nameof(CommandHandlers), "VerifyBundleAsync");
}
return method.Invoke(null, new object[] { path, logger, token }) as Task
?? Task.CompletedTask;
}
}

View File

@@ -0,0 +1,69 @@
using System;
using System.CommandLine;
using System.Linq;
using System.Threading;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using StellaOps.Cli.Commands;
using StellaOps.Cli.Configuration;
namespace StellaOps.Cli.Tests.Commands;
public sealed class ToolsCommandGroupTests
{
[Fact]
public void Create_ExposesToolsCommands()
{
using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None));
var services = new ServiceCollection().BuildServiceProvider();
var root = CommandFactory.Create(services, new StellaOpsCliOptions(), CancellationToken.None, loggerFactory);
var tools = Assert.Single(root.Subcommands, command => string.Equals(command.Name, "tools", StringComparison.Ordinal));
Assert.Contains(tools.Subcommands, command => string.Equals(command.Name, "policy-dsl-validate", StringComparison.Ordinal));
Assert.Contains(tools.Subcommands, command => string.Equals(command.Name, "policy-schema-export", StringComparison.Ordinal));
Assert.Contains(tools.Subcommands, command => string.Equals(command.Name, "policy-simulation-smoke", StringComparison.Ordinal));
}
[Fact]
public void ToolsCommand_PolicyDslValidator_HasExpectedOptions()
{
var command = BuildToolsCommand().Subcommands.First(c => c.Name == "policy-dsl-validate");
Assert.NotNull(FindOption(command, "--strict", "-s"));
Assert.NotNull(FindOption(command, "--json", "-j"));
Assert.Contains(command.Arguments, argument => string.Equals(argument.Name, "inputs", StringComparison.Ordinal));
}
[Fact]
public void ToolsCommand_PolicySchemaExporter_HasExpectedOptions()
{
var command = BuildToolsCommand().Subcommands.First(c => c.Name == "policy-schema-export");
Assert.NotNull(FindOption(command, "--output", "-o"));
Assert.NotNull(FindOption(command, "--repo-root", "-r"));
}
[Fact]
public void ToolsCommand_PolicySimulationSmoke_HasExpectedOptions()
{
var command = BuildToolsCommand().Subcommands.First(c => c.Name == "policy-simulation-smoke");
Assert.NotNull(FindOption(command, "--scenario-root", "-r"));
Assert.NotNull(FindOption(command, "--output", "-o"));
Assert.NotNull(FindOption(command, "--repo-root"));
Assert.NotNull(FindOption(command, "--fixed-time"));
}
private static Command BuildToolsCommand()
{
using var loggerFactory = LoggerFactory.Create(builder => builder.SetMinimumLevel(LogLevel.None));
return ToolsCommandGroup.BuildToolsCommand(loggerFactory, CancellationToken.None);
}
private static Option? FindOption(Command command, params string[] aliases)
{
return command.Options.FirstOrDefault(option =>
aliases.Any(alias => string.Equals(option.Name, alias, StringComparison.Ordinal) || option.Aliases.Contains(alias)));
}
}

View File

@@ -122,7 +122,8 @@ public sealed class CliIntegrationTests : IDisposable
// Act & Assert
var act = async () => await client.ScanAsync("slow/image:v1");
await act.Should().ThrowAsync<TimeoutException>();
await act.Should().ThrowAsync<Exception>()
.Where(ex => ex is TimeoutException || ex is TaskCanceledException);
}
[Fact]

View File

@@ -0,0 +1,65 @@
using System.Collections.Immutable;
using StellaOps.Cli.Replay;
using Xunit;
namespace StellaOps.Cli.Tests.Replay;
public sealed class RunManifestSerializerTests
{
[Fact]
public void Serialize_UsesCanonicalOrdering()
{
var manifest = CreateManifest();
var json1 = RunManifestSerializer.Serialize(manifest);
var json2 = RunManifestSerializer.Serialize(manifest);
Assert.Equal(json1, json2);
}
[Fact]
public void ComputeDigest_IsStable()
{
var manifest = CreateManifest();
var digest1 = RunManifestSerializer.ComputeDigest(manifest);
var digest2 = RunManifestSerializer.ComputeDigest(manifest);
Assert.Equal(digest1, digest2);
Assert.Equal(64, digest1.Length);
}
[Fact]
public void RoundTrip_PreservesFields()
{
var manifest = CreateManifest();
var json = RunManifestSerializer.Serialize(manifest);
var deserialized = RunManifestSerializer.Deserialize(json);
var normalized = RunManifestSerializer.Serialize(deserialized);
Assert.Equal(json, normalized);
}
private static RunManifest CreateManifest()
{
return new RunManifest
{
RunId = "run-1",
SchemaVersion = "1.0.0",
ArtifactDigests = ImmutableArray.Create(
new ArtifactDigest("sha256", new string('a', 64), "application/vnd.oci.image.layer.v1.tar", "example")),
SbomDigests = ImmutableArray.Create(
new SbomReference("cyclonedx-1.6", new string('b', 64), "sbom.json")),
FeedSnapshot = new FeedSnapshot("nvd", "2025.12.01", new string('c', 64), new DateTimeOffset(2025, 12, 1, 0, 0, 0, TimeSpan.Zero)),
PolicySnapshot = new PolicySnapshot("policy-1", new string('d', 64), ImmutableArray.Create("rule-1")),
ToolVersions = new ToolVersions("1.0.0", "1.0.0", "1.0.0", "1.0.0", ImmutableDictionary<string, string>.Empty),
CryptoProfile = new CryptoProfile("default", ImmutableArray.Create("root-1"), ImmutableArray.Create("sha256")),
EnvironmentProfile = new EnvironmentProfile("postgres-only", false, "16", null),
PrngSeed = 42,
CanonicalizationVersion = "1.0.0",
InitiatedAt = new DateTimeOffset(2025, 12, 1, 0, 0, 0, TimeSpan.Zero)
};
}
}