T2: CI runs every test against a throwaway mongod
tools/ci/with-test-mongod.sh starts mongod (or podman's mongo:8) on a random localhost port with a temporary data directory, runs the command, and removes both. build.yml and deploy.yml test through it, so the ~85 integration tests stop being skipped in CI. MongoFixture refuses production's port and data directory, and in CI anything but the wrapper's mongod; with PRIVAPUB_TEST_REQUIRE_MONGOD=1 a missing mongod fails instead of skipping. The deploy now passes the PRIVAPUB_SMOKE_TOKEN secret to the Mastodon smoke check, so its signed-in half runs once the owner creates the persona and the secret. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ELjqpznMFMNrJoJUj6K5p2
This commit is contained in:
1 parent
00b2685cf4
commit
85fdff606d
5 files changed
+110
-9
No files matched your search
@@ -13,15 +13,24 @@ namespace PrivaPub.Tests.Support
|
||||
public sealed class MongoFixture : IAsyncLifetime
|
||||
{
|
||||
public const string Skip = "set PRIVAPUB_TEST_MONGOD=1 (and optionally PRIVAPUB_TEST_MONGO) to run the tests that need a mongod";
|
||||
const int ProductionPort = 27022;
|
||||
const int DefaultPort = 27017;
|
||||
|
||||
public static bool Enabled => Environment.GetEnvironmentVariable("PRIVAPUB_TEST_MONGOD") == "1";
|
||||
static bool Required => Environment.GetEnvironmentVariable("PRIVAPUB_TEST_REQUIRE_MONGOD") == "1";
|
||||
static bool InCi => !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("CI")) || !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("GITEA_ACTIONS"));
|
||||
|
||||
public string Database { get; } = $"PrivaPubTests_{Guid.NewGuid():N}";
|
||||
public static string Connection { get; } = Environment.GetEnvironmentVariable("PRIVAPUB_TEST_MONGO") ?? $"mongodb://127.0.0.1:{DefaultPort}";
|
||||
public static string Database { get; } = $"PrivaPubTests_{Guid.NewGuid():N}";
|
||||
|
||||
public async ValueTask InitializeAsync()
|
||||
{
|
||||
if (Required && !Enabled)
|
||||
throw new InvalidOperationException("PRIVAPUB_TEST_REQUIRE_MONGOD=1 but PRIVAPUB_TEST_MONGOD is not 1: the integration tests would be skipped");
|
||||
if (!Enabled)
|
||||
return;
|
||||
var settings = MongoClientSettings.FromConnectionString(Connection);
|
||||
Refuse(settings);
|
||||
try
|
||||
{
|
||||
BsonSerializer.RegisterSerializer(new GuidSerializer(GuidRepresentation.Standard));
|
||||
@@ -29,8 +38,8 @@ namespace PrivaPub.Tests.Support
|
||||
catch (BsonSerializationException)
|
||||
{
|
||||
}
|
||||
var connection = Environment.GetEnvironmentVariable("PRIVAPUB_TEST_MONGO") ?? "mongodb://127.0.0.1:27017";
|
||||
await DB.InitAsync(Database, MongoClientSettings.FromConnectionString(connection));
|
||||
await DB.InitAsync(Database, settings);
|
||||
await RefuseProductionData();
|
||||
EntityMaps.Warm();
|
||||
await Indexes.Create();
|
||||
}
|
||||
@@ -40,5 +49,32 @@ namespace PrivaPub.Tests.Support
|
||||
if (Enabled)
|
||||
await DB.Default.Database().Client.DropDatabaseAsync(Database);
|
||||
}
|
||||
|
||||
static void Refuse(MongoClientSettings settings)
|
||||
{
|
||||
var ports = settings.Servers.Select(s => s.Port).ToList();
|
||||
if (ports.Contains(ProductionPort))
|
||||
throw new InvalidOperationException($"the tests never run against port {ProductionPort}: that is production's mongod");
|
||||
if (InCi && (Environment.GetEnvironmentVariable("PRIVAPUB_TEST_MONGO") == default || ports.Contains(DefaultPort)))
|
||||
throw new InvalidOperationException("in CI the tests run only against a throwaway mongod: use tools/ci/with-test-mongod.sh");
|
||||
}
|
||||
|
||||
static async Task RefuseProductionData()
|
||||
{
|
||||
BsonDocument options;
|
||||
try
|
||||
{
|
||||
options = await DB.Default.Database().Client.GetDatabase("admin").RunCommandAsync<BsonDocument>(new BsonDocument("getCmdLineOpts", 1));
|
||||
}
|
||||
catch (MongoCommandException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var dbPath = options.GetValue("parsed", new BsonDocument()).AsBsonDocument
|
||||
.GetValue("storage", new BsonDocument()).AsBsonDocument
|
||||
.GetValue("dbPath", BsonNull.Value);
|
||||
if (dbPath.IsString && dbPath.AsString.StartsWith("/var/lib/privapub", StringComparison.Ordinal))
|
||||
throw new InvalidOperationException($"the mongod at {Connection} keeps its data in {dbPath.AsString}: that is production's");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user