- FindingsLedger: change schema from public to findings (V3-01) - Add 9 migration module plugins: RiskEngine, Replay, ExportCenter, Integrations, Signer, IssuerDirectory, Workflow, PacksRegistry, OpsMemory (V4-01 to V4-09) - Remove 16 redundant inline CREATE SCHEMA patterns (V4-10) - Rename export→export-web, excititor→excititor-web for consistency - Compose stella-ops.yml: thin wrapper using include: directive - Fix dead /api/v1/jobengine/* gateway routes → release-orchestrator/packsregistry - Scheduler plugin architecture: ISchedulerJobPlugin + ScanJobPlugin + DoctorJobPlugin - Create unified audit sink sprint plan - VulnExplorer integration tests + gap analysis Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
94 lines
4.6 KiB
C#
94 lines
4.6 KiB
C#
using System;
|
|
using System.Linq;
|
|
using StellaOps.Platform.Database;
|
|
using Xunit;
|
|
|
|
namespace StellaOps.Cli.Tests.Commands;
|
|
|
|
public class MigrationModuleRegistryTests
|
|
{
|
|
[Fact]
|
|
public void Modules_Populated_With_All_Postgres_Modules()
|
|
{
|
|
var modules = MigrationModuleRegistry.Modules;
|
|
Assert.True(modules.Count >= 20, $"Expected at least 20 registered modules, found {modules.Count}");
|
|
Assert.Contains(modules, m => m.Name == "AdvisoryAI" && m.SchemaName == "advisoryai");
|
|
Assert.Contains(modules, m => m.Name == "AirGap" && m.SchemaName == "airgap");
|
|
Assert.Contains(modules, m => m.Name == "Authority" && m.SchemaName == "authority");
|
|
Assert.Contains(modules, m => m.Name == "Eventing" && m.SchemaName == "timeline");
|
|
Assert.Contains(modules, m => m.Name == "Evidence" && m.SchemaName == "evidence");
|
|
Assert.Contains(modules, m => m.Name == "Scheduler" && m.SchemaName == "scheduler");
|
|
Assert.Contains(modules, m => m.Name == "Concelier" && m.SchemaName == "vuln");
|
|
Assert.Contains(modules, m => m.Name == "Policy" && m.SchemaName == "policy");
|
|
Assert.Contains(modules, m => m.Name == "Notify" && m.SchemaName == "notify");
|
|
Assert.Contains(modules, m => m.Name == "Excititor" && m.SchemaName == "vex");
|
|
Assert.Contains(modules, m => m.Name == "PluginRegistry" && m.SchemaName == "platform");
|
|
Assert.Contains(modules, m => m.Name == "Platform" && m.SchemaName == "release");
|
|
var scanner = Assert.Single(modules, static module => module.Name == "Scanner" && module.SchemaName == "scanner");
|
|
Assert.Equal(2, scanner.Sources.Count);
|
|
Assert.Contains(
|
|
scanner.Sources,
|
|
static source => string.Equals(
|
|
source.ResourcePrefix,
|
|
"StellaOps.Scanner.Triage.Migrations",
|
|
StringComparison.Ordinal));
|
|
Assert.Contains(modules, m => m.Name == "TimelineIndexer" && m.SchemaName == "timeline");
|
|
Assert.Contains(modules, m => m.Name == "VexHub" && m.SchemaName == "vexhub");
|
|
Assert.Contains(modules, m => m.Name == "Remediation" && m.SchemaName == "remediation");
|
|
Assert.Contains(modules, m => m.Name == "VexLens" && m.SchemaName == "vexlens");
|
|
Assert.Contains(modules, m => m.Name == "SbomLineage" && m.SchemaName == "sbom");
|
|
Assert.Contains(modules, m => m.Name == "ReachGraph" && m.SchemaName == "reachgraph");
|
|
Assert.Contains(modules, m => m.Name == "Verdict" && m.SchemaName == "stellaops");
|
|
Assert.Contains(modules, m => m.Name == "FindingsLedger" && m.SchemaName == "findings");
|
|
Assert.Contains(modules, m => m.Name == "Signer" && m.SchemaName == "signer");
|
|
Assert.Contains(modules, m => m.Name == "IssuerDirectory" && m.SchemaName == "issuer");
|
|
Assert.Contains(modules, m => m.Name == "Workflow" && m.SchemaName == "workflow");
|
|
Assert.Contains(modules, m => m.Name == "PacksRegistry" && m.SchemaName == "packs");
|
|
Assert.Contains(modules, m => m.Name == "OpsMemory" && m.SchemaName == "opsmemory");
|
|
Assert.Contains(modules, m => m.Name == "ExportCenter" && m.SchemaName == "export_center");
|
|
Assert.Contains(modules, m => m.Name == "Integrations" && m.SchemaName == "integrations");
|
|
Assert.Contains(modules, m => m.Name == "Replay" && m.SchemaName == "replay");
|
|
Assert.Contains(modules, m => m.Name == "RiskEngine" && m.SchemaName == "riskengine");
|
|
Assert.True(MigrationModuleRegistry.ModuleNames.Count() >= 36);
|
|
}
|
|
|
|
[Fact]
|
|
public void Modules_Are_AutoDiscovered_From_Plugins()
|
|
{
|
|
var pluginTypes = typeof(MigrationModuleRegistry)
|
|
.Assembly
|
|
.GetTypes()
|
|
.Where(static type =>
|
|
typeof(IMigrationModulePlugin).IsAssignableFrom(type) &&
|
|
!type.IsAbstract &&
|
|
!type.IsInterface)
|
|
.ToArray();
|
|
|
|
Assert.NotEmpty(pluginTypes);
|
|
Assert.Equal(pluginTypes.Length, MigrationModuleRegistry.Modules.Count);
|
|
}
|
|
|
|
[Fact]
|
|
public void FindModule_Finds_By_Name_CaseInsensitive()
|
|
{
|
|
var result = MigrationModuleRegistry.FindModule("authority");
|
|
Assert.NotNull(result);
|
|
Assert.Equal("authority", result!.SchemaName);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetModules_Filtered_Returns_Single()
|
|
{
|
|
var result = MigrationModuleRegistry.GetModules("Authority");
|
|
var module = Assert.Single(result);
|
|
Assert.Equal("authority", module.SchemaName);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetModules_All_Returns_All()
|
|
{
|
|
var result = MigrationModuleRegistry.GetModules(null);
|
|
Assert.True(result.Count() >= 36);
|
|
}
|
|
}
|