up
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Reachability Corpus Validation / validate-corpus (push) Has been cancelled
Reachability Corpus Validation / validate-ground-truths (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Reachability Corpus Validation / determinism-check (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Reachability Corpus Validation / validate-corpus (push) Has been cancelled
Reachability Corpus Validation / validate-ground-truths (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Reachability Corpus Validation / determinism-check (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled
Notify Smoke Test / Notify Unit Tests (push) Has been cancelled
Notify Smoke Test / Notifier Service Tests (push) Has been cancelled
Notify Smoke Test / Notification Smoke Test (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using MicrosoftOptions = Microsoft.Extensions.Options;
|
||||
using StellaOps.SbomService.Models;
|
||||
using StellaOps.SbomService.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.SbomService.Storage.Postgres.Tests;
|
||||
|
||||
[Collection(SbomServicePostgresCollection.Name)]
|
||||
public sealed class PostgresEntrypointRepositoryTests : IAsyncLifetime
|
||||
{
|
||||
private readonly SbomServicePostgresFixture _fixture;
|
||||
private readonly PostgresEntrypointRepository _repository;
|
||||
private readonly string _tenantId = "tenant-" + Guid.NewGuid().ToString("N")[..8];
|
||||
|
||||
public PostgresEntrypointRepositoryTests(SbomServicePostgresFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
|
||||
var options = fixture.Fixture.CreateOptions();
|
||||
options.SchemaName = fixture.SchemaName;
|
||||
var dataSource = new SbomServiceDataSource(MicrosoftOptions.Options.Create(options), NullLogger<SbomServiceDataSource>.Instance);
|
||||
_repository = new PostgresEntrypointRepository(dataSource, NullLogger<PostgresEntrypointRepository>.Instance);
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await _fixture.TruncateAllTablesAsync();
|
||||
}
|
||||
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
public async Task UpsertAndList_RoundTripsEntrypoint()
|
||||
{
|
||||
// Arrange
|
||||
var entrypoint = new Entrypoint(
|
||||
Artifact: "ghcr.io/test/api",
|
||||
Service: "web",
|
||||
Path: "/api",
|
||||
Scope: "runtime",
|
||||
RuntimeFlag: true);
|
||||
|
||||
// Act
|
||||
await _repository.UpsertAsync(_tenantId, entrypoint, CancellationToken.None);
|
||||
var fetched = await _repository.ListAsync(_tenantId, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
fetched.Should().HaveCount(1);
|
||||
fetched[0].Artifact.Should().Be("ghcr.io/test/api");
|
||||
fetched[0].Service.Should().Be("web");
|
||||
fetched[0].Path.Should().Be("/api");
|
||||
fetched[0].RuntimeFlag.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpsertAsync_UpdatesExistingEntrypoint()
|
||||
{
|
||||
// Arrange
|
||||
var entrypoint1 = new Entrypoint("ghcr.io/test/api", "web", "/old", "runtime", false);
|
||||
var entrypoint2 = new Entrypoint("ghcr.io/test/api", "web", "/new", "build", true);
|
||||
|
||||
// Act
|
||||
await _repository.UpsertAsync(_tenantId, entrypoint1, CancellationToken.None);
|
||||
await _repository.UpsertAsync(_tenantId, entrypoint2, CancellationToken.None);
|
||||
var fetched = await _repository.ListAsync(_tenantId, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
fetched.Should().HaveCount(1);
|
||||
fetched[0].Path.Should().Be("/new");
|
||||
fetched[0].Scope.Should().Be("build");
|
||||
fetched[0].RuntimeFlag.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListAsync_ReturnsOrderedByArtifactServicePath()
|
||||
{
|
||||
// Arrange
|
||||
await _repository.UpsertAsync(_tenantId, new Entrypoint("z-api", "web", "/z", "runtime", true), CancellationToken.None);
|
||||
await _repository.UpsertAsync(_tenantId, new Entrypoint("a-api", "web", "/a", "runtime", true), CancellationToken.None);
|
||||
await _repository.UpsertAsync(_tenantId, new Entrypoint("a-api", "worker", "/b", "runtime", true), CancellationToken.None);
|
||||
|
||||
// Act
|
||||
var fetched = await _repository.ListAsync(_tenantId, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
fetched.Should().HaveCount(3);
|
||||
fetched[0].Artifact.Should().Be("a-api");
|
||||
fetched[0].Service.Should().Be("web");
|
||||
fetched[1].Artifact.Should().Be("a-api");
|
||||
fetched[1].Service.Should().Be("worker");
|
||||
fetched[2].Artifact.Should().Be("z-api");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListAsync_ReturnsEmptyForUnknownTenant()
|
||||
{
|
||||
// Act
|
||||
var fetched = await _repository.ListAsync("unknown-tenant", CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
fetched.Should().BeEmpty();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using MicrosoftOptions = Microsoft.Extensions.Options;
|
||||
using StellaOps.SbomService.Services;
|
||||
using StellaOps.SbomService.Storage.Postgres.Repositories;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.SbomService.Storage.Postgres.Tests;
|
||||
|
||||
[Collection(SbomServicePostgresCollection.Name)]
|
||||
public sealed class PostgresOrchestratorControlRepositoryTests : IAsyncLifetime
|
||||
{
|
||||
private readonly SbomServicePostgresFixture _fixture;
|
||||
private readonly PostgresOrchestratorControlRepository _repository;
|
||||
private readonly string _tenantId = "tenant-" + Guid.NewGuid().ToString("N")[..8];
|
||||
|
||||
public PostgresOrchestratorControlRepositoryTests(SbomServicePostgresFixture fixture)
|
||||
{
|
||||
_fixture = fixture;
|
||||
|
||||
var options = fixture.Fixture.CreateOptions();
|
||||
options.SchemaName = fixture.SchemaName;
|
||||
var dataSource = new SbomServiceDataSource(MicrosoftOptions.Options.Create(options), NullLogger<SbomServiceDataSource>.Instance);
|
||||
_repository = new PostgresOrchestratorControlRepository(dataSource, NullLogger<PostgresOrchestratorControlRepository>.Instance);
|
||||
}
|
||||
|
||||
public async Task InitializeAsync()
|
||||
{
|
||||
await _fixture.TruncateAllTablesAsync();
|
||||
}
|
||||
|
||||
public Task DisposeAsync() => Task.CompletedTask;
|
||||
|
||||
[Fact]
|
||||
public async Task GetAsync_ReturnsDefaultStateForNewTenant()
|
||||
{
|
||||
// Act
|
||||
var state = await _repository.GetAsync(_tenantId, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
state.Should().NotBeNull();
|
||||
state.TenantId.Should().Be(_tenantId);
|
||||
state.Paused.Should().BeFalse();
|
||||
state.ThrottlePercent.Should().Be(0);
|
||||
state.Backpressure.Should().Be("normal");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetAsync_PersistsControlState()
|
||||
{
|
||||
// Arrange
|
||||
var state = new OrchestratorControlState(
|
||||
TenantId: _tenantId,
|
||||
Paused: true,
|
||||
ThrottlePercent: 50,
|
||||
Backpressure: "high",
|
||||
UpdatedAtUtc: DateTimeOffset.UtcNow);
|
||||
|
||||
// Act
|
||||
await _repository.SetAsync(state, CancellationToken.None);
|
||||
var fetched = await _repository.GetAsync(_tenantId, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
fetched.Paused.Should().BeTrue();
|
||||
fetched.ThrottlePercent.Should().Be(50);
|
||||
fetched.Backpressure.Should().Be("high");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SetAsync_UpdatesExistingState()
|
||||
{
|
||||
// Arrange
|
||||
var state1 = new OrchestratorControlState(_tenantId, false, 10, "low", DateTimeOffset.UtcNow);
|
||||
var state2 = new OrchestratorControlState(_tenantId, true, 90, "critical", DateTimeOffset.UtcNow);
|
||||
|
||||
// Act
|
||||
await _repository.SetAsync(state1, CancellationToken.None);
|
||||
await _repository.SetAsync(state2, CancellationToken.None);
|
||||
var fetched = await _repository.GetAsync(_tenantId, CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
fetched.Paused.Should().BeTrue();
|
||||
fetched.ThrottlePercent.Should().Be(90);
|
||||
fetched.Backpressure.Should().Be("critical");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ListAsync_ReturnsAllStates()
|
||||
{
|
||||
// Arrange
|
||||
var tenant1 = "tenant-a-" + Guid.NewGuid().ToString("N")[..4];
|
||||
var tenant2 = "tenant-b-" + Guid.NewGuid().ToString("N")[..4];
|
||||
await _repository.SetAsync(new OrchestratorControlState(tenant1, false, 0, "normal", DateTimeOffset.UtcNow), CancellationToken.None);
|
||||
await _repository.SetAsync(new OrchestratorControlState(tenant2, true, 50, "high", DateTimeOffset.UtcNow), CancellationToken.None);
|
||||
|
||||
// Act
|
||||
var states = await _repository.ListAsync(CancellationToken.None);
|
||||
|
||||
// Assert
|
||||
states.Should().HaveCountGreaterOrEqualTo(2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Reflection;
|
||||
using StellaOps.Infrastructure.Postgres.Testing;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.SbomService.Storage.Postgres.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// PostgreSQL integration test fixture for the SbomService module.
|
||||
/// </summary>
|
||||
public sealed class SbomServicePostgresFixture : PostgresIntegrationFixture, ICollectionFixture<SbomServicePostgresFixture>
|
||||
{
|
||||
protected override Assembly? GetMigrationAssembly()
|
||||
=> typeof(SbomServiceDataSource).Assembly;
|
||||
|
||||
protected override string GetModuleName() => "SbomService";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Collection definition for SbomService PostgreSQL integration tests.
|
||||
/// Tests in this collection share a single PostgreSQL container instance.
|
||||
/// </summary>
|
||||
[CollectionDefinition(Name)]
|
||||
public sealed class SbomServicePostgresCollection : ICollectionFixture<SbomServicePostgresFixture>
|
||||
{
|
||||
public const string Name = "SbomServicePostgres";
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" ?>
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>preview</LangVersion>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FluentAssertions" Version="6.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="10.0.0" />
|
||||
<PackageReference Include="xunit" Version="2.9.2" />
|
||||
<PackageReference Include="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">
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\StellaOps.SbomService.Storage.Postgres\StellaOps.SbomService.Storage.Postgres.csproj" />
|
||||
<ProjectReference Include="..\..\__Libraries\StellaOps.Infrastructure.Postgres.Testing\StellaOps.Infrastructure.Postgres.Testing.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user