// ============================================================================= // StellaOps.Integration.Performance - Performance Test Fixture // Sprint 3500.0004.0003 - T7: Performance Baseline Tests // ============================================================================= using System.Text.Json; namespace StellaOps.Integration.Performance; /// /// Test fixture for performance baseline tests. /// Manages baseline data and measurement recording. /// public sealed class PerformanceTestFixture : IDisposable { private readonly string _baselinesPath; private readonly string _outputPath; private readonly Dictionary _baselines; private readonly Dictionary _measurements = new(); public PerformanceTestFixture() { _baselinesPath = Path.Combine(AppContext.BaseDirectory, "baselines"); _outputPath = Path.Combine(AppContext.BaseDirectory, "output"); Directory.CreateDirectory(_outputPath); _baselines = LoadBaselines(); } /// /// Gets the baseline value for a metric. /// Returns default if baseline not found. /// public double GetBaseline(string metric) { return _baselines.TryGetValue(metric, out var baseline) ? baseline : GetDefaultBaseline(metric); } /// /// Records a measurement for a metric. /// public void RecordMeasurement(string metric, double value) { _measurements[metric] = value; } /// /// Gets all recorded measurements. /// public IEnumerable<(string metric, double value)> GetAllMeasurements() { return _measurements.Select(kv => (kv.Key, kv.Value)); } /// /// Gets the path to a test assembly. /// 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"); } /// /// Gets available test assemblies. /// 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); } } } /// /// Saves a report file. /// public void SaveReport(string filename, string content) { var path = Path.Combine(_outputPath, filename); File.WriteAllText(path, content); } private Dictionary LoadBaselines() { var baselinesFile = Path.Combine(_baselinesPath, "performance-baselines.json"); if (File.Exists(baselinesFile)) { var json = File.ReadAllText(baselinesFile); return JsonSerializer.Deserialize>(json) ?? GetDefaultBaselines(); } return GetDefaultBaselines(); } private static Dictionary GetDefaultBaselines() { return new Dictionary { // 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); } }