Merge all changes

This commit is contained in:
StellaOps Bot
2026-01-08 08:54:27 +02:00
parent 589de352c2
commit 110591d6bf
381 changed files with 2237 additions and 1939 deletions

View File

@@ -149,8 +149,8 @@ public sealed class BootstrapPackBuilderTests : IDisposable
Assert.Contains("checksums.txt", fileNames);
Assert.Contains("images/oci-layout", fileNames);
Assert.Contains("images/index.json", fileNames);
Assert.True(fileNames.Any(f => f.StartsWith("charts/")));
Assert.True(fileNames.Any(f => f.StartsWith("images/blobs/")));
Assert.Contains(fileNames, f => f.StartsWith("charts/"));
Assert.Contains(fileNames, f => f.StartsWith("images/blobs/"));
}
[Trait("Category", TestCategories.Unit)]

View File

@@ -15,10 +15,11 @@ public sealed class MigrationScriptTests
Assert.True(result);
Assert.NotNull(script);
Assert.Equal(1, script.Version);
Assert.Equal("001_initial_schema.sql", script.Name);
Assert.Equal(sql, script.Sql);
Assert.NotEmpty(script.Sha256);
var scriptValue = script!;
Assert.Equal(1, scriptValue.Version);
Assert.Equal("001_initial_schema.sql", scriptValue.Name);
Assert.Equal(sql, scriptValue.Sql);
Assert.NotEmpty(scriptValue.Sha256);
}
[Fact]
@@ -31,7 +32,7 @@ public sealed class MigrationScriptTests
Assert.True(result);
Assert.NotNull(script);
Assert.Equal(123, script.Version);
Assert.Equal(123, script!.Version);
}
[Fact]
@@ -44,7 +45,7 @@ public sealed class MigrationScriptTests
Assert.True(result);
Assert.NotNull(script);
Assert.Equal(1000, script.Version);
Assert.Equal(1000, script!.Version);
}
[Fact]
@@ -82,7 +83,7 @@ public sealed class MigrationScriptTests
Assert.NotNull(script1);
Assert.NotNull(script2);
Assert.Equal(script1.Sha256, script2.Sha256);
Assert.Equal(script1!.Sha256, script2!.Sha256);
}
[Fact]
@@ -97,7 +98,7 @@ public sealed class MigrationScriptTests
Assert.NotNull(scriptUnix);
Assert.NotNull(scriptWindows);
Assert.Equal(scriptUnix.Sha256, scriptWindows.Sha256);
Assert.Equal(scriptUnix!.Sha256, scriptWindows!.Sha256);
}
[Fact]
@@ -112,7 +113,7 @@ public sealed class MigrationScriptTests
Assert.NotNull(script1);
Assert.NotNull(script2);
Assert.NotEqual(script1.Sha256, script2.Sha256);
Assert.NotEqual(script1!.Sha256, script2!.Sha256);
}
[Fact]
@@ -124,7 +125,7 @@ public sealed class MigrationScriptTests
_ = TryCreateMigrationScript(resourceName, sql, out var script);
Assert.NotNull(script);
Assert.Matches("^[0-9a-f]{64}$", script.Sha256);
Assert.Matches("^[0-9a-f]{64}$", script!.Sha256);
}
// Helper to access internal MigrationScript via reflection

View File

