mirror of
https://github.com/azaion/missions.git
synced 2026-06-21 09:21:07 +00:00
6b2c2d998e
Adds 26 blackbox tests (FT-P-01..18, FT-N-01..08) covering full AC
matrices for Vehicles/Missions/Waypoints/Health/Errors. Three
spec-vs-code carry-forwards documented in batch_02_report.md and
pinned with [Trait("carry_forward", ...)].
Shared scaffolding: ApiDtos.cs, AssertProblemEnvelopeAsync helper,
Seeds.cs, StubSchema.cs, CascadeF3/F4 fixtures, PostgresStopStart
fixture (gated by COMPOSE_RESTART_ENABLED). Removes the 4 placeholder
Sanity.cs files (now superseded). docker-compose.test.yml gains the
expected_results volume mount + FIXTURE_SQL_DIR for the consumer.
Co-authored-by: Cursor <cursoragent@cursor.com>
87 lines
2.9 KiB
C#
87 lines
2.9 KiB
C#
using System.Diagnostics;
|
|
|
|
namespace Azaion.Missions.E2E.Fixtures;
|
|
|
|
/// <summary>
|
|
/// Stop/start helper for the postgres-test compose service. Used by FT-P-17
|
|
/// to prove that <c>/health</c> does not ping the database — the fixture
|
|
/// stops postgres-test, the test asserts /health still returns 200, and the
|
|
/// fixture restarts postgres-test in teardown.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Like <see cref="ComposeRestartFixture"/>, this fixture only runs when
|
|
/// <c>COMPOSE_RESTART_ENABLED=1</c>. The e2e-consumer image needs the
|
|
/// docker CLI on PATH and a docker socket bind to actually drive compose.
|
|
/// Tests using the fixture must skip with a clear reason when disabled.
|
|
/// </remarks>
|
|
public sealed class PostgresStopStartFixture
|
|
{
|
|
public bool Enabled => Environment.GetEnvironmentVariable("COMPOSE_RESTART_ENABLED") == "1";
|
|
|
|
public string ComposeFile =>
|
|
Environment.GetEnvironmentVariable("COMPOSE_FILE_PATH") ?? "/workspace/docker-compose.test.yml";
|
|
|
|
public string ServiceName =>
|
|
Environment.GetEnvironmentVariable("POSTGRES_SERVICE_NAME") ?? "postgres-test";
|
|
|
|
public void Stop()
|
|
{
|
|
EnsureEnabled();
|
|
Run("docker", $"compose -f {ComposeFile} stop {ServiceName}");
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
EnsureEnabled();
|
|
Run("docker", $"compose -f {ComposeFile} start {ServiceName}");
|
|
// Wait for the service to report healthy via pg_isready before
|
|
// returning — otherwise the next test would hit ConnectionRefused.
|
|
WaitUntilHealthy();
|
|
}
|
|
|
|
private void WaitUntilHealthy()
|
|
{
|
|
var deadline = DateTime.UtcNow.AddSeconds(30);
|
|
while (DateTime.UtcNow < deadline)
|
|
{
|
|
try
|
|
{
|
|
Run("docker",
|
|
$"compose -f {ComposeFile} exec -T {ServiceName} pg_isready -U postgres -d azaion");
|
|
return;
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
Thread.Sleep(500);
|
|
}
|
|
}
|
|
throw new InvalidOperationException(
|
|
$"postgres service '{ServiceName}' did not become ready within 30s after start");
|
|
}
|
|
|
|
private void EnsureEnabled()
|
|
{
|
|
if (!Enabled)
|
|
throw new InvalidOperationException(
|
|
"PostgresStopStartFixture is disabled; set COMPOSE_RESTART_ENABLED=1 to use it.");
|
|
}
|
|
|
|
private static void Run(string file, string args)
|
|
{
|
|
var psi = new ProcessStartInfo(file, args)
|
|
{
|
|
RedirectStandardOutput = true,
|
|
RedirectStandardError = true,
|
|
UseShellExecute = false
|
|
};
|
|
using var p = Process.Start(psi)
|
|
?? throw new InvalidOperationException($"Failed to launch {file} {args}");
|
|
p.WaitForExit();
|
|
if (p.ExitCode != 0)
|
|
{
|
|
var err = p.StandardError.ReadToEnd();
|
|
throw new InvalidOperationException($"`{file} {args}` exited {p.ExitCode}: {err}");
|
|
}
|
|
}
|
|
}
|