Add unit tests for PackRunAttestation and SealedInstallEnforcer
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
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
Policy Lint & Smoke / policy-lint (push) Has been cancelled
release-manifest-verify / verify (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
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
Policy Lint & Smoke / policy-lint (push) Has been cancelled
release-manifest-verify / verify (push) Has been cancelled
- Implement comprehensive tests for PackRunAttestationService, covering attestation generation, verification, and event emission. - Add tests for SealedInstallEnforcer to validate sealed install requirements and enforcement logic. - Introduce a MonacoLoaderService stub for testing purposes to prevent Monaco workers/styles from loading during Karma runs.
This commit is contained in:
@@ -9,8 +9,8 @@
|
||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.Scheduler.Queue\StellaOps.Scheduler.Queue.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Scheduler.Storage.Postgres\StellaOps.Scheduler.Storage.Postgres.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Scheduler.Worker\StellaOps.Scheduler.Worker.csproj" />
|
||||
<ProjectReference Include="..\__Libraries\StellaOps.Scheduler.Queue\StellaOps.Scheduler.Queue.csproj" />
|
||||
<ProjectReference Include="..\__Libraries\StellaOps.Scheduler.Storage.Postgres\StellaOps.Scheduler.Storage.Postgres.csproj" />
|
||||
<ProjectReference Include="..\__Libraries\StellaOps.Scheduler.Worker\StellaOps.Scheduler.Worker.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -99,18 +99,6 @@ Global
|
||||
{382FA1C0-5F5F-424A-8485-7FED0ADE9F6B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{382FA1C0-5F5F-424A-8485-7FED0ADE9F6B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{382FA1C0-5F5F-424A-8485-7FED0ADE9F6B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Release|x64.Build.0 = Release|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2}.Release|x86.Build.0 = Release|Any CPU
|
||||
{56209C24-3CE7-4F8E-8B8C-F052CB919DE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{56209C24-3CE7-4F8E-8B8C-F052CB919DE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{56209C24-3CE7-4F8E-8B8C-F052CB919DE2}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
@@ -363,18 +351,6 @@ Global
|
||||
{7C22F6B7-095E-459B-BCCF-87098EA9F192}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7C22F6B7-095E-459B-BCCF-87098EA9F192}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7C22F6B7-095E-459B-BCCF-87098EA9F192}.Release|x86.Build.0 = Release|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Release|x64.Build.0 = Release|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7B4C9EAC-316E-4890-A715-7BB9C1577F96}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7B4C9EAC-316E-4890-A715-7BB9C1577F96}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7B4C9EAC-316E-4890-A715-7BB9C1577F96}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
@@ -441,7 +417,6 @@ Global
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{382FA1C0-5F5F-424A-8485-7FED0ADE9F6B} = {41F15E67-7190-CF23-3BC4-77E87134CADD}
|
||||
{33770BC5-6802-45AD-A866-10027DD360E2} = {41F15E67-7190-CF23-3BC4-77E87134CADD}
|
||||
{56209C24-3CE7-4F8E-8B8C-F052CB919DE2} = {41F15E67-7190-CF23-3BC4-77E87134CADD}
|
||||
{167198F1-43CF-42F4-BEF2-5ABC87116A37} = {41F15E67-7190-CF23-3BC4-77E87134CADD}
|
||||
{6A62C12A-8742-4D1E-AEA7-8DDC3C722AC4} = {41F15E67-7190-CF23-3BC4-77E87134CADD}
|
||||
@@ -451,7 +426,6 @@ Global
|
||||
{5ED2BF16-72CE-4DF1-917C-6D832427AE6F} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642}
|
||||
{2F097B4B-8F38-45C3-8A42-90250E912F0C} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642}
|
||||
{7C22F6B7-095E-459B-BCCF-87098EA9F192} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642}
|
||||
{972CEB4D-510B-4701-B4A2-F14A85F11CC7} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642}
|
||||
{7B4C9EAC-316E-4890-A715-7BB9C1577F96} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642}
|
||||
{B13D1DF0-1B9E-4557-919C-0A4E0FC9A8C7} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642}
|
||||
{D640DBB2-4251-44B3-B949-75FC6BF02B71} = {56BCE1BF-7CBA-7CE8-203D-A88051F1D642}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Npgsql;
|
||||
using Scheduler.Backfill;
|
||||
using StellaOps.Scheduler.Models;
|
||||
using StellaOps.Scheduler.Storage.Postgres;
|
||||
using StellaOps.Scheduler.Storage.Postgres.Repositories;
|
||||
using StellaOps.Infrastructure.Postgres.Options;
|
||||
|
||||
var parsed = ParseArgs(args);
|
||||
var options = BackfillOptions.From(parsed.PostgresConnection, parsed.BatchSize, parsed.DryRun);
|
||||
@@ -91,7 +94,7 @@ internal sealed class BackfillRunner
|
||||
SchemaName = "scheduler",
|
||||
CommandTimeoutSeconds = 30,
|
||||
AutoMigrate = false
|
||||
}));
|
||||
}), NullLogger<SchedulerDataSource>.Instance);
|
||||
_graphJobRepository = new GraphJobRepository(_dataSource);
|
||||
}
|
||||
|
||||
@@ -106,7 +109,7 @@ internal sealed class BackfillRunner
|
||||
return;
|
||||
}
|
||||
|
||||
await using var conn = await _dataSource.OpenConnectionAsync();
|
||||
await using var conn = await _dataSource.OpenSystemConnectionAsync(CancellationToken.None);
|
||||
await using var tx = await conn.BeginTransactionAsync();
|
||||
|
||||
// Example: seed an empty job to validate wiring
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using StellaOps.Scheduler.Models;
|
||||
using StellaOps.Scheduler.Worker.Planning;
|
||||
|
||||
namespace StellaOps.Scheduler.Queue;
|
||||
|
||||
@@ -156,9 +155,9 @@ public sealed class RunnerSegmentQueueMessage
|
||||
public static readonly IReadOnlyDictionary<TKey, TValue> Instance =
|
||||
new ReadOnlyDictionary<TKey, TValue>(new Dictionary<TKey, TValue>(0, EqualityComparer<TKey>.Default));
|
||||
}
|
||||
}
|
||||
|
||||
public readonly record struct SchedulerQueueEnqueueResult(string MessageId, bool Deduplicated);
|
||||
}
|
||||
|
||||
public readonly record struct SchedulerQueueEnqueueResult(string MessageId, bool Deduplicated);
|
||||
|
||||
public sealed class SchedulerQueueLeaseRequest
|
||||
{
|
||||
@@ -215,12 +214,32 @@ public sealed class SchedulerQueueClaimOptions
|
||||
MinIdleTime = minIdleTime;
|
||||
}
|
||||
|
||||
public string ClaimantConsumer { get; }
|
||||
|
||||
public int BatchSize { get; }
|
||||
|
||||
public TimeSpan MinIdleTime { get; }
|
||||
}
|
||||
public string ClaimantConsumer { get; }
|
||||
|
||||
public int BatchSize { get; }
|
||||
|
||||
public TimeSpan MinIdleTime { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Minimal pointer to a Surface.FS manifest associated with an image digest.
|
||||
/// Kept local to avoid coupling queue contracts to worker assemblies.
|
||||
/// </summary>
|
||||
public sealed record SurfaceManifestPointer
|
||||
{
|
||||
public SurfaceManifestPointer(string manifestDigest, string? tenant)
|
||||
{
|
||||
ManifestDigest = manifestDigest ?? throw new ArgumentNullException(nameof(manifestDigest));
|
||||
Tenant = tenant;
|
||||
}
|
||||
|
||||
[JsonPropertyName("manifestDigest")]
|
||||
public string ManifestDigest { get; init; }
|
||||
|
||||
[JsonPropertyName("tenant")]
|
||||
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
|
||||
public string? Tenant { get; init; }
|
||||
}
|
||||
|
||||
public enum SchedulerQueueReleaseDisposition
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Text.Json;
|
||||
using Dapper;
|
||||
using Npgsql;
|
||||
using StellaOps.Infrastructure.Postgres;
|
||||
@@ -10,12 +9,10 @@ namespace StellaOps.Scheduler.Storage.Postgres.Repositories;
|
||||
public sealed class GraphJobRepository : IGraphJobRepository
|
||||
{
|
||||
private readonly SchedulerDataSource _dataSource;
|
||||
private readonly JsonSerializerOptions _json;
|
||||
|
||||
public GraphJobRepository(SchedulerDataSource dataSource)
|
||||
{
|
||||
_dataSource = dataSource;
|
||||
_json = CanonicalJsonSerializer.Options;
|
||||
}
|
||||
|
||||
public async ValueTask InsertAsync(GraphBuildJob job, CancellationToken cancellationToken)
|
||||
@@ -24,16 +21,16 @@ public sealed class GraphJobRepository : IGraphJobRepository
|
||||
(id, tenant_id, type, status, payload, created_at, updated_at, correlation_id)
|
||||
VALUES (@Id, @TenantId, @Type, @Status, @Payload, @CreatedAt, @UpdatedAt, @CorrelationId);";
|
||||
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(job.TenantId, cancellationToken).ConfigureAwait(false);
|
||||
await conn.ExecuteAsync(sql, new
|
||||
{
|
||||
job.Id,
|
||||
job.TenantId,
|
||||
Type = (short)GraphJobQueryType.Build,
|
||||
Status = (short)job.Status,
|
||||
Payload = JsonSerializer.Serialize(job, _json),
|
||||
Payload = CanonicalJsonSerializer.Serialize(job),
|
||||
job.CreatedAt,
|
||||
UpdatedAt = job.UpdatedAt ?? job.CreatedAt,
|
||||
UpdatedAt = job.CompletedAt ?? job.CreatedAt,
|
||||
job.CorrelationId
|
||||
});
|
||||
}
|
||||
@@ -44,16 +41,16 @@ public sealed class GraphJobRepository : IGraphJobRepository
|
||||
(id, tenant_id, type, status, payload, created_at, updated_at, correlation_id)
|
||||
VALUES (@Id, @TenantId, @Type, @Status, @Payload, @CreatedAt, @UpdatedAt, @CorrelationId);";
|
||||
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(job.TenantId, cancellationToken).ConfigureAwait(false);
|
||||
await conn.ExecuteAsync(sql, new
|
||||
{
|
||||
job.Id,
|
||||
job.TenantId,
|
||||
Type = (short)GraphJobQueryType.Overlay,
|
||||
Status = (short)job.Status,
|
||||
Payload = JsonSerializer.Serialize(job, _json),
|
||||
Payload = CanonicalJsonSerializer.Serialize(job),
|
||||
job.CreatedAt,
|
||||
UpdatedAt = job.UpdatedAt ?? job.CreatedAt,
|
||||
UpdatedAt = job.CompletedAt ?? job.CreatedAt,
|
||||
job.CorrelationId
|
||||
});
|
||||
}
|
||||
@@ -61,17 +58,17 @@ public sealed class GraphJobRepository : IGraphJobRepository
|
||||
public async ValueTask<GraphBuildJob?> GetBuildJobAsync(string tenantId, string jobId, CancellationToken cancellationToken)
|
||||
{
|
||||
const string sql = "SELECT payload FROM scheduler.graph_jobs WHERE tenant_id=@TenantId AND id=@Id AND type=@Type LIMIT 1";
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(tenantId, cancellationToken).ConfigureAwait(false);
|
||||
var payload = await conn.ExecuteScalarAsync<string?>(sql, new { TenantId = tenantId, Id = jobId, Type = (short)GraphJobQueryType.Build });
|
||||
return payload is null ? null : JsonSerializer.Deserialize<GraphBuildJob>(payload, _json);
|
||||
return payload is null ? null : CanonicalJsonSerializer.Deserialize<GraphBuildJob>(payload);
|
||||
}
|
||||
|
||||
public async ValueTask<GraphOverlayJob?> GetOverlayJobAsync(string tenantId, string jobId, CancellationToken cancellationToken)
|
||||
{
|
||||
const string sql = "SELECT payload FROM scheduler.graph_jobs WHERE tenant_id=@TenantId AND id=@Id AND type=@Type LIMIT 1";
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(tenantId, cancellationToken).ConfigureAwait(false);
|
||||
var payload = await conn.ExecuteScalarAsync<string?>(sql, new { TenantId = tenantId, Id = jobId, Type = (short)GraphJobQueryType.Overlay });
|
||||
return payload is null ? null : JsonSerializer.Deserialize<GraphOverlayJob>(payload, _json);
|
||||
return payload is null ? null : CanonicalJsonSerializer.Deserialize<GraphOverlayJob>(payload);
|
||||
}
|
||||
|
||||
public async ValueTask<IReadOnlyCollection<GraphBuildJob>> ListBuildJobsAsync(string tenantId, GraphJobStatus? status, int limit, CancellationToken cancellationToken)
|
||||
@@ -83,15 +80,15 @@ public sealed class GraphJobRepository : IGraphJobRepository
|
||||
}
|
||||
sql += " ORDER BY created_at DESC LIMIT @Limit";
|
||||
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(tenantId, cancellationToken).ConfigureAwait(false);
|
||||
var rows = await conn.QueryAsync<string>(sql, new
|
||||
{
|
||||
TenantId = tenantId,
|
||||
Type = (short)GraphJobQueryType.Build,
|
||||
Status = status is null ? null : (short)status,
|
||||
Status = (short?)status,
|
||||
Limit = limit
|
||||
});
|
||||
return rows.Select(r => JsonSerializer.Deserialize<GraphBuildJob>(r, _json)!).ToArray();
|
||||
return rows.Select(r => CanonicalJsonSerializer.Deserialize<GraphBuildJob>(r)).ToArray();
|
||||
}
|
||||
|
||||
public async ValueTask<IReadOnlyCollection<GraphOverlayJob>> ListOverlayJobsAsync(string tenantId, GraphJobStatus? status, int limit, CancellationToken cancellationToken)
|
||||
@@ -103,15 +100,15 @@ public sealed class GraphJobRepository : IGraphJobRepository
|
||||
}
|
||||
sql += " ORDER BY created_at DESC LIMIT @Limit";
|
||||
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(tenantId, cancellationToken).ConfigureAwait(false);
|
||||
var rows = await conn.QueryAsync<string>(sql, new
|
||||
{
|
||||
TenantId = tenantId,
|
||||
Type = (short)GraphJobQueryType.Overlay,
|
||||
Status = status is null ? null : (short)status,
|
||||
Status = (short?)status,
|
||||
Limit = limit
|
||||
});
|
||||
return rows.Select(r => JsonSerializer.Deserialize<GraphOverlayJob>(r, _json)!).ToArray();
|
||||
return rows.Select(r => CanonicalJsonSerializer.Deserialize<GraphOverlayJob>(r)).ToArray();
|
||||
}
|
||||
|
||||
public ValueTask<IReadOnlyCollection<GraphOverlayJob>> ListOverlayJobsAsync(string tenantId, CancellationToken cancellationToken)
|
||||
@@ -123,7 +120,7 @@ public sealed class GraphJobRepository : IGraphJobRepository
|
||||
SET status=@NewStatus, payload=@Payload, updated_at=NOW()
|
||||
WHERE tenant_id=@TenantId AND id=@Id AND status=@ExpectedStatus AND type=@Type";
|
||||
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(job.TenantId, cancellationToken).ConfigureAwait(false);
|
||||
var rows = await conn.ExecuteAsync(sql, new
|
||||
{
|
||||
job.TenantId,
|
||||
@@ -131,7 +128,7 @@ public sealed class GraphJobRepository : IGraphJobRepository
|
||||
ExpectedStatus = (short)expectedStatus,
|
||||
NewStatus = (short)job.Status,
|
||||
Type = (short)GraphJobQueryType.Build,
|
||||
Payload = JsonSerializer.Serialize(job, _json)
|
||||
Payload = CanonicalJsonSerializer.Serialize(job)
|
||||
});
|
||||
return rows == 1;
|
||||
}
|
||||
@@ -142,7 +139,7 @@ public sealed class GraphJobRepository : IGraphJobRepository
|
||||
SET status=@NewStatus, payload=@Payload, updated_at=NOW()
|
||||
WHERE tenant_id=@TenantId AND id=@Id AND status=@ExpectedStatus AND type=@Type";
|
||||
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(cancellationToken).ConfigureAwait(false);
|
||||
await using var conn = await _dataSource.OpenConnectionAsync(job.TenantId, cancellationToken).ConfigureAwait(false);
|
||||
var rows = await conn.ExecuteAsync(sql, new
|
||||
{
|
||||
job.TenantId,
|
||||
@@ -150,8 +147,14 @@ public sealed class GraphJobRepository : IGraphJobRepository
|
||||
ExpectedStatus = (short)expectedStatus,
|
||||
NewStatus = (short)job.Status,
|
||||
Type = (short)GraphJobQueryType.Overlay,
|
||||
Payload = JsonSerializer.Serialize(job, _json)
|
||||
Payload = CanonicalJsonSerializer.Serialize(job)
|
||||
});
|
||||
return rows == 1;
|
||||
}
|
||||
}
|
||||
|
||||
internal enum GraphJobQueryType : short
|
||||
{
|
||||
Build = 0,
|
||||
Overlay = 1
|
||||
}
|
||||
|
||||
@@ -8,8 +8,11 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="xunit" Version="2.6.3" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.6.3" />
|
||||
<PackageReference Update="xunit" Version="2.9.2" />
|
||||
<PackageReference Update="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -12,14 +12,14 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
||||
<PackageReference Update="Microsoft.NET.Test.Sdk" Version="17.14.0" />
|
||||
<PackageReference Include="Moq" Version="4.20.70" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<PackageReference Update="xunit" Version="2.9.2" />
|
||||
<PackageReference Update="xunit.runner.visualstudio" Version="2.8.2">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="coverlet.collector" Version="6.0.4">
|
||||
<PackageReference Update="coverlet.collector" Version="6.0.4">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
|
||||
Reference in New Issue
Block a user