@@ -1,10 +1,11 @@
using System.Formats.Tar;
using System.IO.Compression;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Linq;
using System.Threading;
using StellaOps.ExportCenter.Core.DevPortalOffline;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.ExportCenter.Tests;
@@ -55,7 +56,7 @@ public sealed class DevPortalOfflineBundleBuilderTests
var fixedNow = new DateTimeOffset(2025, 11, 4, 12, 30, 0, TimeSpan.Zero);
var builder = new DevPortalOfflineBundleBuilder(new FakeCryptoHash(), new FixedTimeProvider(fixedNow));
var result = builder.Build(request, CancellationToken.None);
var result = builder.Build(request, TestContext.Current.CancellationToken);
Assert.Equal(request.BundleId, result.Manifest.BundleId);
Assert.Equal("devportal-offline/v1", result.Manifest.Version);
@@ -136,7 +137,7 @@ public sealed class DevPortalOfflineBundleBuilderTests
var builder = new DevPortalOfflineBundleBuilder(new FakeCryptoHash(), new FixedTimeProvider(DateTimeOffset.UtcNow));
var request = new DevPortalOfflineBundleRequest(Guid.NewGuid());
var exception = Assert.Throws<InvalidOperationException>(() => builder.Build(request, CancellationToken.None));
var exception = Assert.Throws<InvalidOperationException>(() => builder.Build(request, TestContext.Current.CancellationToken));
Assert.Contains("does not contain any files", exception.Message, StringComparison.Ordinal);
}
@@ -153,7 +154,7 @@ public sealed class DevPortalOfflineBundleBuilderTests
File.WriteAllText(Path.Combine(portalRoot, "index.html"), "<html/>");
var builder = new DevPortalOfflineBundleBuilder(new FakeCryptoHash(), new FixedTimeProvider(DateTimeOffset.UtcNow));
var result = builder.Build(new DevPortalOfflineBundleRequest(Guid.NewGuid(), portalRoot), CancellationToken.None);
var result = builder.Build(new DevPortalOfflineBundleRequest(Guid.NewGuid(), portalRoot), TestContext.Current.CancellationToken);
Assert.Single(result.Manifest.Entries);
Assert.True(result.Manifest.Sources.PortalIncluded);
@@ -178,7 +179,7 @@ public sealed class DevPortalOfflineBundleBuilderTests
var missing = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
var request = new DevPortalOfflineBundleRequest(Guid.NewGuid(), missing);
Assert.Throws<DirectoryNotFoundException>(() => builder.Build(request, CancellationToken.None));
Assert.Throws<DirectoryNotFoundException>(() => builder.Build(request, TestContext.Current.CancellationToken));
}
private static string CalculateFileHash(string path)

View File

@@ -6,9 +6,9 @@ using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using StellaOps.ExportCenter.Core.DevPortalOffline;
using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.ExportCenter.Core.DevPortalOffline;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.ExportCenter.Tests;
@@ -56,7 +56,7 @@ public class DevPortalOfflineJobTests
var outcome = await job.ExecuteAsync(
new DevPortalOfflineJobRequest(request, "exports/devportal", "bundle.tgz"),
CancellationToken.None);
TestContext.Current.CancellationToken);
var expectedPrefix = $"exports/devportal/{bundleId:D}";
Assert.Equal($"{expectedPrefix}/manifest.json", outcome.ManifestStorage.StorageKey);
@@ -103,7 +103,7 @@ public class DevPortalOfflineJobTests
var request = new DevPortalOfflineBundleRequest(Guid.NewGuid(), portalRoot);
var outcome = await job.ExecuteAsync(
new DevPortalOfflineJobRequest(request, "exports", "../bundle.tgz"),
CancellationToken.None);
TestContext.Current.CancellationToken);
var expectedPrefix = $"exports/{request.BundleId:D}";
Assert.Equal($"{expectedPrefix}/bundle.tgz", outcome.BundleStorage.StorageKey);

View File

