using System; using System.Linq; using System.Threading; 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; [Collection("mongo-fixture")] public sealed class MongoBootstrapperTests : IClassFixture { private readonly MongoIntegrationFixture _fixture; public MongoBootstrapperTests(MongoIntegrationFixture fixture) { _fixture = fixture; } [Fact] public async Task InitializeAsync_CreatesNormalizedIndexesWhenSemVerStyleEnabled() { var databaseName = $"concelier-bootstrap-semver-{Guid.NewGuid():N}"; var database = _fixture.Client.GetDatabase(databaseName); try { var runner = new MongoMigrationRunner( database, Array.Empty(), NullLogger.Instance, TimeProvider.System); var bootstrapper = new MongoBootstrapper( database, Options.Create(new MongoStorageOptions { EnableSemVerStyle = true }), NullLogger.Instance, runner); await bootstrapper.InitializeAsync(CancellationToken.None); var indexCursor = await database .GetCollection(MongoStorageDefaults.Collections.Advisory) .Indexes .ListAsync(); var indexNames = (await indexCursor.ToListAsync()).Select(x => x["name"].AsString).ToArray(); Assert.Contains("advisory_normalizedVersions_pkg_scheme_type", indexNames); Assert.Contains("advisory_normalizedVersions_value", indexNames); } finally { await _fixture.Client.DropDatabaseAsync(databaseName); } } [Fact] public async Task InitializeAsync_DoesNotCreateNormalizedIndexesWhenFeatureDisabled() { var databaseName = $"concelier-bootstrap-no-semver-{Guid.NewGuid():N}"; var database = _fixture.Client.GetDatabase(databaseName); try { var runner = new MongoMigrationRunner( database, Array.Empty(), NullLogger.Instance, TimeProvider.System); var bootstrapper = new MongoBootstrapper( database, Options.Create(new MongoStorageOptions { EnableSemVerStyle = false }), NullLogger.Instance, runner); await bootstrapper.InitializeAsync(CancellationToken.None); var indexCursor = await database .GetCollection(MongoStorageDefaults.Collections.Advisory) .Indexes .ListAsync(); var indexNames = (await indexCursor.ToListAsync()).Select(x => x["name"].AsString).ToArray(); Assert.DoesNotContain("advisory_normalizedVersions_pkg_scheme_type", indexNames); Assert.DoesNotContain("advisory_normalizedVersions_value", indexNames); } finally { await _fixture.Client.DropDatabaseAsync(databaseName); } } [Fact] public async Task InitializeAsync_CreatesAdvisoryEventIndexes() { var databaseName = $"concelier-bootstrap-events-{Guid.NewGuid():N}"; var database = _fixture.Client.GetDatabase(databaseName); try { var runner = new MongoMigrationRunner( database, Array.Empty(), NullLogger.Instance, TimeProvider.System); var bootstrapper = new MongoBootstrapper( database, Options.Create(new MongoStorageOptions()), NullLogger.Instance, runner); await bootstrapper.InitializeAsync(CancellationToken.None); var statementIndexes = await database .GetCollection(MongoStorageDefaults.Collections.AdvisoryStatements) .Indexes .ListAsync(); var statementIndexNames = (await statementIndexes.ToListAsync()).Select(x => x["name"].AsString).ToArray(); Assert.Contains("advisory_statements_vulnerability_asof_desc", statementIndexNames); Assert.Contains("advisory_statements_statementHash_unique", statementIndexNames); var conflictIndexes = await database .GetCollection(MongoStorageDefaults.Collections.AdvisoryConflicts) .Indexes .ListAsync(); var conflictIndexNames = (await conflictIndexes.ToListAsync()).Select(x => x["name"].AsString).ToArray(); Assert.Contains("advisory_conflicts_vulnerability_asof_desc", conflictIndexNames); Assert.Contains("advisory_conflicts_conflictHash_unique", conflictIndexNames); } finally { await _fixture.Client.DropDatabaseAsync(databaseName); } } }