TenantAtlas/apps/platform/tests/Feature/Guards/TestLaneTrendClassificationTest.php
Ahmed Darrazi 97262787c9
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 4m15s
feat: implement runtime trend recalibration reporting
2026-04-18 09:34:23 +02:00

79 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
use Tests\Support\TestLaneTrendFixtures;
function classifiedTrendReport(string $laneId, string $suffix, array $seededHistory, float $currentSeconds): array
{
$artifactDirectory = TestLaneTrendFixtures::artifactDirectory('trend-classification/'.$suffix);
$durationsByFile = [
'tests/Feature/Guards/TestLaneTrendClassificationTest.php' => 10.0,
'tests/Feature/Guards/TestLaneTrendSummaryContractTest.php' => 8.0,
];
$workflowId = $laneId === 'confidence' ? 'main-confidence' : 'pr-fast-feedback';
$triggerClass = $laneId === 'confidence' ? 'mainline-push' : 'pull-request';
$comparisonProfile = in_array($laneId, ['fast-feedback', 'confidence'], true)
? 'shared-test-fixture-slimming'
: null;
$baseReport = TestLaneTrendFixtures::buildReport(
laneId: $laneId,
wallClockSeconds: $seededHistory[0],
durationsByFile: $durationsByFile,
artifactDirectory: $artifactDirectory,
ciContext: [
'workflowId' => $workflowId,
'triggerClass' => $triggerClass,
'entryPointResolved' => true,
'workflowLaneMatched' => true,
],
comparisonProfile: $comparisonProfile,
);
$artifact = $baseReport['trendHistoryArtifact'];
$templateRecord = $artifact['history'][0];
$artifact['history'] = array_values(array_map(
static function (float $seconds, int $index) use ($templateRecord): array {
$record = $templateRecord;
$record['runRef'] = sprintf('%s-history-%d', $templateRecord['laneId'], $index + 1);
$record['generatedAt'] = sprintf('2026-04-%02dT09:00:00+00:00', $index + 1);
$record['wallClockSeconds'] = round($seconds, 6);
return $record;
},
$seededHistory,
array_keys($seededHistory),
));
TestLaneTrendFixtures::writeTrendHistory($laneId, $artifact, $artifactDirectory);
return TestLaneTrendFixtures::buildReport(
laneId: $laneId,
wallClockSeconds: $currentSeconds,
durationsByFile: $durationsByFile,
artifactDirectory: $artifactDirectory,
ciContext: [
'workflowId' => $workflowId,
'triggerClass' => $triggerClass,
'entryPointResolved' => true,
'workflowLaneMatched' => true,
],
comparisonProfile: $comparisonProfile,
);
}
it('classifies healthy, budget-near, trending-worse, regressed, and unstable runtime states', function (): void {
$healthy = classifiedTrendReport('fast-feedback', 'healthy', [176.1, 175.6, 176.2, 175.4, 176.0], 176.4);
$budgetNear = classifiedTrendReport('confidence', 'budget-near', [433.0, 430.0, 427.0, 424.0, 420.0], 438.5);
$trendingWorse = classifiedTrendReport('fast-feedback', 'trending-worse', [175.0, 150.0, 125.0, 100.0, 75.0], 195.0);
$regressed = classifiedTrendReport('fast-feedback', 'regressed', [200.0, 180.0, 160.0, 140.0, 120.0], 225.0);
$unstable = classifiedTrendReport('fast-feedback', 'unstable', [170.0, 195.0, 168.0, 193.0, 166.0], 194.0);
expect($healthy['trendCurrentAssessment']['healthClass'])->toBe('healthy')
->and($budgetNear['trendCurrentAssessment']['healthClass'])->toBe('budget-near')
->and($trendingWorse['trendCurrentAssessment']['healthClass'])->toBe('trending-worse')
->and($regressed['trendCurrentAssessment']['healthClass'])->toBe('regressed')
->and($unstable['trendCurrentAssessment']['healthClass'])->toBe('unstable')
->and($unstable['trendCurrentAssessment']['windowStatus'])->toBe('noisy');
});