@@ -1,6 +1,8 @@
using System.Text.Json;
using System.Threading;
using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.ExportCenter.Core.EvidenceCache;
using Xunit;
namespace StellaOps.ExportCenter.Tests.EvidenceCache;
@@ -38,7 +40,7 @@ public sealed class LocalEvidenceCacheServiceTests
}
};
var cacheResult = await service.CacheEvidenceAsync(temp.Path, bundle, CancellationToken.None);
var cacheResult = await service.CacheEvidenceAsync(temp.Path, bundle, TestContext.Current.CancellationToken);
Assert.True(cacheResult.Success);
var cacheDir = Path.Combine(temp.Path, ".evidence");
@@ -47,7 +49,7 @@ public sealed class LocalEvidenceCacheServiceTests
Assert.True(File.Exists(Path.Combine(cacheDir, "bundles", "alert-1.evidence.json")));
Assert.True(File.Exists(Path.Combine(cacheDir, "enrichment_queue.json")));
var statistics = await service.GetStatisticsAsync(temp.Path, CancellationToken.None);
var statistics = await service.GetStatisticsAsync(temp.Path, TestContext.Current.CancellationToken);
Assert.Equal(1, statistics.TotalBundles);
Assert.Equal(0, statistics.FullyAvailable);
@@ -73,13 +75,13 @@ public sealed class LocalEvidenceCacheServiceTests
AttemptCount = 0
};
await service.QueueEnrichmentAsync(temp.Path, request, CancellationToken.None);
await service.QueueEnrichmentAsync(temp.Path, request with { Reason = "still missing" }, CancellationToken.None);
await service.QueueEnrichmentAsync(temp.Path, request, TestContext.Current.CancellationToken);
await service.QueueEnrichmentAsync(temp.Path, request with { Reason = "still missing" }, TestContext.Current.CancellationToken);
var queuePath = Path.Combine(temp.Path, ".evidence", "enrichment_queue.json");
Assert.True(File.Exists(queuePath));
using var document = JsonDocument.Parse(await File.ReadAllTextAsync(queuePath, CancellationToken.None));
using var document = JsonDocument.Parse(await File.ReadAllTextAsync(queuePath, TestContext.Current.CancellationToken));
var requests = document.RootElement.GetProperty("requests");
Assert.Equal(1, requests.GetArrayLength());
Assert.Equal("alert-1", requests[0].GetProperty("alert_id").GetString());
@@ -102,16 +104,16 @@ public sealed class LocalEvidenceCacheServiceTests
QueuedAt = DateTimeOffset.MinValue,
AttemptCount = 0
},
CancellationToken.None);
TestContext.Current.CancellationToken);
var result = await service.ProcessEnrichmentQueueAsync(temp.Path, CancellationToken.None);
var result = await service.ProcessEnrichmentQueueAsync(temp.Path, TestContext.Current.CancellationToken);
Assert.Equal(0, result.ProcessedCount);
Assert.Equal(1, result.FailedCount);
Assert.Equal(1, result.RemainingCount);
var queuePath = Path.Combine(temp.Path, ".evidence", "enrichment_queue.json");
using var document = JsonDocument.Parse(await File.ReadAllTextAsync(queuePath, CancellationToken.None));
using var document = JsonDocument.Parse(await File.ReadAllTextAsync(queuePath, TestContext.Current.CancellationToken));
var requests = document.RootElement.GetProperty("requests");
Assert.Equal(1, requests.GetArrayLength());
Assert.Equal(1, requests[0].GetProperty("attempt_count").GetInt32());

View File

@@ -35,7 +35,7 @@ public sealed class ExportNotificationEmitterTests
Assert.True(result.Success);
Assert.Equal(1, result.AttemptCount);
Assert.Equal(1, _sink.Count);
Assert.Single(_sink);
}
[Trait("Category", TestCategories.Unit)]
@@ -84,7 +84,7 @@ public sealed class ExportNotificationEmitterTests
var result = await emitter.EmitAirgapReadyAsync(notification);
Assert.False(result.Success);
Assert.Equal(1, _dlq.Count);
Assert.Single(_dlq);
}
[Trait("Category", TestCategories.Unit)]
@@ -132,7 +132,7 @@ public sealed class ExportNotificationEmitterTests
Assert.True(result.Success);
Assert.Equal(3, result.AttemptCount);
Assert.Equal(0, _dlq.Count);
Assert.Empty(_dlq);
}
[Trait("Category", TestCategories.Unit)]
@@ -221,7 +221,7 @@ public sealed class ExportNotificationEmitterTests
var result = await emitter.EmitAirgapReadyAsync(notification);
Assert.False(result.Success);
Assert.Equal(1, _dlq.Count);
Assert.Single(_dlq);
}
[Trait("Category", TestCategories.Unit)]
@@ -451,7 +451,7 @@ public sealed class InMemoryExportNotificationSinkTests
await sink.PublishAsync("test.channel", "{\"test\":true}");
Assert.Equal(1, sink.Count);
Assert.Single(sink);
}
[Trait("Category", TestCategories.Unit)]
@@ -481,7 +481,7 @@ public sealed class InMemoryExportNotificationSinkTests
await sink.PublishAsync("test", "message2");
sink.Clear();
Assert.Equal(0, sink.Count);
Assert.Empty(sink);
}
}
@@ -496,7 +496,7 @@ public sealed class InMemoryExportNotificationDlqTests
await dlq.EnqueueAsync(entry);
Assert.Equal(1, dlq.Count);
Assert.Single(dlq);
}
[Trait("Category", TestCategories.Unit)]

