Add integration tests for Proof Chain and Reachability workflows

- Implement ProofChainTestFixture for PostgreSQL-backed integration tests.
- Create StellaOps.Integration.ProofChain project with necessary dependencies.
- Add ReachabilityIntegrationTests to validate call graph extraction and reachability analysis.
- Introduce ReachabilityTestFixture for managing corpus and fixture paths.
- Establish StellaOps.Integration.Reachability project with required references.
- Develop UnknownsWorkflowTests to cover the unknowns lifecycle: detection, ranking, escalation, and resolution.
- Create StellaOps.Integration.Unknowns project with dependencies for unknowns workflow.
This commit is contained in:
StellaOps Bot
2025-12-20 22:19:26 +02:00
parent 3c6e14fca5
commit efe9bd8cfe
86 changed files with 9616 additions and 323 deletions

View File

@@ -0,0 +1,147 @@
// =============================================================================
// StellaOps.Integration.Performance - Performance Test Fixture
// Sprint 3500.0004.0003 - T7: Performance Baseline Tests
// =============================================================================
using System.Text.Json;
namespace StellaOps.Integration.Performance;
/// <summary>
/// Test fixture for performance baseline tests.
/// Manages baseline data and measurement recording.
/// </summary>
public sealed class PerformanceTestFixture : IDisposable
{
private readonly string _baselinesPath;
private readonly string _outputPath;
private readonly Dictionary<string, double> _baselines;
private readonly Dictionary<string, double> _measurements = new();
public PerformanceTestFixture()
{
_baselinesPath = Path.Combine(AppContext.BaseDirectory, "baselines");
_outputPath = Path.Combine(AppContext.BaseDirectory, "output");
Directory.CreateDirectory(_outputPath);
_baselines = LoadBaselines();
}
/// <summary>
/// Gets the baseline value for a metric.
/// Returns default if baseline not found.
/// </summary>
public double GetBaseline(string metric)
{
return _baselines.TryGetValue(metric, out var baseline) ? baseline : GetDefaultBaseline(metric);
}
/// <summary>
/// Records a measurement for a metric.
/// </summary>
public void RecordMeasurement(string metric, double value)
{
_measurements[metric] = value;
}
/// <summary>
/// Gets all recorded measurements.
/// </summary>
public IEnumerable<(string metric, double value)> GetAllMeasurements()
{
return _measurements.Select(kv => (kv.Key, kv.Value));
}
/// <summary>
/// Gets the path to a test assembly.
/// </summary>
public string GetTestAssemblyPath(string name)
{
var path = Path.Combine(AppContext.BaseDirectory, "test-assemblies", $"{name}.dll");
return File.Exists(path) ? path : Path.Combine(AppContext.BaseDirectory, "StellaOps.Integration.Performance.dll");
}
/// <summary>
/// Gets available test assemblies.
/// </summary>
public IEnumerable<(string Name, string Path)> GetTestAssemblies()
{
var testAssembliesDir = Path.Combine(AppContext.BaseDirectory, "test-assemblies");
if (Directory.Exists(testAssembliesDir))
{
foreach (var file in Directory.GetFiles(testAssembliesDir, "*.dll"))
{
yield return (Path.GetFileNameWithoutExtension(file), file);
}
}
else
{
// Use self as test assembly
var selfPath = Path.Combine(AppContext.BaseDirectory, "StellaOps.Integration.Performance.dll");
if (File.Exists(selfPath))
{
yield return ("Self", selfPath);
}
}
}
/// <summary>
/// Saves a report file.
/// </summary>
public void SaveReport(string filename, string content)
{
var path = Path.Combine(_outputPath, filename);
File.WriteAllText(path, content);
}
private Dictionary<string, double> LoadBaselines()
{
var baselinesFile = Path.Combine(_baselinesPath, "performance-baselines.json");
if (File.Exists(baselinesFile))
{
var json = File.ReadAllText(baselinesFile);
return JsonSerializer.Deserialize<Dictionary<string, double>>(json) ?? GetDefaultBaselines();
}
return GetDefaultBaselines();
}
private static Dictionary<string, double> GetDefaultBaselines()
{
return new Dictionary<string, double>
{
// Score computation
["score_computation_ms"] = 100,
["score_computation_large_ms"] = 500,
// Proof bundle
["proof_bundle_generation_ms"] = 200,
["proof_signing_ms"] = 50,
// Call graph
["dotnet_callgraph_extraction_ms"] = 500,
// Reachability
["reachability_computation_ms"] = 100,
["reachability_large_graph_ms"] = 500,
["reachability_deep_path_ms"] = 200
};
}
private static double GetDefaultBaseline(string metric)
{
// Default to 1 second for unknown metrics
return 1000;
}
public void Dispose()
{
// Save measurements for potential baseline updates
var measurementsFile = Path.Combine(_outputPath, "measurements.json");
var json = JsonSerializer.Serialize(_measurements, new JsonSerializerOptions { WriteIndented = true });
File.WriteAllText(measurementsFile, json);
}
}