79 lines
3.6 KiB
PHP
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');
|
|
});
|