View File

@@ -7,7 +7,7 @@ using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using StellaOps.ExportCenter.Core.DevPortalOffline;
using StellaOps.ExportCenter.Infrastructure.DevPortalOffline;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.ExportCenter.Tests;
@@ -37,7 +37,7 @@ public class HmacDevPortalOfflineManifestSignerTests
var rootHash = Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(manifest))).ToLowerInvariant();
var bundleId = Guid.Parse("9ca2aafb-42b7-4df9-85f7-5a1d46c4e0ef");
var document = await signer.SignAsync(bundleId, manifest, rootHash, CancellationToken.None);
var document = await signer.SignAsync(bundleId, manifest, rootHash, TestContext.Current.CancellationToken);
Assert.Equal(bundleId, document.BundleId);
Assert.Equal(rootHash, document.RootHash);
@@ -73,7 +73,7 @@ public class HmacDevPortalOfflineManifestSignerTests
NullLogger<HmacDevPortalOfflineManifestSigner>.Instance);
await Assert.ThrowsAsync<NotSupportedException>(() =>
signer.SignAsync(Guid.NewGuid(), "{}", "root", CancellationToken.None));
signer.SignAsync(Guid.NewGuid(), "{}", "root", TestContext.Current.CancellationToken));
}
private static string ComputeExpectedSignature(DevPortalOfflineManifestSigningOptions options, string manifest)

View File

@@ -1,6 +1,7 @@
using System.IO.Compression;
using System.Threading;
using StellaOps.ExportCenter.RiskBundles;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.ExportCenter.Tests;
@@ -25,7 +26,7 @@ public sealed class RiskBundleBuilderTests
});
var builder = new RiskBundleBuilder();
var cancellation = CancellationToken.None;
var cancellation = TestContext.Current.CancellationToken;
var result = builder.Build(request, cancellation);
Assert.Equal(2, result.Manifest.Providers.Count);
@@ -66,7 +67,7 @@ public sealed class RiskBundleBuilderTests
var builder = new RiskBundleBuilder();
Assert.Throws<InvalidOperationException>(() => builder.Build(request, CancellationToken.None));
Assert.Throws<InvalidOperationException>(() => builder.Build(request, TestContext.Current.CancellationToken));
}
private sealed class TempDir : IDisposable

View File

@@ -4,7 +4,7 @@ using System.Text;
using System.Text.Json;
using Microsoft.Extensions.Logging.Abstractions;
using StellaOps.ExportCenter.RiskBundles;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.ExportCenter.Tests;
@@ -31,7 +31,7 @@ public sealed class RiskBundleJobTests
store,
NullLogger<RiskBundleJob>.Instance);
var outcome = await job.ExecuteAsync(new RiskBundleJobRequest(buildRequest), CancellationToken.None);
var outcome = await job.ExecuteAsync(new RiskBundleJobRequest(buildRequest), TestContext.Current.CancellationToken);
Assert.Equal("risk-bundles/provider-manifest.json", outcome.ManifestStorage.StorageKey);
Assert.Equal("risk-bundles/signatures/provider-manifest.dsse", outcome.ManifestSignatureStorage.StorageKey);

View File

@@ -1,6 +1,8 @@
using System.Text.Json;
using System.Threading;
using StellaOps.Cryptography;
using StellaOps.ExportCenter.RiskBundles;
using Xunit;
using StellaOps.TestKit;
namespace StellaOps.ExportCenter.Tests;
@@ -14,7 +16,7 @@ public class RiskBundleSignerTests
var signer = new HmacRiskBundleManifestSigner(new FakeCryptoHmac(), "secret-key", "test-key");
const string manifest = "{\"foo\":1}";
var doc = await signer.SignAsync(manifest, CancellationToken.None);
var doc = await signer.SignAsync(manifest, TestContext.Current.CancellationToken);
Assert.Equal("application/stellaops.risk-bundle.provider-manifest+json", doc.PayloadType);
Assert.NotNull(doc.Payload);

View File

@@ -370,7 +370,7 @@ public class ExportVerificationServiceTests
var result = await _service.VerifyAsync(request);
// The existing file should verify fine
Assert.True(result.FileHashes.Any(h => h.IsValid));
Assert.Contains(result.FileHashes, h => h.IsValid);
}
[Fact]