From 2d01b0460949027984c16b04d035ef9c1ca535db Mon Sep 17 00:00:00 2001 From: KS Date: Tue, 6 Oct 2026 15:32:21 -0400 Subject: [PATCH] Keep only the Fission JetStream 3 signature per platform The script kept every jetstream3 signature, so the A55 fenix rows mixed Fission and non-Fission runs. Keep one signature per application/platform/test: prefer Fission, then the fewest extra_options (skipping profiling runs), then the newest. This matches the dashboard chart (selectCanonicalSignatures in mozilla/performance). --- scripts/fetch-jetstream-data.mjs | 40 ++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/scripts/fetch-jetstream-data.mjs b/scripts/fetch-jetstream-data.mjs index 0a711cc7..03546d88 100644 --- a/scripts/fetch-jetstream-data.mjs +++ b/scripts/fetch-jetstream-data.mjs @@ -120,6 +120,36 @@ function subtestStartDate() { return midnight.toISOString().replace(/\.\d{3}Z$/, ''); } +// One signature per application/platform/test: the Fission run if there is +// one, then the fewest extra_options (so not a profiled or other variant), then +// the newest. Desktop always runs with Fission; Android also has a non-Fission +// job, which is not the one to report. Matches selectCanonicalSignatures in +// mozilla/performance. +function selectCanonicalSignatures(signatures) { + const options = sig => sig.extra_options ?? []; + const hasFission = sig => options(sig).includes('fission'); + + const isMoreCanonical = (candidate, current) => { + if (hasFission(candidate) !== hasFission(current)) { + return hasFission(candidate); + } + if (options(candidate).length !== options(current).length) { + return options(candidate).length < options(current).length; + } + return candidate.id > current.id; + }; + + const canonical = new Map(); + for (const sig of signatures) { + const key = [sig.application, sig.machine_platform, sig.test].join('|'); + const current = canonical.get(key); + if (!current || isMoreCanonical(sig, current)) { + canonical.set(key, sig); + } + } + return [...canonical.values()]; +} + async function fetchSignatures() { const url = `${TREEHERDER_API}/project/${REPOSITORY}/performance/signatures/?framework=${FRAMEWORK_ID}`; console.log('Fetching jetstream3 signatures'); @@ -139,8 +169,14 @@ async function fetchSignatures() { } } - console.log(`Found ${scoreSignatures.length} score signatures and ${subtestSignatures.length} -Geometric signatures`); - return { scoreSignatures, subtestSignatures }; + const canonicalScore = selectCanonicalSignatures(scoreSignatures); + const canonicalSubtest = selectCanonicalSignatures(subtestSignatures); + + console.log( + `Found ${canonicalScore.length} score signatures and ${canonicalSubtest.length} -Geometric signatures ` + + `(of ${scoreSignatures.length} and ${subtestSignatures.length} before dropping variants)` + ); + return { scoreSignatures: canonicalScore, subtestSignatures: canonicalSubtest }; } // Fetch every datum for the given signatures since startDate, tagging each with