Rename Feedser to Concelier

This commit is contained in:
master
2025-10-18 20:04:15 +03:00
parent dd66f58b00
commit 89ede53cc3
1208 changed files with 4370 additions and 4370 deletions

View File

@@ -0,0 +1,238 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using MongoDB.Bson;
using MongoDB.Driver;
using StellaOps.Concelier.Storage.Mongo;
using StellaOps.Concelier.Storage.Mongo.Migrations;
using Xunit;
namespace StellaOps.Concelier.Storage.Mongo.Tests.Migrations;
[Collection("mongo-fixture")]
public sealed class MongoMigrationRunnerTests
{
private readonly MongoIntegrationFixture _fixture;
public MongoMigrationRunnerTests(MongoIntegrationFixture fixture)
{
_fixture = fixture;
}
[Fact]
public async Task RunAsync_AppliesPendingMigrationsOnce()
{
var databaseName = $"concelier-migrations-{Guid.NewGuid():N}";
var database = _fixture.Client.GetDatabase(databaseName);
await database.CreateCollectionAsync(MongoStorageDefaults.Collections.Migrations);
try
{
var migration = new TestMigration();
var runner = new MongoMigrationRunner(
database,
new IMongoMigration[] { migration },
NullLogger<MongoMigrationRunner>.Instance,
TimeProvider.System);
await runner.RunAsync(CancellationToken.None);
await runner.RunAsync(CancellationToken.None);
Assert.Equal(1, migration.ApplyCount);
var count = await database
.GetCollection<BsonDocument>(MongoStorageDefaults.Collections.Migrations)
.CountDocumentsAsync(FilterDefinition<BsonDocument>.Empty);
Assert.Equal(1, count);
}
finally
{
await _fixture.Client.DropDatabaseAsync(databaseName);
}
}
[Fact]
public async Task EnsureDocumentExpiryIndexesMigration_CreatesTtlIndexWhenRetentionEnabled()
{
var databaseName = $"concelier-doc-ttl-{Guid.NewGuid():N}";
var database = _fixture.Client.GetDatabase(databaseName);
await database.CreateCollectionAsync(MongoStorageDefaults.Collections.Document);
await database.CreateCollectionAsync(MongoStorageDefaults.Collections.Migrations);
try
{
var options = Options.Create(new MongoStorageOptions
{
RawDocumentRetention = TimeSpan.FromDays(45),
RawDocumentRetentionTtlGrace = TimeSpan.FromHours(12),
});
var migration = new EnsureDocumentExpiryIndexesMigration(options);
var runner = new MongoMigrationRunner(
database,
new IMongoMigration[] { migration },
NullLogger<MongoMigrationRunner>.Instance,
TimeProvider.System);
await runner.RunAsync(CancellationToken.None);
var indexes = await database
.GetCollection<BsonDocument>(MongoStorageDefaults.Collections.Document)
.Indexes.ListAsync();
var indexList = await indexes.ToListAsync();
var ttlIndex = indexList.Single(x => x["name"].AsString == "document_expiresAt_ttl");
Assert.Equal(0, ttlIndex["expireAfterSeconds"].ToDouble());
Assert.True(ttlIndex["partialFilterExpression"].AsBsonDocument["expiresAt"].AsBsonDocument["$exists"].ToBoolean());
}
finally
{
await _fixture.Client.DropDatabaseAsync(databaseName);
}
}
[Fact]
public async Task EnsureDocumentExpiryIndexesMigration_DropsTtlIndexWhenRetentionDisabled()
{
var databaseName = $"concelier-doc-notl-{Guid.NewGuid():N}";
var database = _fixture.Client.GetDatabase(databaseName);
await database.CreateCollectionAsync(MongoStorageDefaults.Collections.Document);
await database.CreateCollectionAsync(MongoStorageDefaults.Collections.Migrations);
try
{
var collection = database.GetCollection<BsonDocument>(MongoStorageDefaults.Collections.Document);
var keys = Builders<BsonDocument>.IndexKeys.Ascending("expiresAt");
var options = new CreateIndexOptions<BsonDocument>
{
Name = "document_expiresAt_ttl",
ExpireAfter = TimeSpan.Zero,
PartialFilterExpression = Builders<BsonDocument>.Filter.Exists("expiresAt", true),
};
await collection.Indexes.CreateOneAsync(new CreateIndexModel<BsonDocument>(keys, options));
var migration = new EnsureDocumentExpiryIndexesMigration(Options.Create(new MongoStorageOptions
{
RawDocumentRetention = TimeSpan.Zero,
}));
var runner = new MongoMigrationRunner(
database,
new IMongoMigration[] { migration },
NullLogger<MongoMigrationRunner>.Instance,
TimeProvider.System);
await runner.RunAsync(CancellationToken.None);
var indexes = await collection.Indexes.ListAsync();
var indexList = await indexes.ToListAsync();
Assert.DoesNotContain(indexList, x => x["name"].AsString == "document_expiresAt_ttl");
var nonTtl = indexList.Single(x => x["name"].AsString == "document_expiresAt");
Assert.False(nonTtl.Contains("expireAfterSeconds"));
}
finally
{
await _fixture.Client.DropDatabaseAsync(databaseName);
}
}
[Fact]
public async Task EnsureGridFsExpiryIndexesMigration_CreatesTtlIndexWhenRetentionEnabled()
{
var databaseName = $"concelier-gridfs-ttl-{Guid.NewGuid():N}";
var database = _fixture.Client.GetDatabase(databaseName);
await database.CreateCollectionAsync("documents.files");
await database.CreateCollectionAsync(MongoStorageDefaults.Collections.Migrations);
try
{
var migration = new EnsureGridFsExpiryIndexesMigration(Options.Create(new MongoStorageOptions
{
RawDocumentRetention = TimeSpan.FromDays(30),
}));
var runner = new MongoMigrationRunner(
database,
new IMongoMigration[] { migration },
NullLogger<MongoMigrationRunner>.Instance,
TimeProvider.System);
await runner.RunAsync(CancellationToken.None);
var indexes = await database.GetCollection<BsonDocument>("documents.files").Indexes.ListAsync();
var indexList = await indexes.ToListAsync();
var ttlIndex = indexList.Single(x => x["name"].AsString == "gridfs_files_expiresAt_ttl");
Assert.Equal(0, ttlIndex["expireAfterSeconds"].ToDouble());
}
finally
{
await _fixture.Client.DropDatabaseAsync(databaseName);
}
}
[Fact]
public async Task EnsureGridFsExpiryIndexesMigration_DropsTtlIndexWhenRetentionDisabled()
{
var databaseName = $"concelier-gridfs-notl-{Guid.NewGuid():N}";
var database = _fixture.Client.GetDatabase(databaseName);
await database.CreateCollectionAsync("documents.files");
await database.CreateCollectionAsync(MongoStorageDefaults.Collections.Migrations);
try
{
var collection = database.GetCollection<BsonDocument>("documents.files");
var keys = Builders<BsonDocument>.IndexKeys.Ascending("metadata.expiresAt");
var options = new CreateIndexOptions<BsonDocument>
{
Name = "gridfs_files_expiresAt_ttl",
ExpireAfter = TimeSpan.Zero,
PartialFilterExpression = Builders<BsonDocument>.Filter.Exists("metadata.expiresAt", true),
};
await collection.Indexes.CreateOneAsync(new CreateIndexModel<BsonDocument>(keys, options));
var migration = new EnsureGridFsExpiryIndexesMigration(Options.Create(new MongoStorageOptions
{
RawDocumentRetention = TimeSpan.Zero,
}));
var runner = new MongoMigrationRunner(
database,
new IMongoMigration[] { migration },
NullLogger<MongoMigrationRunner>.Instance,
TimeProvider.System);
await runner.RunAsync(CancellationToken.None);
var indexes = await collection.Indexes.ListAsync();
var indexList = await indexes.ToListAsync();
Assert.DoesNotContain(indexList, x => x["name"].AsString == "gridfs_files_expiresAt_ttl");
}
finally
{
await _fixture.Client.DropDatabaseAsync(databaseName);
}
}
private sealed class TestMigration : IMongoMigration
{
public int ApplyCount { get; private set; }
public string Id => "999_test";
public string Description => "test migration";
public Task ApplyAsync(IMongoDatabase database, CancellationToken cancellationToken)
{
ApplyCount++;
return Task.CompletedTask;
}
}
}