Some checks failed
Main Confidence / confidence (push) Failing after 46s
## Summary - implement Spec 211 runtime trend reporting with bounded lane history, drift classification, hotspot trend output, and recalibration evidence handling - extend the repo-truth governance seams and workflow wrappers for comparable-bundle hydration, trend artifact publication, and contract-backed reporting - add the Spec 211 planning artifacts, data model, quickstart, tasks, and repository contract documents ## Validation - parsed `specs/211-runtime-trend-recalibration/contracts/test-runtime-trend-history.schema.json` - parsed `specs/211-runtime-trend-recalibration/contracts/test-runtime-trend.logical.openapi.yaml` - re-ran cross-artifact consistency analysis for the Spec 211 artifact set until no material findings remained - no application test suite was re-run as part of this final commit/push/PR step Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #244
97 lines
3.1 KiB
PHP
97 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Support;
|
|
|
|
final class TestLaneTrendFixtures
|
|
{
|
|
public static function artifactDirectory(string $suffix): string
|
|
{
|
|
return sprintf('storage/logs/test-lanes/%s', trim($suffix, '/'));
|
|
}
|
|
|
|
/**
|
|
* @param array<string, float> $durationsByFile
|
|
* @return list<array<string, mixed>>
|
|
*/
|
|
public static function slowestEntries(array $durationsByFile, string $laneId): array
|
|
{
|
|
$entries = array_values(array_map(
|
|
static fn (float $seconds, string $filePath): array => [
|
|
'label' => $filePath.'::synthetic',
|
|
'subject' => $filePath.'::synthetic',
|
|
'filePath' => $filePath,
|
|
'durationSeconds' => $seconds,
|
|
'wallClockSeconds' => $seconds,
|
|
'laneId' => $laneId,
|
|
],
|
|
$durationsByFile,
|
|
array_keys($durationsByFile),
|
|
));
|
|
|
|
usort($entries, static fn (array $left, array $right): int => $right['wallClockSeconds'] <=> $left['wallClockSeconds']);
|
|
|
|
return $entries;
|
|
}
|
|
|
|
/**
|
|
* @param array<string, float> $durationsByFile
|
|
* @param array<string, mixed>|null $ciContext
|
|
* @return array<string, mixed>
|
|
*/
|
|
public static function buildReport(
|
|
string $laneId,
|
|
float $wallClockSeconds,
|
|
array $durationsByFile = [],
|
|
?string $artifactDirectory = null,
|
|
?array $ciContext = null,
|
|
?string $comparisonProfile = null,
|
|
): array {
|
|
return TestLaneReport::buildReport(
|
|
laneId: $laneId,
|
|
wallClockSeconds: $wallClockSeconds,
|
|
slowestEntries: self::slowestEntries($durationsByFile, $laneId),
|
|
durationsByFile: $durationsByFile,
|
|
artifactDirectory: $artifactDirectory,
|
|
comparisonProfile: $comparisonProfile,
|
|
ciContext: $ciContext,
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, mixed> $artifact
|
|
*/
|
|
public static function writeTrendHistory(string $laneId, array $artifact, ?string $artifactDirectory = null): string
|
|
{
|
|
$artifactPaths = TestLaneReport::artifactPaths($laneId, $artifactDirectory);
|
|
$absolutePath = TestLaneManifest::absolutePath($artifactPaths['trendHistory']);
|
|
$directory = dirname($absolutePath);
|
|
|
|
if (! is_dir($directory)) {
|
|
mkdir($directory, 0777, true);
|
|
}
|
|
|
|
file_put_contents($absolutePath, json_encode($artifact, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR));
|
|
|
|
return $absolutePath;
|
|
}
|
|
|
|
/**
|
|
* @return array<string, mixed>
|
|
*/
|
|
public static function readTrendHistory(string $laneId, ?string $artifactDirectory = null): array
|
|
{
|
|
$artifactPaths = TestLaneReport::artifactPaths($laneId, $artifactDirectory);
|
|
$absolutePath = TestLaneManifest::absolutePath($artifactPaths['trendHistory']);
|
|
|
|
if (! is_file($absolutePath)) {
|
|
return [];
|
|
}
|
|
|
|
$decoded = json_decode((string) file_get_contents($absolutePath), true);
|
|
|
|
return is_array($decoded) ? $decoded : [];
|
|
}
|
|
}
|