From d76b6da053615b00c4e0c772616fc097688d6cab Mon Sep 17 00:00:00 2001 From: Ryan Curran Date: Wed, 26 Aug 2026 11:23:54 -0400 Subject: [PATCH 1/2] Estimate when a try push will finish Adds an ETA to the push list and the push detail view. Two numbers, not one, because a push does not finish smoothly: on a sampled 907-job push, 90% of the jobs were done at 47 minutes and the last one at 144, and the tail was queueing (95-117 min) rather than slow work (12-25 min). The headline is when 90% of the jobs are in; the full finish sits beside it as an approximation. Backtested against 369 try pushes / 73,864 jobs by replaying 77 completed pushes at nine points each. Most-results: 2 min median error, within +/-25% 70% of the time, overruns by >30 min in 1%. All-done: 13 min, 39%, 32%. Naive percent-complete extrapolation, for contrast, has a 84-165 min median error and a -50 to -105 min bias, because the completion curve is nowhere near linear. Run time comes from a bundled 137 KB table of per-job-type medians -- duration has a median coefficient of variation of 5%, so this predicts to within 5%. Queue wait, the hard part, is read live per worker pool from the push itself. Building the whole thing from the push's own jobs instead lands within +/-25% only 12% of the time, which is why the table ships. Below 60% pool coverage the estimate is wrong by ~113 min, so it is not shown; a flat "rough" band was measured and dropped (within +/-50% only half the time, and an honest range has to span 6x). Instead that case shows the precise thing it is actually waiting for: the build. Gecko's shippable pipeline is three stages deep, so the chain is walked rather than just the running stage. Predicted build finishes land within 5 min 71% of the time. Also fixes three things this work surfaced: - TreeHerder emits an `unscheduled` job state that JobState did not model, so the parser's unknown-state fallback filed those jobs as `.completed`. They were invisible to isRunning and could fire "Try push passed" with jobs not yet started -- a live 691-job push had 24 of them. Unknown states now default to `.pending`, since guessing "done" is the dangerous direction. - Absent timestamps arrive as 0, not null, and decoded to a valid 1970 date, so every queued job looked already-started. - A still-running push with failures showed only the failure badge, hiding the ETA on exactly the pushes being watched most closely. --- BuildWatch/Models/Job.swift | 62 ++- BuildWatch/Models/JobDurationTable.swift | 70 +++ BuildWatch/Models/PushETA.swift | 307 +++++++++++++ BuildWatch/Models/PushSummary.swift | 23 +- BuildWatch/Resources/JobDurations.json | 1 + BuildWatch/Services/TreeHerderService.swift | 22 +- .../ViewModels/DashboardViewModel.swift | 2 +- BuildWatch/Views/DashboardView.swift | 22 + BuildWatch/Views/ETAView.swift | 423 ++++++++++++++++++ BuildWatch/Views/PushDetailView.swift | 17 + README.md | 53 +++ tools/generate-duration-table.py | 141 ++++++ 12 files changed, 1127 insertions(+), 16 deletions(-) create mode 100644 BuildWatch/Models/JobDurationTable.swift create mode 100644 BuildWatch/Models/PushETA.swift create mode 100644 BuildWatch/Resources/JobDurations.json create mode 100644 BuildWatch/Views/ETAView.swift create mode 100755 tools/generate-duration-table.py diff --git a/BuildWatch/Models/Job.swift b/BuildWatch/Models/Job.swift index b88500d..73abf4d 100644 --- a/BuildWatch/Models/Job.swift +++ b/BuildWatch/Models/Job.swift @@ -52,6 +52,15 @@ nonisolated enum JobResult: String, Codable, Sendable, CaseIterable { nonisolated enum JobState: String, Codable, Sendable { case pending, running, completed + /// A task whose dependencies haven't resolved yet — a test still waiting on its build. + /// TreeHerder emits this alongside the other three and it is not rare: a live 691-job + /// push had 24 jobs in it. It was previously unmodelled, so the parser's unknown-state + /// fallback filed them as `.completed`, which made them invisible to `isRunning` and + /// could fire "Try push passed" with two dozen jobs not yet started. + case unscheduled + + /// Not started, whether or not the queue has released it yet. + var isWaiting: Bool { self == .pending || self == .unscheduled } } nonisolated struct Job: Identifiable, Codable, Sendable { @@ -66,6 +75,9 @@ nonisolated struct Job: Identifiable, Codable, Sendable { let jobGroupSymbol: String let state: JobState let result: JobResult + /// When Taskcluster accepted the task. The basis of every queue-wait calculation — + /// `startTimestamp - submitTimestamp` is how long this job sat in its pool. + let submitTimestamp: Int? let startTimestamp: Int? let endTimestamp: Int? let tier: Int @@ -74,6 +86,45 @@ nonisolated struct Job: Identifiable, Codable, Sendable { startTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) } } + var submitDate: Date? { + submitTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) } + } + + var endDate: Date? { + endTimestamp.map { Date(timeIntervalSince1970: TimeInterval($0)) } + } + + /// How long this job waited in its worker pool before a worker picked it up. + /// Only known once it has started; that is exactly what makes it useful for + /// predicting the jobs in the same pool that haven't. + var queueWait: TimeInterval? { + guard let s = submitTimestamp, let st = startTimestamp, st > s else { return nil } + return TimeInterval(st - s) + } + + /// Jobs sharing this key contend for the same workers, so they share a queue wait. + var poolKey: String { "\(platform)|\(platformOption)" } + + /// Where this job sits in the build chain tests wait on, or `nil` if it isn't part of it. + /// + /// A shippable macOS build is not one task, it is a pipeline: `instrumented-build-…` + /// produces a profiling binary, `generate-profile-…` runs it, and only then does + /// `build-…` produce the artifact tests consume. Missing the middle stage is why an + /// earlier version of this found no build to wait on at all on a live Talos push — the + /// `build-*` jobs were themselves still unscheduled, behind a running `generate-profile`. + /// + /// Deliberately a name check. The alternative is the Taskcluster dependency graph, which + /// costs one request per task. + var buildStage: Int? { + if jobTypeName.hasPrefix("toolchain-") { return 0 } + if jobTypeName.hasPrefix("instrumented-build-") { return 1 } + if jobTypeName.hasPrefix("generate-profile-") { return 2 } + if jobTypeName.hasPrefix("build-") + || jobTypeName.hasPrefix("spidermonkey-") + || jobTypeName.contains("-build-") { return 3 } + return nil + } + var duration: TimeInterval? { guard let s = startTimestamp, let e = endTimestamp, e > s else { return nil } return TimeInterval(e - s) @@ -105,7 +156,7 @@ nonisolated struct Job: Identifiable, Codable, Sendable { } var isRunning: Bool { state == .running } - var isPending: Bool { state == .pending } + var isPending: Bool { state.isWaiting } var displayResult: JobResult { state == .completed ? result : .unknown @@ -118,9 +169,10 @@ nonisolated struct Job: Identifiable, Codable, Sendable { /// Spoken status, so VoiceOver conveys what the coloured glyph conveys visually. var statusDescription: String { switch state { - case .pending: "pending" - case .running: elapsedString().map { "running for \($0)" } ?? "running" - case .completed: durationString.map { "\(result.displayName), took \($0)" } ?? result.displayName + case .pending: "pending" + case .unscheduled: "waiting on its build" + case .running: elapsedString().map { "running for \($0)" } ?? "running" + case .completed: durationString.map { "\(result.displayName), took \($0)" } ?? result.displayName } } @@ -149,7 +201,7 @@ nonisolated struct PlatformGroup: Identifiable, Sendable { var failures = 0, pending = 0, running = 0, successes = 0 for job in jobs { switch job.state { - case .pending: pending += 1 + case .pending, .unscheduled: pending += 1 case .running: running += 1 case .completed: if job.result.isFailure { failures += 1 } diff --git a/BuildWatch/Models/JobDurationTable.swift b/BuildWatch/Models/JobDurationTable.swift new file mode 100644 index 0000000..47655d7 --- /dev/null +++ b/BuildWatch/Models/JobDurationTable.swift @@ -0,0 +1,70 @@ +import Foundation + +/// How long each kind of job *runs*, learned offline from real try pushes. +/// +/// Run time is the one genuinely predictable part of a try push: measured across 369 try +/// pushes and 73,864 jobs, a job's duration has a median coefficient of variation of 5%, +/// and a plain per-job-type median predicts a held-out run to within 5% at the median. +/// Queue *wait* is the unpredictable part, and that is estimated live per worker pool from +/// the push itself — see `PushETA`. +/// +/// Shipping this table is what makes the estimate work. The same estimator built purely +/// from the push's own completed jobs lands within ±25% only 12% of the time; with the +/// table it is 63%. There is no runtime cost — one bundled JSON read, lazily, once. +/// +/// Regenerate with `tools/generate-duration-table.py`. +nonisolated final class JobDurationTable: Sendable { + + static let shared = JobDurationTable() + + private let exact: [String: Double] + private let family: [String: Double] + private let platform: [String: Double] + private let fallback: Double + + /// Used when the bundle resource is missing entirely — the global median job. + private static let hardFallback: Double = 20.8 + + private init() { + guard + let url = Bundle.main.url(forResource: "JobDurations", withExtension: "json"), + let data = try? Data(contentsOf: url), + let decoded = try? JSONDecoder().decode(Payload.self, from: data) + else { + exact = [:]; family = [:]; platform = [:]; fallback = Self.hardFallback + return + } + exact = decoded.exact + family = decoded.family + platform = decoded.platform + fallback = decoded.global + } + + private struct Payload: Decodable { + let exact: [String: Double] + let family: [String: Double] + let platform: [String: Double] + let global: Double + } + + /// Expected run time in seconds, most specific match first. + /// + /// The `family` tier exists because chunked suites are named `…-wdspec-headless-1`, + /// `…-2`, and so on. Collapsing the chunk number lets a chunk BuildWatch has never seen + /// inherit its siblings' timing, which cuts the table's miss rate from 14% to 8%. + func expectedRunTime(for job: Job) -> TimeInterval { + let minutes = exact[job.jobTypeName] + ?? family[Self.familyKey(job.jobTypeName)] + ?? platform["\(job.platform)|\(job.platformOption)"] + ?? fallback + return minutes * 60 + } + + /// Strips a trailing chunk number: `…-wdspec-headless-1` → `…-wdspec-headless`. + static func familyKey(_ jobTypeName: String) -> String { + guard let dash = jobTypeName.lastIndex(of: "-") else { return jobTypeName } + let suffix = jobTypeName[jobTypeName.index(after: dash)...] + guard !suffix.isEmpty, suffix.allSatisfy(\.isNumber) else { return jobTypeName } + return String(jobTypeName[..30 min | +/// |---|---|---|---|---| +/// | `mostResultsBy` (90% of jobs) | **2 min** | **63%** | **88%** | **1%** | +/// | `allDoneBy` (last job) | 13 min | 39% | 62% | 32% | +/// +/// `mostResultsBy` is the number to lead with — it answers "when will I know if this is +/// green", it is nearly unbiased, and it almost never overruns. `allDoneBy` is real but +/// soft, which is why the UI renders it as an approximation rather than a clock time. +/// +/// ## How +/// +/// Per worker pool, the jobs that have already started tell you what the ones that haven't +/// will wait: on one push, 76 jobs in `macosx1500-aarch64-shippable` had a p25, median and +/// p90 queue wait of 140.7, 140.7 and 144.6 minutes, because they are all gated on the same +/// build and released together. Add the expected run time from `JobDurationTable`, take the +/// projected finish of every unresolved job, and read off the 90th percentile and the max. +/// +/// Naive alternatives were measured and rejected: extrapolating from percent-complete has a +/// median error of 84–165 minutes and a −50 to −105 minute bias, because the completion +/// curve is nowhere near linear. +nonisolated struct PushETA: Sendable, Equatable { + + /// When 90% of this push's jobs will have resolved. The headline number. + let mostResultsBy: Date + + /// When the last job will resolve. Approximate by nature — see the type comment. + let allDoneBy: Date + + /// The worker pool holding everything up, if one clearly is. + let longPole: String? + + /// Unresolved jobs in `longPole`. + let longPoleRemaining: Int + + /// When the push started, so the UI can draw elapsed against remaining. + let pushedAt: Date + + let confidence: Confidence + + /// Set only when `confidence == .blockedOnBuild`. + let blockingBuild: BlockingBuild? + + /// How much of the push we can actually see the shape of yet. + /// + /// The estimate only works once a pool has *someone* in it who has started — that is + /// what reveals the pool's queue wait. Early on it doesn't: median pool coverage is 20% + /// at 15 minutes in and 35% at 20, and estimates made in that window are wrong by + /// around 113 minutes. So the UI shows nothing rather than something wrong. + /// Three states, because there are three genuinely different situations and only one of + /// them supports a countdown. + /// + /// A flat "rough estimate" band was tried and dropped. Below the firm bar the push ETA + /// lands within ±50% only about half the time, and a range wide enough to be honest — + /// 77% coverage — has to span 6×, i.e. "somewhere between one hour and six". That is not + /// worth a hero slot. But the reason those pushes are unpredictable turned out to be + /// specific and fixable: they are nearly all waiting on a build, and *build* finish + /// times are sharp. So instead of a vague push ETA, that case shows the precise thing. + enum Confidence: Sendable { + /// Nothing to go on yet. Show progress, not a time. Only ~6% of the window. + case estimating + /// The push is gated on a build that is still running. Show the build's finish + /// instead of the push's: measured over 4,438 running builds, the predicted end is + /// within 5 minutes 71% of the time and within 10 minutes 80%. + case blockedOnBuild + /// Enough pools have started that the push ETA holds up: within ±25% of the true + /// remaining time 70% of the time, and it overruns by more than half an hour in 1% + /// of cases. + case firm + } + + /// The build chain everything is queued behind, when that is the whole story. + struct BlockingBuild: Sendable, Equatable { + /// The stage running right now — what to show the reader, because it is the part + /// that is actually happening. + let currentStage: String + /// When the *last* stage of the chain is expected to land, which is when tests are + /// released. Later than the running stage's own finish whenever stages remain. + let releasesAt: Date + /// Jobs that cannot start until then. + let blockedJobs: Int + } + + /// `allDoneBy` underestimates: with no correction the true finish is 1.9× the predicted + /// remaining time at the median. Scaling the remaining span by 1.25 brings that to 1.5× + /// and lifts within-±50% accuracy from 55% to 62%, while still overshooting by more than + /// 2× in only 2% of cases. Erring long is the right direction for an ETA. + private static let tailCalibration: Double = 1.25 + + /// The estimate is only trustworthy once this share of the unresolved jobs sit in pools + /// where something has already started — that is what reveals the pool's queue wait. + /// + /// 0.60 is where the accuracy cliff is. Coarsening the pool key to reach the bar sooner + /// was tried and rejected: it lifts how often an ETA is shown from 28% to 32% of the + /// window but drops within-±25% accuracy from 67% to 59% and takes overruns from 1% to + /// 6%, because a pool key that ignores the build variant stops modelling the dependency + /// that actually gates the wait. + /// + /// The bar is not as restrictive as it sounds: 83% of pushes clear it, at a median of 30 + /// minutes in, and then stay clear for a median 72% of what's left. + private static let firmCoverage = 0.60 + + /// The decision task has to land before there is anything to estimate. + private static let minimumElapsed: TimeInterval = 8 * 60 + + // MARK: - Estimation + + /// Returns `nil` when the push has no unresolved jobs — a finished push has no ETA. + init?(jobs: [Job], pushedAt: Date, now: Date = Date(), table: JobDurationTable = .shared) { + guard !jobs.isEmpty else { return nil } + + var resolvedEnds: [Date] = [] + var unresolved: [Job] = [] + var waitsByPool: [String: [TimeInterval]] = [:] + + for job in jobs { + if job.state == .completed, let end = job.endDate { + resolvedEnds.append(end) + } else { + unresolved.append(job) + } + // A start stamp is an observation of that pool's queue whether the job has + // since finished or not, so completed jobs feed the wait table too. + if let wait = job.queueWait { + waitsByPool[job.poolKey, default: []].append(wait) + } + } + + guard !unresolved.isEmpty else { return nil } + + let poolWaits = waitsByPool.mapValues { Self.median($0) } + let globalWait = poolWaits.isEmpty ? 0 : Self.median(Array(poolWaits.values)) + + // A job in a pool nothing has started in is usually not idly queued — it is + // waiting on a build. Finding that build turns "no idea" into a real release time: + // one live push had 32 of its 37 unresolved jobs sitting in `unscheduled` behind a + // single running macOS build, with no pool observation to go on at all. + let gate = Self.buildGate( + unresolved, poolWaits: poolWaits, globalWait: globalWait, now: now, table: table + ) + + var projected: [Date] = resolvedEnds + projected.reserveCapacity(jobs.count) + + var worstEnd = Date.distantPast + var worstPool: Job? + var observedPools = 0 + + for job in unresolved { + let end: Date + if let start = job.startDate { + // Already running: the only unknown left is how long it runs. + end = start.addingTimeInterval(table.expectedRunTime(for: job)) + } else { + guard let submitted = job.submitDate else { continue } + if let known = poolWaits[job.poolKey] { + observedPools += 1 + // Never predict a wait shorter than the wait already served. + let wait = max(known, now.timeIntervalSince(submitted)) + end = submitted + .addingTimeInterval(wait) + .addingTimeInterval(table.expectedRunTime(for: job)) + } else if let gate { + // Released when the build chain lands, then a normal queue wait on top. + end = max(gate.releasesAt, now) + .addingTimeInterval(globalWait) + .addingTimeInterval(table.expectedRunTime(for: job)) + } else { + let wait = max(globalWait, now.timeIntervalSince(submitted)) + end = submitted + .addingTimeInterval(wait) + .addingTimeInterval(table.expectedRunTime(for: job)) + } + } + projected.append(end) + if end > worstEnd { + worstEnd = end + worstPool = job + } + } + + guard projected.count > resolvedEnds.count else { return nil } + + projected.sort() + let p90 = projected[min(projected.count - 1, Int(Double(projected.count) * 0.9))] + let last = projected[projected.count - 1] + + self.pushedAt = pushedAt + self.mostResultsBy = max(now, p90) + self.allDoneBy = max( + self.mostResultsBy, + now.addingTimeInterval(max(0, last.timeIntervalSince(now)) * Self.tailCalibration) + ) + + let coverage = Double(observedPools) / Double(unresolved.count) + let elapsed = now.timeIntervalSince(pushedAt) + if elapsed >= Self.minimumElapsed && coverage >= Self.firmCoverage { + confidence = .firm + blockingBuild = nil + } else if let gate, gate.releasesAt > now { + confidence = .blockedOnBuild + blockingBuild = BlockingBuild( + currentStage: gate.currentStage, + releasesAt: gate.releasesAt, + blockedJobs: unresolved.count { $0.startDate == nil && poolWaits[$0.poolKey] == nil } + ) + } else { + confidence = .estimating + blockingBuild = nil + } + + // Only name a long pole when it is genuinely holding things up — otherwise the + // callout is noise. The true long-pole pool is in this estimator's top three 86% + // of the time but top *one* only 51%, so it is offered as a hint, not a fact. + if let worstPool, worstEnd > self.mostResultsBy.addingTimeInterval(5 * 60) { + longPole = worstPool.platformDisplay + longPoleRemaining = unresolved.count { $0.poolKey == worstPool.poolKey } + } else { + longPole = nil + longPoleRemaining = 0 + } + } + + // MARK: - Display helpers + + /// Fraction of the estimated total wall time already elapsed, for the progress track. + func progress(asOf now: Date = Date()) -> Double { + let total = allDoneBy.timeIntervalSince(pushedAt) + guard total > 0 else { return 1 } + return min(1, max(0, now.timeIntervalSince(pushedAt) / total)) + } + + /// Where `mostResultsBy` sits along that same track, so the UI can mark it. + func mostResultsFraction() -> Double { + let total = allDoneBy.timeIntervalSince(pushedAt) + guard total > 0 else { return 1 } + return min(1, max(0, mostResultsBy.timeIntervalSince(pushedAt) / total)) + } + + /// Walks the build chain stage by stage to find when tests are released. + /// + /// Each stage can only start once every earlier stage has landed, so the frontier is + /// carried forward: a running stage is projected from its own start, and a stage that + /// hasn't started is projected from the frontier plus a normal queue wait. Chaining + /// rather than reading only the running stage shrinks the no-estimate dead zone from 13% + /// of the window to 10% and lifts the gated tier's within-±50% accuracy from 54% to 58%, + /// while leaving the firm tier untouched. + private static func buildGate( + _ unresolved: [Job], poolWaits: [String: TimeInterval], globalWait: TimeInterval, + now: Date, table: JobDurationTable + ) -> (releasesAt: Date, currentStage: String)? { + var frontier: Date? + var runningStage: (Date, String)? + + for stage in 0...3 { + var ends: [Date] = [] + for job in unresolved where job.buildStage == stage { + let run = table.expectedRunTime(for: job) + if let start = job.startDate { + let end = start.addingTimeInterval(run) + ends.append(end) + // Prefer the latest-finishing running stage as the one to name. + if runningStage == nil || end > runningStage!.0 { + runningStage = (end, job.jobTypeName) + } + } else if let frontier { + ends.append(frontier.addingTimeInterval(globalWait).addingTimeInterval(run)) + } else if let known = poolWaits[job.poolKey], let submitted = job.submitDate { + ends.append( + submitted + .addingTimeInterval(max(known, now.timeIntervalSince(submitted))) + .addingTimeInterval(run) + ) + } + } + if let stageEnd = ends.max() { + frontier = max(frontier ?? stageEnd, stageEnd) + } + } + + guard let frontier, let runningStage else { return nil } + return (frontier, runningStage.1) + } + + private static func median(_ values: [TimeInterval]) -> TimeInterval { + guard !values.isEmpty else { return 0 } + let sorted = values.sorted() + let mid = sorted.count / 2 + return sorted.count.isMultiple(of: 2) + ? (sorted[mid - 1] + sorted[mid]) / 2 + : sorted[mid] + } +} diff --git a/BuildWatch/Models/PushSummary.swift b/BuildWatch/Models/PushSummary.swift index 7722b7f..2d5b45a 100644 --- a/BuildWatch/Models/PushSummary.swift +++ b/BuildWatch/Models/PushSummary.swift @@ -36,13 +36,22 @@ nonisolated struct PushSummary: Sendable { /// correction ever arrived. let lowerTierActive: Int + /// When this push is expected to finish. `nil` once it has, or when there isn't yet + /// enough of it visible to say anything — see `PushETA.Confidence`. + /// + /// Estimated here, at ingest, rather than in a view: it is derived state like every + /// other field on this type, and it walks the whole job array to do it. + let eta: PushETA? + var isRunning: Bool { runningCount > 0 || pendingCount > 0 || lowerTierActive > 0 } var hasJobs: Bool { totalCount > 0 || lowerTierTotal > 0 } var isComplete: Bool { hasJobs && !isRunning } - static let empty = PushSummary(jobs: []) + static let empty = PushSummary(jobs: [], pushedAt: nil) - init(jobs: [Job]) { + /// - Parameter pushedAt: when the push landed, needed to draw elapsed against + /// remaining. Omit it and no ETA is produced. + init(jobs: [Job], pushedAt: Date?, now: Date = Date()) { var byPlatform: [String: [Job]] = [:] var failures = 0, running = 0, pending = 0, successes = 0, total = 0 var otherTotal = 0, otherFailures = 0, otherActive = 0 @@ -51,7 +60,7 @@ nonisolated struct PushSummary: Sendable { guard job.tier == 1 else { otherTotal += 1 switch job.state { - case .running, .pending: otherActive += 1 + case .running, .pending, .unscheduled: otherActive += 1 case .completed: if job.result.isFailure { otherFailures += 1 } } continue @@ -59,7 +68,7 @@ nonisolated struct PushSummary: Sendable { total += 1 switch job.state { - case .pending: pending += 1 + case .pending, .unscheduled: pending += 1 case .running: running += 1 case .completed: if job.result.isFailure { failures += 1 } @@ -81,6 +90,12 @@ nonisolated struct PushSummary: Sendable { lowerTierTotal = otherTotal lowerTierFailures = otherFailures lowerTierActive = otherActive + + // Every tier counts here. Tier 2 is not a rounding error — one sampled push ran + // 209 tier-1 jobs against 545 tier-2 — and an ETA that ignored it would promise a + // finish while hundreds of jobs were still queued, exactly the bug that made + // `isComplete` count all tiers in the first place. + eta = pushedAt.flatMap { PushETA(jobs: jobs, pushedAt: $0, now: now) } } /// Spoken summary for the push row, so a VoiceOver user hears the same thing the diff --git a/BuildWatch/Resources/JobDurations.json b/BuildWatch/Resources/JobDurations.json new file mode 100644 index 0000000..e084f43 --- /dev/null +++ b/BuildWatch/Resources/JobDurations.json @@ -0,0 +1 @@ +{"exact":{"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain":13.2,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-6":12.3,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-fis-hv":14.7,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-fis-hv-3":20.3,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-nofis":14.7,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-nofis-6":11.6,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-xorig":14.6,"test-android-em-14-x86_64-lite/opt-geckoview-reftest-nofis-3":11.0,"test-android-em-14-x86_64-lite/opt-geckoview-reftest-nofis-4":11.7,"test-android-em-14-x86_64-lite/opt-geckoview-test-verify-nofis-1":3.7,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-1":6.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-10":13.9,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-11":20.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-12":15.0,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-13":14.4,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-14":26.7,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-15":27.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-16":14.0,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-17":17.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-18":14.2,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-19":15.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-2":25.0,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-20":6.0,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-21":27.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-22":27.5,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-23":14.2,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-24":28.4,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-25":21.7,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-26":14.4,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-27":28.4,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-28":15.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-29":5.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-3":23.2,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-30":3.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-32":15.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-33":12.6,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-34":14.2,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-35":30.2,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-36":18.3,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-37":16.9,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-4":14.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-5":14.4,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-6":14.2,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-7":15.9,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-8":14.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis-9":18.0,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis":30.7,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-1":5.3,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-10":14.2,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-11":26.0,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-12":24.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-13":5.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-14":6.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-15":22.3,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-2":26.3,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-3":30.7,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-4":15.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-5":21.3,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-6":17.0,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-7":18.6,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-8":26.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis-9":24.6,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-2":24.4,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-3":12.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-4":11.5,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-5":12.9,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-6":16.4,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-7":24.2,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-9":8.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-nofis-1":4.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-nofis-6":12.4,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-nofis-8":12.4,"test-android-em-14-x86_64-lite/opt-geckoview-xpcshell":32.7,"test-android-em-14-x86_64-lite/opt-geckoview-xpcshell-nofis":32.0,"test-android-em-14-x86_64-lite/opt-geckoview-xpcshell-nofis-1":19.2,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-nofis-15":24.5,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-nofis-33":24.9,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-nofis-35":30.6,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-nofis-36":32.8,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-nofis-37":32.9,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-reftest-nofis-11":32.4,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-reftest-nofis-12":33.5,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-reftest-nofis-13":31.2,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-reftest-nofis-7":31.0,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-reftest-nofis-8":30.6,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-wdspec-7":27.1,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-xpcshell-2":29.2,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-nofis-10":25.7,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-nofis-33":24.2,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-nofis-36":34.0,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-nofis-37":34.5,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-nofis-9":32.2,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-reftest-nofis-3":33.8,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-reftest-nofis-7":25.8,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-wdspec-5":14.9,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-wdspec-nofis-5":26.8,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-wdspec-nofis-9":27.0,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain":18.1,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-6":27.2,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-aab-nofis":17.4,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-fis-hv":11.3,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-nofis":13.5,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-xorig":4.3,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-xorig-9":25.7,"test-android-em-14-x86_64/debug-geckoview-reftest-nofis-3":29.6,"test-android-em-14-x86_64/debug-geckoview-reftest-nofis-4":26.3,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-1":8.1,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-10":31.5,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-19":24.8,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-20":32.5,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-25":32.1,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-35":31.8,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-38":31.4,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-40":31.2,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-42":33.1,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-43":33.3,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-6":24.9,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis-7":33.5,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-nofis-1":6.4,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-nofis-11":34.0,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-nofis-16":31.2,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-nofis-3":36.3,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-nofis-4":31.0,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-nofis-5":30.8,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-nofis-6":32.9,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-swr-nofis-1":6.6,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-swr-nofis-12":29.8,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-swr-nofis-18":29.4,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-swr-nofis-3":32.6,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-wdspec-1":6.5,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-wdspec-nofis-1":5.3,"test-android-em-14-x86_64/debug-isolated-process-geckoview-mochitest-plain":17.7,"test-android-em-14-x86_64/debug-isolated-process-geckoview-mochitest-plain-7":27.3,"test-android-em-14-x86_64/debug-isolated-process-geckoview-mochitest-plain-fis-hv-7":25.2,"test-android-em-14-x86_64/debug-isolated-process-geckoview-mochitest-plain-fis-hv-8":26.2,"test-android-em-14-x86_64/debug-isolated-process-geckoview-mochitest-plain-xorig":10.8,"test-android-em-14-x86_64/debug-isolated-process-geckoview-reftest-nofis":11.6,"test-android-em-14-x86_64/debug-isolated-process-geckoview-reftest-nofis-4":25.3,"test-android-em-14-x86_64/debug-isolated-process-geckoview-web-platform-tests-wdspec-1":5.5,"test-android-em-14-x86_64/debug-isolated-process-geckoview-web-platform-tests-wdspec-nofis-1":5.0,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain":8.1,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-fis-hv":9.3,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-fis-hv-6":12.3,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-nofis":8.9,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-nofis-5":25.8,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-xorig":9.1,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis-1":5.4,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis-13":30.4,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis-20":30.7,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis-32":30.7,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis-34":14.0,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis-35":16.3,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis-36":17.8,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis-37":31.3,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis-9":31.7,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-reftest-nofis":31.9,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-reftest-nofis-1":5.3,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-reftest-nofis-12":29.5,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-reftest-nofis-14":27.7,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-reftest-nofis-6":27.7,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-reftest-nofis-7":27.2,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-reftest-nofis-8":28.6,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-reftest-nofis-9":27.2,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-wdspec-1":6.1,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-wdspec-nofis-1":5.3,"test-android-em-14-x86_64/opt-geckoview-xpcshell":31.0,"test-android-em-14-x86_64/opt-geckoview-xpcshell-nofis-1":23.6,"test-android-em-14-x86_64/opt-geckoview-xpcshell-nofis-2":25.1,"test-linux2204-64-wayland-shippable/opt-web-platform-tests-wdspec-headless-3":11.4,"test-linux2204-64-wayland/debug-mochitest-plain":2.1,"test-linux2204-64-wayland/debug-mochitest-plain-12":14.8,"test-linux2204-64-wayland/debug-web-platform-tests-wdspec-headless-3":17.5,"test-linux2204-64-wayland/opt-mochitest-plain":1.3,"test-linux2204-64-wayland/opt-mochitest-plain-4":23.8,"test-linux2204-64-wayland/opt-web-platform-tests-wdspec-headless-1":24.4,"test-linux2204-64-wayland/opt-web-platform-tests-wdspec-headless-2":41.1,"test-linux2204-64-wayland/opt-web-platform-tests-wdspec-headless-3":12.1,"test-linux2404-64-asan/opt-marionette-integration":4.5,"test-linux2404-64-asan/opt-mochitest-browser-chrome-swr-35":32.7,"test-linux2404-64-asan/opt-mochitest-browser-chrome-swr-36":36.7,"test-linux2404-64-asan/opt-mochitest-chrome-1proc":18.1,"test-linux2404-64-asan/opt-web-platform-tests-42":28.6,"test-linux2404-64-asan/opt-web-platform-tests-43":29.5,"test-linux2404-64-asan/opt-web-platform-tests-8":29.0,"test-linux2404-64-asan/opt-web-platform-tests-nofis-21":21.4,"test-linux2404-64-asan/opt-web-platform-tests-nofis-3":20.7,"test-linux2404-64-asan/opt-web-platform-tests-nofis-30":22.8,"test-linux2404-64-asan/opt-web-platform-tests-nofis-40":26.2,"test-linux2404-64-asan/opt-web-platform-tests-nofis-41":26.6,"test-linux2404-64-asan/opt-web-platform-tests-nofis-9":22.8,"test-linux2404-64-asan/opt-web-platform-tests-reftest":15.9,"test-linux2404-64-shippable/opt-mochitest-plain-headless":1.3,"test-linux2404-64-tsan/opt-jsreftest-3":26.8,"test-linux2404-64-tsan/opt-marionette-integration":4.2,"test-linux2404-64-tsan/opt-marionette-integration-4":37.9,"test-linux2404-64-tsan/opt-mochitest-browser-a11y":13.0,"test-linux2404-64-tsan/opt-mochitest-browser-chrome-swr":4.7,"test-linux2404-64-tsan/opt-mochitest-browser-chrome-swr-57":23.7,"test-linux2404-64-tsan/opt-mochitest-browser-chrome-swr-58":27.4,"test-linux2404-64-tsan/opt-mochitest-chrome-1proc":25.3,"test-linux2404-64-tsan/opt-test-verify":2.6,"test-linux2404-64-tsan/opt-test-verify-1":64.5,"test-linux2404-64-tsan/opt-test-verify-2":64.8,"test-linux2404-64-tsan/opt-test-verify-3":41.7,"test-linux2404-64-tsan/opt-web-platform-tests-22":23.2,"test-linux2404-64-tsan/opt-web-platform-tests-36":22.8,"test-linux2404-64-tsan/opt-web-platform-tests-56":29.2,"test-linux2404-64-tsan/opt-web-platform-tests-57":33.1,"test-linux2404-64-tsan/opt-web-platform-tests-58":35.6,"test-linux2404-64-tsan/opt-web-platform-tests-crashtest":8.6,"test-linux2404-64-tsan/opt-web-platform-tests-reftest":25.3,"test-linux2404-64-tsan/opt-web-platform-tests-reftest-1":38.1,"test-linux2404-64-tsan/opt-web-platform-tests-wdspec-18":28.2,"test-linux2404-64-tsan/opt-xpcshell":15.2,"test-linux2404-64/debug-mochitest-browser-chrome-standalone":14.8,"test-linux2404-64/debug-mochitest-browser-chrome-standalone-73":25.1,"test-linux2404-64/debug-mochitest-browser-chrome-standalone-74":29.1,"test-linux2404-64/debug-mochitest-browser-chrome-standalone-75":32.5,"test-linux2404-64/debug-mochitest-browser-chrome-standalone-76":33.9,"test-linux2404-64/debug-mochitest-browser-chrome-standalone-77":36.9,"test-linux2404-64/debug-mochitest-browser-chrome-standalone-78":38.0,"test-linux2404-64/debug-mochitest-browser-chrome-standalone-79":59.1,"test-linux2404-64/debug-mochitest-browser-chrome-standalone-80":59.3,"test-linux2404-64/debug-mochitest-browser-chrome-standalone-81":58.1,"test-linux2404-64/debug-mochitest-browser-chrome-swr":6.7,"test-linux2404-64/debug-mochitest-browser-chrome-swr-32":26.7,"test-linux2404-64/debug-mochitest-browser-chrome-swr-33":34.8,"test-linux2404-64/debug-mochitest-chrome-1proc":13.3,"test-linux2404-64/debug-mochitest-chrome-swr-1proc":13.4,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-18":26.2,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-19":26.7,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-20":28.0,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-21":28.6,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-22":29.8,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-23":30.2,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-24":31.0,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-25":32.9,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-26":33.7,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-27":35.1,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-28":36.4,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-29":38.5,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-30":38.0,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-31":48.7,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone-32":50.0,"test-linux2404-64/debug-mochitest-media-swr":20.5,"test-linux2404-64/debug-mochitest-plain":9.1,"test-linux2404-64/debug-mochitest-plain-headless":3.0,"test-linux2404-64/debug-mochitest-plain-http2":5.9,"test-linux2404-64/debug-mochitest-plain-http3":6.1,"test-linux2404-64/debug-mochitest-plain-nofis":2.8,"test-linux2404-64/debug-mochitest-plain-standalone":2.5,"test-linux2404-64/debug-mochitest-plain-standalone-34":25.2,"test-linux2404-64/debug-mochitest-plain-standalone-35":25.6,"test-linux2404-64/debug-mochitest-plain-standalone-36":26.1,"test-linux2404-64/debug-mochitest-plain-standalone-37":26.9,"test-linux2404-64/debug-mochitest-plain-standalone-38":26.9,"test-linux2404-64/debug-mochitest-plain-standalone-39":29.0,"test-linux2404-64/debug-mochitest-plain-standalone-40":30.9,"test-linux2404-64/debug-mochitest-plain-standalone-41":30.9,"test-linux2404-64/debug-mochitest-plain-standalone-42":33.0,"test-linux2404-64/debug-mochitest-plain-standalone-43":42.2,"test-linux2404-64/debug-mochitest-plain-standalone-44":49.5,"test-linux2404-64/debug-mochitest-plain-xorig":8.5,"test-linux2404-64/debug-reftest-s-1":24.4,"test-linux2404-64/debug-reftest-s-2":24.1,"test-linux2404-64/debug-reftest-s-3":23.8,"test-linux2404-64/debug-reftest-swr-1":24.3,"test-linux2404-64/debug-reftest-swr-2":24.0,"test-linux2404-64/debug-reftest-swr-3":23.3,"test-linux2404-64/debug-test-verify-1":65.4,"test-linux2404-64/debug-test-verify-2":63.5,"test-linux2404-64/debug-test-verify-3":35.7,"test-linux2404-64/debug-web-platform-tests-nofis-1":5.3,"test-linux2404-64/debug-web-platform-tests-nofis-10":20.8,"test-linux2404-64/debug-web-platform-tests-nofis-11":18.6,"test-linux2404-64/debug-web-platform-tests-nofis-14":19.7,"test-linux2404-64/debug-web-platform-tests-nofis-3":19.0,"test-linux2404-64/debug-web-platform-tests-nofis-33":23.4,"test-linux2404-64/debug-web-platform-tests-nofis-34":25.2,"test-linux2404-64/debug-web-platform-tests-reftest":12.8,"test-linux2404-64/debug-web-platform-tests-reftest-s":9.4,"test-linux2404-64/debug-web-platform-tests-reftest-swr":10.4,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-1":11.6,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-10":17.8,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-2":29.6,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-3":24.1,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-5":12.4,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-6":48.9,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-7":27.9,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-9":27.7,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-long-1":31.0,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-long-3":66.0,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-long-4":80.1,"test-linux2404-64/opt-mochitest-browser-chrome-no-nv":4.8,"test-linux2404-64/opt-mochitest-browser-chrome-standalone":7.3,"test-linux2404-64/opt-mochitest-browser-chrome-standalone-13":27.6,"test-linux2404-64/opt-mochitest-browser-chrome-swr":4.0,"test-linux2404-64/opt-mochitest-browser-chrome-swr-a11y-checks":4.8,"test-linux2404-64/opt-mochitest-devtools-chrome":17.9,"test-linux2404-64/opt-mochitest-devtools-chrome-a11y-checks":19.3,"test-linux2404-64/opt-mochitest-media-spi":15.8,"test-linux2404-64/opt-mochitest-plain":15.4,"test-linux2404-64/opt-mochitest-plain-standalone":1.8,"test-linux2404-64/opt-mochitest-plain-xorig":16.8,"test-linux2404-64/opt-reftest":7.3,"test-linux2404-64/opt-reftest-nogpu":7.6,"test-linux2404-64/opt-reftest-swr-1":7.2,"test-linux2404-64/opt-reftest-swr-2":10.2,"test-linux2404-64/opt-reftest-swr-3":6.5,"test-linux2404-64/opt-reftest-swr-5":12.6,"test-linux2404-64/opt-test-verify-1":36.9,"test-linux2404-64/opt-test-verify-2":53.0,"test-linux2404-64/opt-test-verify-3":45.6,"test-linux2404-64/opt-web-platform-tests-1":20.9,"test-linux2404-64/opt-web-platform-tests-reftest":6.9,"test-linux2404-64/opt-web-platform-tests-wdspec":2.6,"test-linux2404-64/opt-web-platform-tests-wdspec-headless":3.3,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-1":10.4,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-2":24.9,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-3":17.1,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-5":9.7,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-6":32.6,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-8":7.8,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-9":21.4,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-long-1":20.1,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-long-3":34.6,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-long-4":74.3,"test-macosx1015-64-qr/debug-jittest-1proc-1":8.0,"test-macosx1015-64-qr/debug-xpcshell":34.2,"test-macosx1015-64-qr/debug-xpcshell-3":18.7,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-1":7.4,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-10":5.8,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-11":56.6,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-12":28.4,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-13":20.6,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-14":26.0,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-15":7.6,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-16":4.2,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-17":34.4,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-18":25.9,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-19":12.5,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-2":8.9,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-20":4.9,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-22":8.9,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-23":7.7,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-24":19.6,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-25":15.7,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-3":8.0,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-5":22.3,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-6":21.1,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-7":43.9,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-8":5.8,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-long-3":43.8,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-long-4":45.4,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-long-5":74.3,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-1":6.5,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-10":5.0,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-11":42.3,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-12":7.6,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-13":15.5,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-14":17.5,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-15":4.0,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-16":3.7,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-17":31.4,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-18":24.8,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-19":6.1,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-2":7.4,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-20":3.9,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-21":8.6,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-22":7.3,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-23":6.4,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-24":18.3,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-25":14.3,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-3":5.9,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-4":11.2,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-5":19.6,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-6":12.3,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-7":27.5,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-8":3.8,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-long-1":52.3,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-long-2":39.0,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-long-4":22.7,"test-macosx1500-aarch64-vms/debug-jittest-1proc-1":5.2,"test-macosx1500-aarch64-vms/debug-jittest-1proc-3":14.8,"test-macosx1500-aarch64-vms/debug-xpcshell-1":19.1,"test-macosx1500-aarch64-vms/debug-xpcshell-2":18.9,"test-macosx1500-aarch64-vms/opt-mochitest-chrome-1proc":16.2,"test-macosx1500-aarch64-vms/opt-mochitest-plain":9.3,"test-macosx1500-aarch64/debug-jittest-1proc-1":3.3,"test-macosx1500-aarch64/debug-jittest-1proc-3":6.5,"test-macosx1500-aarch64/debug-mochitest-chrome-1proc":16.3,"test-macosx1500-aarch64/debug-mochitest-media-2":15.0,"test-macosx1500-aarch64/debug-mochitest-plain":6.7,"test-macosx1500-aarch64/debug-mochitest-plain-xorig":6.6,"test-macosx1500-aarch64/debug-mochitest-plain-xorig-5":17.9,"test-macosx1500-aarch64/debug-test-verify-1":17.2,"test-macosx1500-aarch64/debug-test-verify-2":77.7,"test-macosx1500-aarch64/debug-web-platform-tests-reftest":9.7,"test-macosx1500-aarch64/opt-mochitest-browser-chrome":1.4,"test-macosx1500-aarch64/opt-mochitest-browser-chrome-no-nv":7.5,"test-macosx1500-aarch64/opt-mochitest-chrome-no-nv-1":15.5,"test-macosx1500-aarch64/opt-mochitest-plain":3.9,"test-macosx1500-aarch64/opt-mochitest-plain-xorig":17.5,"test-macosx1500-aarch64/opt-reftest":31.4,"test-macosx1500-aarch64/opt-test-verify":0.8,"test-macosx1500-aarch64/opt-test-verify-1":68.8,"test-macosx1500-aarch64/opt-test-verify-2":66.3,"test-macosx1500-aarch64/opt-test-verify-3":24.2,"test-macosx1500-aarch64/opt-web-platform-tests":27.8,"test-macosx1500-aarch64/opt-web-platform-tests-1":19.7,"test-macosx1500-aarch64/opt-web-platform-tests-reftest":5.8,"test-macosx1500-aarch64/opt-web-platform-tests-reftest-1":20.4,"test-macosx1500-aarch64/opt-web-platform-tests-reftest-2":20.3,"test-macosx1500-aarch64/opt-web-platform-tests-reftest-3":20.8,"test-macosx1500-aarch64/opt-xpcshell-1":2.1,"test-macosx1500-aarch64/opt-xpcshell-2":10.9,"test-windows10-64-2009-qr/debug-mochitest-chrome-1proc":16.8,"test-windows10-64-2009-qr/debug-mochitest-plain":3.4,"test-windows10-64-2009-qr/opt-mochitest-plain":1.7,"test-windows11-32-25h2-shippable/opt-mochitest-browser-chrome-7":26.8,"test-windows11-32-25h2-shippable/opt-reftest-wr-dc0-3":16.4,"test-windows11-32-25h2/debug-mochitest-browser-chrome":5.1,"test-windows11-32-25h2/debug-mochitest-chrome-1proc":23.1,"test-windows11-32-25h2/debug-reftest":7.7,"test-windows11-32-25h2/debug-reftest-4":18.9,"test-windows11-32-25h2/debug-test-verify":5.4,"test-windows11-32-25h2/debug-test-verify-1":59.4,"test-windows11-32-25h2/debug-test-verify-2":49.1,"test-windows11-32-25h2/debug-test-verify-3":22.3,"test-windows11-32-25h2/debug-web-platform-tests-1":5.5,"test-windows11-32-25h2/opt-mochitest-browser-chrome":3.2,"test-windows11-32-25h2/opt-mochitest-chrome-1proc":18.6,"test-windows11-32-25h2/opt-mochitest-chrome-1proc-3":24.4,"test-windows11-32-25h2/opt-reftest":7.9,"test-windows11-32-25h2/opt-reftest-wr-dc0":6.4,"test-windows11-32-25h2/opt-reftest-wr-dc1-p":7.9,"test-windows11-32-25h2/opt-reftest-wr-dc2-o":6.5,"test-windows11-32-25h2/opt-reftest-wr-dc3-c":6.7,"test-windows11-32-25h2/opt-test-verify":3.8,"test-windows11-32-25h2/opt-web-platform-tests":32.9,"test-windows11-32-25h2/opt-web-platform-tests-11":24.6,"test-windows11-32-25h2/opt-web-platform-tests-12":24.1,"test-windows11-32-25h2/opt-web-platform-tests-13":24.2,"test-windows11-32-25h2/opt-web-platform-tests-4":24.1,"test-windows11-32-25h2/opt-web-platform-tests-6":24.1,"test-windows11-32-25h2/opt-web-platform-tests-7":24.9,"test-windows11-32-25h2/opt-web-platform-tests-8":23.7,"test-windows11-64-24h2/debug-jsreftest-2":16.8,"test-windows11-64-24h2/opt-reftest-wr-dc0":3.6,"test-windows11-64-24h2/opt-reftest-wr-dc1-p":6.2,"test-windows11-64-24h2/opt-reftest-wr-dc2-o":6.5,"test-windows11-64-25h2-asan/opt-mochitest-browser-chrome-44":28.5,"test-windows11-64-25h2-asan/opt-mochitest-browser-chrome-45":41.0,"test-windows11-64-25h2-asan/opt-mochitest-chrome-1proc-5":26.6,"test-windows11-64-25h2-devedition/opt-mochitest-browser-chrome-9":25.7,"test-windows11-64-25h2-shippable/opt-mochitest-media-spi-1":20.9,"test-windows11-64-25h2-shippable/opt-mochitest-media-spi-2":21.4,"test-windows11-64-25h2-shippable/opt-web-platform-tests-reftest-2":30.7,"test-windows11-64-25h2-shippable/opt-web-platform-tests-wdspec-1":24.8,"test-windows11-64-25h2/debug-mochitest-browser-chrome":4.7,"test-windows11-64-25h2/debug-mochitest-browser-chrome-msix":3.4,"test-windows11-64-25h2/debug-mochitest-browser-chrome-standalone":8.1,"test-windows11-64-25h2/debug-mochitest-browser-chrome-standalone-21":16.9,"test-windows11-64-25h2/debug-mochitest-browser-chrome-standalone-61":38.8,"test-windows11-64-25h2/debug-mochitest-browser-chrome-standalone-62":29.0,"test-windows11-64-25h2/debug-mochitest-browser-chrome-standalone-64":41.5,"test-windows11-64-25h2/debug-mochitest-chrome-1proc":15.9,"test-windows11-64-25h2/debug-mochitest-devtools-chrome-standalone-22":25.4,"test-windows11-64-25h2/debug-mochitest-devtools-chrome-standalone-24":26.9,"test-windows11-64-25h2/debug-mochitest-devtools-chrome-standalone-25":26.1,"test-windows11-64-25h2/debug-mochitest-devtools-chrome-standalone-26":37.1,"test-windows11-64-25h2/debug-mochitest-devtools-chrome-standalone-27":33.8,"test-windows11-64-25h2/debug-mochitest-media-msix-2":20.8,"test-windows11-64-25h2/debug-mochitest-plain":3.9,"test-windows11-64-25h2/debug-mochitest-plain-standalone":1.9,"test-windows11-64-25h2/debug-mochitest-plain-standalone-1":17.9,"test-windows11-64-25h2/debug-mochitest-plain-standalone-31":24.3,"test-windows11-64-25h2/debug-test-verify":1.8,"test-windows11-64-25h2/debug-test-verify-1":18.6,"test-windows11-64-25h2/debug-test-verify-2":58.2,"test-windows11-64-25h2/debug-test-verify-3":22.1,"test-windows11-64-25h2/debug-web-platform-tests-1":5.1,"test-windows11-64-25h2/debug-web-platform-tests-reftest":12.0,"test-windows11-64-25h2/debug-web-platform-tests-reftest-1":6.7,"test-windows11-64-25h2/debug-web-platform-tests-reftest-2":28.7,"test-windows11-64-25h2/debug-web-platform-tests-reftest-3":29.0,"test-windows11-64-25h2/debug-web-platform-tests-reftest-4":29.4,"test-windows11-64-25h2/debug-web-platform-tests-reftest-swr":11.7,"test-windows11-64-25h2/debug-web-platform-tests-reftest-swr-1":6.5,"test-windows11-64-25h2/debug-web-platform-tests-reftest-swr-2":29.1,"test-windows11-64-25h2/debug-web-platform-tests-reftest-swr-3":28.5,"test-windows11-64-25h2/debug-web-platform-tests-reftest-swr-4":28.6,"test-windows11-64-25h2/debug-web-platform-tests-wdspec-1":3.9,"test-windows11-64-25h2/debug-web-platform-tests-wdspec-2":24.7,"test-windows11-64-25h2/debug-web-platform-tests-wdspec-3":25.1,"test-windows11-64-25h2/debug-web-platform-tests-wdspec-4":25.1,"test-windows11-64-25h2/debug-web-platform-tests-wdspec-headless-1":3.7,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-1":13.3,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-10":7.4,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-11":24.1,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-13":7.2,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-14":14.8,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-15":20.3,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-16":7.7,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-17":9.1,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-18":18.7,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-19":5.6,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-2":7.7,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-20":12.5,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-22":12.2,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-3":7.6,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-4":45.5,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-6":20.9,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-7":18.4,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-8":7.5,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-9":7.5,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-long-1":52.5,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-long-2":77.7,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-long-5":12.6,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-long-6":16.9,"test-windows11-64-25h2/opt-mochitest-browser-chrome":3.1,"test-windows11-64-25h2/opt-mochitest-browser-chrome-msix":3.1,"test-windows11-64-25h2/opt-mochitest-browser-chrome-msix-13":25.6,"test-windows11-64-25h2/opt-mochitest-browser-chrome-no-nv":3.8,"test-windows11-64-25h2/opt-mochitest-browser-chrome-no-nv-10":18.1,"test-windows11-64-25h2/opt-mochitest-browser-chrome-standalone":4.6,"test-windows11-64-25h2/opt-mochitest-browser-chrome-uipc":1.5,"test-windows11-64-25h2/opt-mochitest-chrome-1proc":11.2,"test-windows11-64-25h2/opt-mochitest-chrome-1proc-3":25.0,"test-windows11-64-25h2/opt-mochitest-chrome-no-nv-3":30.3,"test-windows11-64-25h2/opt-mochitest-devtools-chrome":17.3,"test-windows11-64-25h2/opt-mochitest-devtools-chrome-3":21.9,"test-windows11-64-25h2/opt-mochitest-media":27.3,"test-windows11-64-25h2/opt-mochitest-media-1":20.7,"test-windows11-64-25h2/opt-mochitest-media-msix":28.2,"test-windows11-64-25h2/opt-mochitest-media-msix-1":22.0,"test-windows11-64-25h2/opt-mochitest-media-nogpu":26.1,"test-windows11-64-25h2/opt-mochitest-media-nogpu-1":16.6,"test-windows11-64-25h2/opt-mochitest-media-spi":23.7,"test-windows11-64-25h2/opt-mochitest-media-spi-1":16.6,"test-windows11-64-25h2/opt-mochitest-plain":3.2,"test-windows11-64-25h2/opt-mochitest-plain-standalone":1.9,"test-windows11-64-25h2/opt-test-verify":1.6,"test-windows11-64-25h2/opt-test-verify-1":7.2,"test-windows11-64-25h2/opt-test-verify-2":37.7,"test-windows11-64-25h2/opt-test-verify-3":11.1,"test-windows11-64-25h2/opt-web-platform-tests":28.4,"test-windows11-64-25h2/opt-web-platform-tests-10":25.2,"test-windows11-64-25h2/opt-web-platform-tests-11":25.3,"test-windows11-64-25h2/opt-web-platform-tests-13":25.2,"test-windows11-64-25h2/opt-web-platform-tests-2":22.6,"test-windows11-64-25h2/opt-web-platform-tests-3":25.2,"test-windows11-64-25h2/opt-web-platform-tests-4":25.5,"test-windows11-64-25h2/opt-web-platform-tests-5":24.5,"test-windows11-64-25h2/opt-web-platform-tests-6":25.2,"test-windows11-64-25h2/opt-web-platform-tests-7":25.6,"test-windows11-64-25h2/opt-web-platform-tests-8":25.4,"test-windows11-64-25h2/opt-web-platform-tests-reftest-1":4.2,"test-windows11-64-25h2/opt-web-platform-tests-reftest-2":28.3,"test-windows11-64-25h2/opt-web-platform-tests-reftest-3":25.5,"test-windows11-64-25h2/opt-web-platform-tests-wdspec-3":20.6,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-1":23.3,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-11":18.1,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-12":26.6,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-13":16.1,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-14":28.8,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-2":24.2,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-4":31.4,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-6":30.5,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-7":15.7,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-8":24.1,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-9":15.4,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-1":26.4,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-10":11.5,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-11":6.5,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-12":7.8,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-13":15.7,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-14":14.4,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-15":13.9,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-17":12.6,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-3":7.9,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-4":7.4,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-5":5.7,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-6":35.8,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-7":5.6,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-8":13.7,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-long-2":69.3,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-long-4":33.0,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-long-5":7.4,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-long-6":8.8,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-long-1":48.9,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-long-2":26.4},"family":{"Action: Add new jobs":1.2,"Action: Cancel All":1.0,"Action: Retrigger":0.9,"Gecko Decision Task":1.9,"beetmover-integration-android-aarch64/opt":0.7,"beetmover-integration-linux64/opt":0.4,"beetmover-integration-macosx64/opt":0.4,"beetmover-integration-win32/opt":0.5,"beetmover-integration-win64/opt":0.5,"build-android-aarch64-fenix/debug":42.0,"build-android-aarch64-lite/opt":21.0,"build-android-aarch64-non-unified/opt":51.6,"build-android-aarch64-shippable-lite/opt":25.2,"build-android-aarch64-shippable-lite/opt-upload-symbols":5.6,"build-android-aarch64-shippable/opt":24.4,"build-android-aarch64-shippable/opt-upload-symbols":4.7,"build-android-aarch64/debug":39.8,"build-android-aarch64/opt":15.8,"build-android-arm-lite/opt":25.4,"build-android-arm-shippable-lite/opt":23.9,"build-android-arm-shippable-lite/opt-upload-symbols":4.0,"build-android-arm-shippable/opt":24.3,"build-android-arm-shippable/opt-upload-symbols":4.8,"build-android-arm/debug":40.9,"build-android-arm/opt":15.1,"build-android-x86_64-asan-fuzzing/opt":25.2,"build-android-x86_64-fuzzing/debug":42.2,"build-android-x86_64-lite/opt":18.1,"build-android-x86_64-non-unified/opt":56.2,"build-android-x86_64-shippable-lite/opt":27.0,"build-android-x86_64-shippable-lite/opt-upload-symbols":6.7,"build-android-x86_64-shippable/opt":27.1,"build-android-x86_64-shippable/opt-upload-symbols":4.4,"build-android-x86_64/debug":17.0,"build-android-x86_64/debug-isolated-process":19.4,"build-android-x86_64/debug-isolated-process-upload-symbols":7.5,"build-android-x86_64/opt":15.9,"build-apk-fenix-android-test-beta":12.4,"build-apk-fenix-android-test-debug":12.0,"build-apk-fenix-beta-firebase":13.4,"build-apk-fenix-debug":10.4,"build-apk-fenix-nightly":20.4,"build-apk-fenix-nightly-firebase":13.8,"build-apk-fenix-nightly-simulation":15.1,"build-apk-focus-android-test-beta":11.4,"build-apk-focus-android-test-debug":11.0,"build-apk-focus-android-test-nightly":11.5,"build-apk-focus-beta-firebase":9.7,"build-apk-focus-debug":8.5,"build-apk-focus-nightly":11.3,"build-apk-focus-nightly-firebase":9.3,"build-apk-klar-debug":8.4,"build-bundle-fenix-debug":10.5,"build-bundle-fenix-nightly":16.2,"build-bundle-focus-debug":8.7,"build-bundle-focus-nightly":11.7,"build-bundle-klar-debug":8.7,"build-components-browser-domains":13.0,"build-components-browser-engine-gecko":16.5,"build-components-browser-engine-system":14.7,"build-components-browser-errorpages":13.3,"build-components-browser-icons":14.9,"build-components-browser-menu":15.1,"build-components-browser-menu2":13.9,"build-components-browser-session-storage":15.5,"build-components-browser-state":14.6,"build-components-browser-storage-sync":13.9,"build-components-browser-tabstray":14.6,"build-components-browser-thumbnails":14.5,"build-components-browser-toolbar":15.4,"build-components-compose-awesomebar":16.6,"build-components-compose-base":14.2,"build-components-compose-browser-toolbar":15.9,"build-components-compose-cfr":14.6,"build-components-compose-engine":14.1,"build-components-compose-tabstray":15.2,"build-components-concept-accelerometer":11.3,"build-components-concept-ai-controls":11.6,"build-components-concept-awesomebar":12.0,"build-components-concept-base":11.6,"build-components-concept-bookmarks-file":11.4,"build-components-concept-bookmarks-parser":11.4,"build-components-concept-engine":14.0,"build-components-concept-fetch":12.0,"build-components-concept-integrity":11.2,"build-components-concept-llm":11.3,"build-components-concept-menu":13.0,"build-components-concept-passwords-file":11.2,"build-components-concept-passwords-parser":13.0,"build-components-concept-push":12.1,"build-components-concept-storage":13.2,"build-components-concept-storage-bookmarks":11.5,"build-components-concept-sync":12.0,"build-components-concept-tabstray":13.2,"build-components-concept-toolbar":13.3,"build-components-feature-accounts":16.0,"build-components-feature-accounts-push":14.4,"build-components-feature-addons":16.1,"build-components-feature-app-links":15.4,"build-components-feature-autofill":14.1,"build-components-feature-awesomebar":16.8,"build-components-feature-containers":14.3,"build-components-feature-contextmenu":16.1,"build-components-feature-customtabs":17.1,"build-components-feature-downloads":16.1,"build-components-feature-example":12.0,"build-components-feature-findinpage":14.3,"build-components-feature-fxsuggest":16.5,"build-components-feature-importer":13.1,"build-components-feature-intent":16.2,"build-components-feature-ipprotection":15.9,"build-components-feature-logins":16.6,"build-components-feature-media":15.2,"build-components-feature-password-importer":13.7,"build-components-feature-privatemode":14.4,"build-components-feature-prompts":17.5,"build-components-feature-protection-dashboard":14.4,"build-components-feature-push":12.5,"build-components-feature-pwa":16.9,"build-components-feature-qr":14.1,"build-components-feature-readerview":14.9,"build-components-feature-recentlyclosed":14.8,"build-components-feature-screendetection":12.2,"build-components-feature-search":16.6,"build-components-feature-serviceworker":15.9,"build-components-feature-session":14.7,"build-components-feature-share":13.0,"build-components-feature-sitepermissions":16.9,"build-components-feature-summarize":14.4,"build-components-feature-syncedtabs":15.0,"build-components-feature-tab-collections":15.9,"build-components-feature-tabs":16.1,"build-components-feature-toolbar":14.9,"build-components-feature-top-sites":13.9,"build-components-feature-webauthn":13.7,"build-components-feature-webcompat":13.7,"build-components-feature-webcompat-reporter":14.3,"build-components-feature-webnotifications":16.1,"build-components-lib-accelerometer-sensormanager":12.1,"build-components-lib-ai-controls":12.1,"build-components-lib-auth":12.3,"build-components-lib-bookmark-parser-jsoup":11.8,"build-components-lib-bookmarks-file":11.9,"build-components-lib-crash":15.2,"build-components-lib-crash-sentry":14.1,"build-components-lib-dataprotect":12.4,"build-components-lib-fetch-httpurlconnection":11.9,"build-components-lib-fetch-okhttp":11.9,"build-components-lib-integrity-googleplay":11.9,"build-components-lib-jexl":11.6,"build-components-lib-llm-gemininano":12.0,"build-components-lib-llm-mlpa":13.1,"build-components-lib-password-parser-csv":13.3,"build-components-lib-passwords-file":13.3,"build-components-lib-publicsuffixlist":11.8,"build-components-lib-push-firebase":12.3,"build-components-lib-shake":11.6,"build-components-lib-state":13.7,"build-components-samples-acorn-components":14.6,"build-components-samples-compose-browser":18.6,"build-components-samples-crash":15.1,"build-components-samples-dataprotect":13.5,"build-components-samples-firefox-accounts":14.9,"build-components-samples-firefox-relay":15.3,"build-components-samples-glean":15.7,"build-components-samples-glean-library":11.6,"build-components-samples-sync":15.3,"build-components-samples-sync-logins":15.1,"build-components-samples-toolbar":16.8,"build-components-service-digitalassetlinks":13.3,"build-components-service-firefox-accounts":13.7,"build-components-service-firefox-relay":14.2,"build-components-service-glean":13.2,"build-components-service-location":13.4,"build-components-service-mars":14.0,"build-components-service-merino-manifest":13.3,"build-components-service-merino-weather":12.2,"build-components-service-nimbus":14.4,"build-components-service-pocket":13.7,"build-components-service-sync":12.0,"build-components-service-sync-autofill":13.3,"build-components-service-sync-logins":13.6,"build-components-support-android-test":11.7,"build-components-support-appservices":12.4,"build-components-support-base":12.4,"build-components-support-images":12.5,"build-components-support-ktx":14.6,"build-components-support-license":14.0,"build-components-support-locale":14.3,"build-components-support-remotesettings":13.3,"build-components-support-test":12.8,"build-components-support-test-appservices":11.4,"build-components-support-test-fakes":13.6,"build-components-support-test-libstate":13.0,"build-components-support-utils":13.5,"build-components-support-webextensions":14.5,"build-components-tooling-detekt":10.8,"build-components-tooling-fetch-tests":11.5,"build-components-tooling-lint":13.5,"build-components-ui-animation":12.4,"build-components-ui-autocomplete":13.2,"build-components-ui-colors":12.3,"build-components-ui-fonts":11.1,"build-components-ui-icons":11.6,"build-components-ui-richtext":13.8,"build-components-ui-tabcounter":14.3,"build-components-ui-widgets":14.6,"build-extensions-browser":4.4,"build-fat-aar-android-geckoview-fat-aar-shippable-lite/opt":7.6,"build-fat-aar-android-geckoview-fat-aar-shippable/opt":8.4,"build-fat-aar-android-geckoview-fat-aar/opt":6.2,"build-ios-non-unified/plain":32.6,"build-ios-sim/debug":27.8,"build-ios-sim/opt":26.4,"build-ios/debug":26.9,"build-ios/opt":24.2,"build-linux64-aarch64-devedition/opt":20.1,"build-linux64-aarch64-shippable/opt":20.1,"build-linux64-aarch64-shippable/opt-upload-symbols":5.9,"build-linux64-aarch64/debug":40.4,"build-linux64-aarch64/opt":17.8,"build-linux64-add-on-devel/opt":38.1,"build-linux64-asan-fuzzing-afl/opt":42.2,"build-linux64-asan-fuzzing-ccov/opt":77.5,"build-linux64-asan-fuzzing-nyx-ccov/opt":35.0,"build-linux64-asan-fuzzing-nyx/opt":53.7,"build-linux64-asan-fuzzing/noopt":33.9,"build-linux64-asan-fuzzing/opt":36.9,"build-linux64-asan/debug":44.5,"build-linux64-asan/opt":13.7,"build-linux64-base-toolchains-clang/debug":32.7,"build-linux64-base-toolchains-clang/opt":31.7,"build-linux64-base-toolchains/debug":49.5,"build-linux64-base-toolchains/opt":48.8,"build-linux64-ccov/debug":65.0,"build-linux64-ccov/opt":58.9,"build-linux64-devedition/opt":49.3,"build-linux64-fuzzing-afl-ccov/opt":57.5,"build-linux64-fuzzing-afl/debug":45.1,"build-linux64-fuzzing-ccov/opt":57.5,"build-linux64-fuzzing-noopt/debug":33.8,"build-linux64-fuzzing/debug":37.7,"build-linux64-gcc/opt":43.7,"build-linux64-nightlyasrelease/opt":47.6,"build-linux64-non-unified/debug":47.5,"build-linux64-non-unified/plain":50.8,"build-linux64-noopt/debug":34.5,"build-linux64-plain/debug":33.5,"build-linux64-plain/opt":29.8,"build-linux64-reproduced/opt":48.3,"build-linux64-rusttests/debug":6.4,"build-linux64-rusttests/opt":5.6,"build-linux64-shippable/opt":48.8,"build-linux64-shippable/opt-upload-symbols":6.8,"build-linux64-tsan-fuzzing/opt":32.5,"build-linux64-tsan/opt":12.8,"build-linux64-x11/opt":29.0,"build-linux64/debug":13.2,"build-linux64/debug-upload-symbols":7.3,"build-linux64/opt":12.4,"build-mac-signing-macosx64-aarch64/debug":1.1,"build-mac-signing-macosx64-aarch64/opt":1.1,"build-mac-signing-macosx64/debug":1.2,"build-mac-signing-macosx64/opt":1.5,"build-macosx64-aarch64-add-on-devel/opt":40.5,"build-macosx64-aarch64-asan-fuzzing/opt":36.4,"build-macosx64-aarch64-devedition/opt":58.7,"build-macosx64-aarch64-fuzzing/debug":41.8,"build-macosx64-aarch64-nightlyasrelease/opt":59.5,"build-macosx64-aarch64-noopt/debug":34.6,"build-macosx64-aarch64-shippable/opt":59.4,"build-macosx64-aarch64/debug":16.8,"build-macosx64-aarch64/debug-upload-symbols":11.2,"build-macosx64-aarch64/opt":16.4,"build-macosx64-add-on-devel/opt":8.7,"build-macosx64-asan-fuzzing/opt":33.6,"build-macosx64-devedition/opt":12.7,"build-macosx64-fuzzing/debug":40.9,"build-macosx64-nightlyasrelease/opt":58.3,"build-macosx64-non-unified/plain":31.9,"build-macosx64-noopt/debug":33.4,"build-macosx64-plain/debug":97.8,"build-macosx64-plain/opt":82.7,"build-macosx64-rusttests/debug":17.6,"build-macosx64-shippable/opt":12.5,"build-macosx64-x64-add-on-devel/opt":39.4,"build-macosx64-x64-devedition/opt":60.3,"build-macosx64-x64-shippable/opt":59.8,"build-macosx64/debug":17.1,"build-macosx64/debug-upload-symbols":10.9,"build-macosx64/opt":16.9,"build-samples-browser-gecko":19.4,"build-samples-browser-system":14.1,"build-signing-android-aarch64-shippable/opt":0.4,"build-signing-linux64-aarch64/opt":5.8,"build-signing-linux64-devedition/opt":5.3,"build-signing-linux64/opt":6.3,"build-signing-win32-devedition/opt":1.1,"build-signing-win32-shippable/opt":1.1,"build-signing-win32/debug":1.4,"build-signing-win32/opt":1.1,"build-signing-win64-aarch64/opt":1.2,"build-signing-win64-devedition/opt":1.3,"build-signing-win64-shippable/opt":1.3,"build-signing-win64/debug":1.7,"build-signing-win64/opt":1.4,"build-win32-add-on-devel/opt":43.9,"build-win32-devedition/opt":55.7,"build-win32-fuzzing/debug":41.1,"build-win32-mingwclang/debug":28.1,"build-win32-mingwclang/opt":31.5,"build-win32-noopt/debug":40.0,"build-win32-shippable/opt":56.2,"build-win32/debug":14.4,"build-win32/debug-upload-symbols":6.7,"build-win32/opt":13.5,"build-win64-aarch64-devedition/opt":26.2,"build-win64-aarch64-devedition/opt-upload-symbols":6.6,"build-win64-aarch64-shippable/opt":19.2,"build-win64-aarch64/debug":39.9,"build-win64-aarch64/debug-upload-symbols":6.7,"build-win64-aarch64/opt":40.0,"build-win64-add-on-devel/opt":45.8,"build-win64-asan-fuzzing/opt":46.3,"build-win64-asan/debug":52.9,"build-win64-asan/opt":29.5,"build-win64-ccov/opt":70.8,"build-win64-devedition/opt":58.3,"build-win64-devedition/opt-upload-symbols":6.8,"build-win64-fuzzing-ccov/opt":74.4,"build-win64-fuzzing/debug":41.4,"build-win64-mingwclang/debug":32.5,"build-win64-mingwclang/opt":25.7,"build-win64-nightlyasrelease/opt":57.1,"build-win64-non-unified/plain":32.5,"build-win64-noopt/debug":38.8,"build-win64-plain/debug":54.4,"build-win64-plain/opt":48.6,"build-win64-rusttests/debug":27.9,"build-win64-shippable/opt":58.3,"build-win64-shippable/opt-upload-symbols":8.1,"build-win64/debug":15.1,"build-win64/debug-upload-symbols":6.5,"build-win64/opt":15.5,"docker-image-fetch-more":0.8,"fetch-binutils-2.31.1":3.2,"fetch-binutils-2.41":0.7,"fetch-clang":1.2,"fetch-clang-trunk":1.6,"fetch-gcc-10.5.0":1.4,"fetch-gcc-14.2.0":0.9,"fetch-gcc-8.5.0":4.9,"fetch-gcc-9.5.0":0.8,"fetch-linux64-chromedriver":0.2,"fetch-mac-arm-chromedriver":0.2,"fetch-mac64-chromedriver":0.2,"fetch-mozilla-smart-tab-topic":0.1,"fetch-mpfr-3.1.4":0.1,"fetch-win64-chromedriver":0.2,"fuzzing-grizzly-linux64-debug":16.7,"fuzzing-grizzly-linux64-opt":6.3,"fuzzing-grizzly-linux64-tsan":2.3,"fuzzing-simple":2.1,"generate-baseline-profile-firebase-fenix":16.6,"generate-baseline-profile-firebase-fenix-simulation":5.9,"generate-profile-android-aarch64-shippable/opt":29.1,"generate-profile-android-arm-shippable/opt":32.1,"generate-profile-android-x86_64-shippable/opt":21.2,"generate-profile-linux64-nightlyasrelease/opt":17.3,"generate-profile-linux64-shippable/opt":17.6,"generate-profile-macosx64-aarch64-nightlyasrelease/opt":16.6,"generate-profile-macosx64-aarch64-shippable/opt":16.3,"generate-profile-macosx64-shippable/opt":18.6,"generate-profile-win32-shippable/opt":21.1,"generate-profile-win64-aarch64-shippable/opt":39.7,"generate-profile-win64-nightlyasrelease/opt":23.6,"generate-profile-win64-shippable/opt":23.4,"hazard-linux64-haz/debug":131.4,"hazard-linux64-shell-haz/debug":22.1,"instrumented-build-android-aarch64-shippable/opt":30.0,"instrumented-build-android-arm-shippable/opt":31.1,"instrumented-build-android-x86_64-shippable/opt":30.1,"instrumented-build-apk-fenix":13.8,"instrumented-build-linux64-nightlyasrelease/opt":26.7,"instrumented-build-linux64-shippable/opt":11.1,"instrumented-build-macosx64-aarch64-nightlyasrelease/opt":32.9,"instrumented-build-macosx64-aarch64-shippable/opt":13.6,"instrumented-build-macosx64-shippable/opt":13.5,"instrumented-build-win32-shippable/opt":42.1,"instrumented-build-win64-aarch64-shippable/opt":41.5,"instrumented-build-win64-nightlyasrelease/opt":34.5,"instrumented-build-win64-shippable/opt":14.6,"l10n-linux64-aarch64/opt":8.3,"l10n-linux64/opt":8.8,"l10n-macosx64/opt":5.9,"l10n-win32/opt":12.9,"l10n-win64/opt":16.9,"linux-install-test-fedora-41-a64-rpm-devedition-ja":5.0,"openh264-plugin-linux64/opt":2.5,"openh264-plugin-macosx64-aarch64/opt":2.5,"openh264-plugin-win64/opt":2.2,"packages-deb10-arm64-gcc":40.5,"packages-deb8-32-gcc":10.8,"packages-deb8-gcc":14.8,"repackage-linux64-aarch64-devedition/opt":5.0,"repackage-linux64-aarch64-shippable/opt":3.0,"repackage-linux64-devedition/opt":4.0,"repackage-linux64-shippable/opt":4.3,"repackage-macosx64-aarch64/debug":5.5,"repackage-macosx64-aarch64/opt":4.7,"repackage-macosx64/opt":7.1,"repackage-msix-win64/debug":3.0,"repackage-msix-win64/opt":2.7,"repackage-signing-msix-win64/debug":0.4,"repackage-signing-msix-win64/opt":0.3,"repackage-win32-shippable/opt":3.6,"repackage-win64-aarch64-devedition/opt":5.2,"repackage-win64-aarch64-shippable/opt":6.3,"searchfox-android-aarch64-searchfox/debug":55.3,"searchfox-ios-searchfox/debug":49.8,"searchfox-linux64-searchfox/debug":60.3,"searchfox-linux64-searchfox/opt":54.5,"searchfox-macosx64-aarch64-searchfox/debug":60.4,"searchfox-macosx64-aarch64-searchfox/opt":54.7,"searchfox-macosx64-searchfox/debug":60.4,"searchfox-win64-searchfox/debug":66.6,"searchfox-win64-searchfox/opt":60.7,"shippable-l10n-linux64-shippable-1/opt":7.8,"signing-apk-fenix-android-test-beta":0.2,"signing-apk-fenix-android-test-debug":0.2,"signing-apk-fenix-beta-firebase":2.1,"signing-apk-fenix-debug":2.3,"signing-apk-fenix-nightly-simulation":2.5,"signing-apk-focus-android-test-beta":0.2,"signing-apk-focus-android-test-debug":0.2,"signing-apk-focus-beta-firebase":1.1,"signing-apk-focus-debug":1.3,"snap-upstream-build-amd64-local/debug":32.5,"snap-upstream-build-amd64-local/opt":31.5,"snap-upstream-build-amd64-nightly/debug":35.4,"snap-upstream-build-amd64-nightly/opt":34.0,"snap-upstream-build-amd64-stable/debug":35.8,"snap-upstream-build-amd64-stable/opt":60.5,"snap-upstream-build-arm64-local/debug":5.0,"snap-upstream-build-arm64-local/opt":5.1,"snap-upstream-build-arm64-nightly/debug":4.9,"snap-upstream-build-arm64-nightly/opt":3.9,"source-test-android-detekt-detekt-android-components":8.1,"source-test-android-detekt-detekt-fenix":7.0,"source-test-android-detekt-detekt-focus":6.2,"source-test-android-gradle-plugins-ac-dependencies-linux2404-64/opt":8.1,"source-test-android-gradle-plugins-apilint-linux2404-64/opt":8.1,"source-test-android-l10n-lint-l10n-lint-android-components":1.2,"source-test-android-l10n-lint-l10n-lint-fenix":1.3,"source-test-android-l10n-lint-l10n-lint-focus":1.1,"source-test-android-lint-android-components":10.8,"source-test-android-lint-fenix":16.6,"source-test-android-lint-focus":9.7,"source-test-buildconfig-buildconfig-android-components":4.8,"source-test-buildconfig-buildconfig-fenix":5.3,"source-test-buildconfig-buildconfig-focus":7.0,"source-test-clang-external":5.0,"source-test-clang-tidy":5.0,"source-test-clang-unittest":7.2,"source-test-doc-generate":7.4,"source-test-doc-upload":8.9,"source-test-file-metadata-bugzilla-components":4.5,"source-test-file-metadata-test-info-all":8.2,"source-test-ktlint-android-components":7.6,"source-test-ktlint-fenix":7.7,"source-test-ktlint-focus":6.5,"source-test-mozlint-agent-skills-sync":3.2,"source-test-mozlint-android-android-components":13.9,"source-test-mozlint-android-expired-strings":1.6,"source-test-mozlint-android-fenix":15.0,"source-test-mozlint-android-focus":10.7,"source-test-mozlint-android-lints":9.6,"source-test-mozlint-c-includes":3.3,"source-test-mozlint-cargo-audit":2.9,"source-test-mozlint-clang-format":4.7,"source-test-mozlint-clippy":10.5,"source-test-mozlint-codespell":2.0,"source-test-mozlint-condprof-addons-verify":3.7,"source-test-mozlint-dot-mozilla-reference":2.0,"source-test-mozlint-eslint":8.5,"source-test-mozlint-file-perm":2.2,"source-test-mozlint-file-whitespace":1.9,"source-test-mozlint-fluent-lint":3.9,"source-test-mozlint-gecko-trace":4.3,"source-test-mozlint-glean-parser":4.1,"source-test-mozlint-header-guards":2.0,"source-test-mozlint-ignorefile-test":3.6,"source-test-mozlint-l10n-conflicts":2.7,"source-test-mozlint-license":2.9,"source-test-mozlint-lintpref":3.7,"source-test-mozlint-localization":3.7,"source-test-mozlint-md":3.6,"source-test-mozlint-mingw-cap":2.7,"source-test-mozlint-mozcheck-tests":3.5,"source-test-mozlint-mscom-init":3.1,"source-test-mozlint-node-licenses":3.9,"source-test-mozlint-node-package-names":4.0,"source-test-mozlint-perfdocs-verify":4.2,"source-test-mozlint-py-ruff":3.6,"source-test-mozlint-py-ruff-format":3.1,"source-test-mozlint-python-sites":3.5,"source-test-mozlint-rejected-words":2.7,"source-test-mozlint-review-context-toml":3.7,"source-test-mozlint-rustfmt":3.5,"source-test-mozlint-shellcheck":3.6,"source-test-mozlint-stylelint":4.2,"source-test-mozlint-test-manifest":8.8,"source-test-mozlint-trojan-source":1.7,"source-test-mozlint-typescript":2.2,"source-test-mozlint-updatebot":3.1,"source-test-mozlint-wpt-subsuite-tagging":3.5,"source-test-mozlint-wptlint-gecko":4.2,"source-test-mozlint-yaml":2.1,"source-test-node-devtools-tests":3.2,"source-test-node-devtools-verify-bundle":1.8,"source-test-node-newtab-unit-tests":5.3,"source-test-puppeteer-puppeteer":6.5,"source-test-python-android-android-gradle-build-linux2404-64/opt":95.6,"source-test-python-condprof-linux2404-64/opt":3.1,"source-test-python-condprof-windows11-64/opt":10.9,"source-test-python-coverage":8.5,"source-test-python-firefox-ci":15.9,"source-test-python-fog-linux2404-64/opt":3.3,"source-test-python-fog-macosx1470-64/opt":4.4,"source-test-python-fog-windows11-64/opt":7.5,"source-test-python-fxms-schemas-linux2404-64/opt":2.2,"source-test-python-mach-linux2404-64/opt":3.0,"source-test-python-mach-windows11-64/opt":10.6,"source-test-python-marionette-harness-linux2404-64/opt":3.4,"source-test-python-marionette-harness-windows11-64/opt":6.5,"source-test-python-mochitest-harness-linux2404-64/debug":7.0,"source-test-python-mochitest-harness-linux2404-64/opt":4.5,"source-test-python-mozbase-linux2404-64/opt":3.4,"source-test-python-mozbase-windows11-64/opt":11.2,"source-test-python-mozbuild-3.11-linux2404-64/opt":9.6,"source-test-python-mozbuild-3.11-macosx1470-64/opt":11.1,"source-test-python-mozbuild-3.11-windows11-64/opt":23.6,"source-test-python-mozbuild-3.9-linux2404-64/opt":10.4,"source-test-python-mozbuild-3.9-macosx1470-64/opt":10.8,"source-test-python-mozbuild-3.9-windows11-64/opt":22.8,"source-test-python-mozharness":4.1,"source-test-python-mozlint-linux2404-64/opt":5.2,"source-test-python-mozlint-macosx1470-64/opt":6.1,"source-test-python-mozlint-windows11-64/opt":11.3,"source-test-python-mozperftest-linux2404-64/opt":4.3,"source-test-python-mozperftest-windows11-64/opt":12.8,"source-test-python-mozrelease":1.9,"source-test-python-mozterm-linux2404-64/opt":3.1,"source-test-python-mozterm-windows11-64/opt":10.6,"source-test-python-mozversioncontrol-linux2404-64/opt":3.6,"source-test-python-mozversioncontrol-windows11-64/opt":12.2,"source-test-python-nimbus-linux2404-64/opt":2.0,"source-test-python-raptor-linux2404-64/opt":2.2,"source-test-python-raptor-windows11-64/opt":7.4,"source-test-python-reftest-harness-linux2404-64-asan/opt":8.4,"source-test-python-reftest-harness-linux2404-64/debug":4.0,"source-test-python-reftest-harness-linux2404-64/opt":3.1,"source-test-python-talos":5.3,"source-test-python-taskgraph-tests":4.3,"source-test-python-telemetry-python-linux2404-64/opt":1.6,"source-test-python-telemetry-python-macosx1470-64/opt":4.7,"source-test-python-telemetry-python-windows11-64/opt":14.4,"source-test-python-tryselect-linux2404-64/opt":8.5,"source-test-python-tryselect-windows11-64/opt":19.4,"source-test-python-update-packaging-linux2404-64/opt":3.2,"source-test-python-verify-decision":3.5,"source-test-python-webext-linux2404-64/opt":3.4,"source-test-python-xpcom-linux2404-64/opt":1.9,"source-test-shadow-scheduler-bugbug_debug_disperse":3.9,"source-test-shadow-scheduler-bugbug_disperse_high":3.9,"source-test-shadow-scheduler-bugbug_disperse_low":3.9,"source-test-shadow-scheduler-bugbug_disperse_medium":3.8,"source-test-shadow-scheduler-bugbug_disperse_medium_no_unseen":3.8,"source-test-shadow-scheduler-bugbug_disperse_medium_only_one":3.8,"source-test-shadow-scheduler-bugbug_disperse_reduced_medium":3.9,"source-test-shadow-scheduler-bugbug_reduced":3.8,"source-test-shadow-scheduler-bugbug_reduced_high":3.9,"source-test-shadow-scheduler-bugbug_reduced_manifests_config_selection_low":3.8,"source-test-shadow-scheduler-bugbug_reduced_manifests_config_selection_medium":3.9,"source-test-shadow-scheduler-bugbug_tasks_high":3.9,"source-test-shadow-scheduler-bugbug_tasks_medium":3.8,"source-test-shadow-scheduler-relevant_tests":3.8,"source-test-taskgraph-diff":12.9,"source-test-vendor-rust":5.1,"source-test-vendor-verify-media":10.9,"spidermonkey-sm-arm-sim-linux32/debug":43.5,"spidermonkey-sm-arm64-sim-linux64/debug":46.8,"spidermonkey-sm-asan-linux64/opt":26.4,"spidermonkey-sm-compacting-linux64/debug":30.8,"spidermonkey-sm-compacting-win32/debug":37.3,"spidermonkey-sm-compacting-win64/debug":35.1,"spidermonkey-sm-concurrent-linux64/debug":30.1,"spidermonkey-sm-fuzzilli-linux64-aarch64/debug":11.3,"spidermonkey-sm-fuzzilli-linux64/debug":21.1,"spidermonkey-sm-fuzzing-asan-linux32/opt":32.5,"spidermonkey-sm-fuzzing-linux32/debug":47.5,"spidermonkey-sm-fuzzing-linux32/opt":20.0,"spidermonkey-sm-fuzzing-linux64/opt":19.5,"spidermonkey-sm-gdb-linux64/debug":10.3,"spidermonkey-sm-linux64-wasi-intl/opt":6.1,"spidermonkey-sm-linux64-wasi-pbl/opt":5.8,"spidermonkey-sm-linux64-wasi/opt":5.8,"spidermonkey-sm-loong64-sim-linux64/debug":35.1,"spidermonkey-sm-mips64-sim-linux64/debug":45.7,"spidermonkey-sm-nojit-linux64/opt":13.8,"spidermonkey-sm-nonunified-linux64/debug":19.9,"spidermonkey-sm-package-linux64/opt":28.7,"spidermonkey-sm-pbl-linux64/debug":26.7,"spidermonkey-sm-pbl-linux64/opt":13.8,"spidermonkey-sm-plain-linux32/debug":30.5,"spidermonkey-sm-plain-linux64/debug":28.9,"spidermonkey-sm-plain-linux64/opt":23.5,"spidermonkey-sm-plain-win32/debug":40.0,"spidermonkey-sm-plain-win32/opt":37.0,"spidermonkey-sm-plain-win64/debug":40.1,"spidermonkey-sm-plain-win64/opt":36.9,"spidermonkey-sm-riscv64-sim-linux64/debug":90.7,"spidermonkey-sm-rootanalysis-linux64/debug":54.2,"spidermonkey-sm-tsan-linux64/opt":31.6,"spidermonkey-sm-wasm-no-experimental-linux64/debug":23.7,"static-analysis-autotest-linux64-st-autotest/debug":5.0,"static-analysis-autotest-win64-st-autotest/debug":21.8,"test-android-em-14-x86_64-lite/opt-geckoview-crashtest-nofis":8.5,"test-android-em-14-x86_64-lite/opt-geckoview-gtest-1proc":12.6,"test-android-em-14-x86_64-lite/opt-geckoview-junit-fis":19.7,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-media":25.3,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-media-nofis":24.0,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-media-nogpu":23.6,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain":22.6,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-aab-nofis":0.3,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-fis-hv":22.7,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-gpu":5.0,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-gpu-nofis":5.3,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-ioi":0.3,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-nofis":22.6,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-standalone":0.4,"test-android-em-14-x86_64-lite/opt-geckoview-mochitest-plain-xorig":24.0,"test-android-em-14-x86_64-lite/opt-geckoview-reftest-nofis":0.3,"test-android-em-14-x86_64-lite/opt-geckoview-reftest-swr-nofis":0.3,"test-android-em-14-x86_64-lite/opt-geckoview-test-verify-nofis":2.6,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-crashtest-nofis":4.3,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-nofis":7.7,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-reftest-nofis":12.1,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec":4.9,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-async":0.3,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-wdspec-nofis":22.8,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-webcodecs":6.0,"test-android-em-14-x86_64-lite/opt-geckoview-web-platform-tests-webrtc":31.8,"test-android-em-14-x86_64-lite/opt-geckoview-xpcshell":19.9,"test-android-em-14-x86_64-lite/opt-geckoview-xpcshell-ioi":0.4,"test-android-em-14-x86_64-lite/opt-geckoview-xpcshell-nofis":21.9,"test-android-em-14-x86_64-lite/opt-geckoview-xpcshell-pb":0.6,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-mochitest-media":25.4,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-mochitest-media-nofis":24.2,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-mochitest-media-nogpu":19.8,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-mochitest-plain":23.5,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-mochitest-plain-fis-hv":21.4,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-mochitest-plain-nofis":22.4,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-reftest-nofis":27.0,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-crashtest-nofis":66.0,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-nofis":27.8,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-reftest-nofis":26.5,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-wdspec":23.9,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-wdspec-nofis":23.5,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-webcodecs":6.7,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-web-platform-tests-webrtc":33.9,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-xpcshell":25.4,"test-android-em-14-x86_64-shippable-lite/opt-geckoview-xpcshell-nofis":24.5,"test-android-em-14-x86_64-shippable/opt-geckoview-junit-nofis":32.2,"test-android-em-14-x86_64-shippable/opt-geckoview-mochitest-media":24.8,"test-android-em-14-x86_64-shippable/opt-geckoview-mochitest-media-nofis":25.2,"test-android-em-14-x86_64-shippable/opt-geckoview-mochitest-media-nogpu":25.1,"test-android-em-14-x86_64-shippable/opt-geckoview-mochitest-plain":22.7,"test-android-em-14-x86_64-shippable/opt-geckoview-mochitest-plain-fis-hv":22.0,"test-android-em-14-x86_64-shippable/opt-geckoview-mochitest-plain-nofis":21.7,"test-android-em-14-x86_64-shippable/opt-geckoview-reftest-nofis":22.8,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-backlog-nofis":31.1,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-crashtest-nofis":51.2,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-nofis":28.9,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-reftest-nofis":30.6,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-wdspec":24.4,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-wdspec-nofis":24.3,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-webcodecs":4.0,"test-android-em-14-x86_64-shippable/opt-geckoview-web-platform-tests-webrtc":32.8,"test-android-em-14-x86_64-shippable/opt-geckoview-xpcshell":25.6,"test-android-em-14-x86_64-shippable/opt-geckoview-xpcshell-nofis":14.2,"test-android-em-14-x86_64/debug-geckoview-cppunittest-1proc":4.1,"test-android-em-14-x86_64/debug-geckoview-crashtest-nofis":19.3,"test-android-em-14-x86_64/debug-geckoview-crashtest-swr-nofis":19.9,"test-android-em-14-x86_64/debug-geckoview-gtest-1proc":13.5,"test-android-em-14-x86_64/debug-geckoview-junit-fis":49.2,"test-android-em-14-x86_64/debug-geckoview-junit-nofis":45.3,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain":24.4,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-aab-nofis":23.9,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-fis-hv":23.2,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-gpu":5.8,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-gpu-nofis":5.3,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-gpu-swr-nofis":5.9,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-nofis":23.9,"test-android-em-14-x86_64/debug-geckoview-mochitest-plain-xorig":22.6,"test-android-em-14-x86_64/debug-geckoview-reftest-nofis":23.4,"test-android-em-14-x86_64/debug-geckoview-reftest-swr-nofis":25.9,"test-android-em-14-x86_64/debug-geckoview-test-verify-nofis":2.9,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-crashtest":5.0,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-crashtest-nofis":5.2,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-crashtest-swr":5.3,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-crashtest-swr-nofis":5.5,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-nofis":28.2,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-nofis":27.5,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-reftest-swr-nofis":26.6,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-wdspec":25.7,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-wdspec-nofis":24.9,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-webcodecs":8.1,"test-android-em-14-x86_64/debug-geckoview-web-platform-tests-webrtc":30.8,"test-android-em-14-x86_64/debug-geckoview-xpcshell":24.9,"test-android-em-14-x86_64/debug-geckoview-xpcshell-nofis":24.4,"test-android-em-14-x86_64/debug-isolated-process-geckoview-cppunittest-1proc":3.7,"test-android-em-14-x86_64/debug-isolated-process-geckoview-gtest-1proc":13.3,"test-android-em-14-x86_64/debug-isolated-process-geckoview-junit-fis":48.7,"test-android-em-14-x86_64/debug-isolated-process-geckoview-junit-nofis":46.3,"test-android-em-14-x86_64/debug-isolated-process-geckoview-mochitest-plain":23.6,"test-android-em-14-x86_64/debug-isolated-process-geckoview-mochitest-plain-fis-hv":22.8,"test-android-em-14-x86_64/debug-isolated-process-geckoview-mochitest-plain-xorig":22.9,"test-android-em-14-x86_64/debug-isolated-process-geckoview-reftest-nofis":22.9,"test-android-em-14-x86_64/debug-isolated-process-geckoview-test-verify-nofis":3.9,"test-android-em-14-x86_64/debug-isolated-process-geckoview-web-platform-tests-wdspec":24.6,"test-android-em-14-x86_64/debug-isolated-process-geckoview-web-platform-tests-wdspec-nofis":24.9,"test-android-em-14-x86_64/debug-isolated-process-geckoview-web-platform-tests-webcodecs":6.6,"test-android-em-14-x86_64/debug-isolated-process-geckoview-web-platform-tests-webrtc":33.9,"test-android-em-14-x86_64/debug-isolated-process-geckoview-xpcshell":24.4,"test-android-em-14-x86_64/opt-geckoview-cppunittest-1proc":3.7,"test-android-em-14-x86_64/opt-geckoview-crashtest-nofis":15.0,"test-android-em-14-x86_64/opt-geckoview-gtest-1proc":12.6,"test-android-em-14-x86_64/opt-geckoview-junit-fis":36.9,"test-android-em-14-x86_64/opt-geckoview-junit-nofis":34.1,"test-android-em-14-x86_64/opt-geckoview-mochitest-media":29.1,"test-android-em-14-x86_64/opt-geckoview-mochitest-media-nofis":25.7,"test-android-em-14-x86_64/opt-geckoview-mochitest-media-nogpu":24.4,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain":22.9,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-aab-nofis":2.4,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-fis-hv":22.4,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-gpu":5.1,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-gpu-nofis":5.0,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-ioi":2.4,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-nofis":23.2,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-standalone":2.4,"test-android-em-14-x86_64/opt-geckoview-mochitest-plain-xorig":22.7,"test-android-em-14-x86_64/opt-geckoview-reftest-nofis":22.6,"test-android-em-14-x86_64/opt-geckoview-reftest-swr-nofis":2.3,"test-android-em-14-x86_64/opt-geckoview-test-verify-nofis":2.7,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-crashtest-nofis":5.1,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-nofis":26.5,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-reftest-nofis":24.6,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-wdspec":23.3,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-wdspec-async":2.4,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-wdspec-nofis":23.0,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-webcodecs":6.2,"test-android-em-14-x86_64/opt-geckoview-web-platform-tests-webrtc":31.7,"test-android-em-14-x86_64/opt-geckoview-xpcshell":20.5,"test-android-em-14-x86_64/opt-geckoview-xpcshell-ioi":2.4,"test-android-em-14-x86_64/opt-geckoview-xpcshell-nofis":29.0,"test-android-em-14-x86_64/opt-geckoview-xpcshell-pb":2.4,"test-android-hw-a55-14-0-aarch64-shippable/opt-browsertime-benchmark-speedometer3-mobile-fenix":11.9,"test-android-hw-a55-14-0-aarch64-shippable/opt-browsertime-benchmark-speedometer3-mobile-geckoview":12.2,"test-android-hw-a55-14-0-aarch64-shippable/opt-geckoview-reftest-qr-nofis":13.0,"test-android-hw-a55-14-0-aarch64-shippable/opt-geckoview-reftest-qr-nogpu":11.7,"test-android-hw-p6-13-0-aarch64-shippable/opt-browsertime-benchmark-speedometer3-mobile-fenix":13.6,"test-android-hw-s24-14-0-aarch64-shippable/opt-browsertime-benchmark-speedometer3-mobile-fenix":12.9,"test-apk-fenix-debug":31.9,"test-apk-focus-debug":16.0,"test-components-android-feature-containers":24.5,"test-components-android-feature-downloads":25.0,"test-components-android-feature-logins":24.3,"test-components-android-feature-prompts":24.6,"test-components-android-feature-pwa":24.7,"test-components-android-feature-recentlyclosed":24.6,"test-components-android-feature-share":24.9,"test-components-android-feature-sitepermissions":24.2,"test-components-android-feature-top-sites":24.4,"test-components-android-lib-crash":25.6,"test-components-android-support-ktx":24.5,"test-components-ui-browser":24.7,"test-components-ui-glean":23.4,"test-components-unit-browser-engine-gecko-nightly":26.3,"test-linux2204-64-wayland-shippable/opt-crashtest":8.9,"test-linux2204-64-wayland-shippable/opt-mochitest-browser-translations":11.9,"test-linux2204-64-wayland-shippable/opt-mochitest-plain":21.6,"test-linux2204-64-wayland-shippable/opt-mochitest-webgl1-core":6.4,"test-linux2204-64-wayland-shippable/opt-mochitest-webgl2-ext":21.9,"test-linux2204-64-wayland-shippable/opt-telemetry-tests-client":2.6,"test-linux2204-64-wayland-shippable/opt-test-verify":1.3,"test-linux2204-64-wayland-shippable/opt-test-verify-gpu":1.2,"test-linux2204-64-wayland-shippable/opt-test-verify-nofis":1.3,"test-linux2204-64-wayland-shippable/opt-test-verify-wpt":1.3,"test-linux2204-64-wayland-shippable/opt-web-platform-tests-aam":4.2,"test-linux2204-64-wayland-shippable/opt-web-platform-tests-crashtest":25.7,"test-linux2204-64-wayland-shippable/opt-web-platform-tests-wdspec":45.1,"test-linux2204-64-wayland-shippable/opt-web-platform-tests-wdspec-headless":13.2,"test-linux2204-64-wayland-shippable/opt-web-platform-tests-webcodecs":3.0,"test-linux2204-64-wayland/debug-cppunittest-1proc":1.6,"test-linux2204-64-wayland/debug-firefox-ui-functional":2.3,"test-linux2204-64-wayland/debug-jsreftest":27.2,"test-linux2204-64-wayland/debug-mochitest-a11y-1proc":12.3,"test-linux2204-64-wayland/debug-mochitest-browser-media":14.6,"test-linux2204-64-wayland/debug-mochitest-browser-translations":28.1,"test-linux2204-64-wayland/debug-mochitest-chrome-gpu-1proc":2.5,"test-linux2204-64-wayland/debug-mochitest-plain":22.2,"test-linux2204-64-wayland/debug-mochitest-plain-gpu":3.1,"test-linux2204-64-wayland/debug-mochitest-remote":8.8,"test-linux2204-64-wayland/debug-mochitest-webgl1-core":14.7,"test-linux2204-64-wayland/debug-mochitest-webgl1-ext":18.9,"test-linux2204-64-wayland/debug-mochitest-webgl2-ext":23.7,"test-linux2204-64-wayland/debug-telemetry-tests-client":5.8,"test-linux2204-64-wayland/debug-web-platform-tests-aam":10.9,"test-linux2204-64-wayland/debug-web-platform-tests-crashtest":54.3,"test-linux2204-64-wayland/debug-web-platform-tests-wdspec":21.7,"test-linux2204-64-wayland/debug-web-platform-tests-wdspec-headless":21.7,"test-linux2204-64-wayland/debug-web-platform-tests-webcodecs":6.0,"test-linux2204-64-wayland/debug-web-platform-tests-webcodecs-openh264":8.7,"test-linux2204-64-wayland/debug-web-platform-tests-webcodecs-openh264-cisco":8.0,"test-linux2204-64-wayland/debug-web-platform-tests-webrtc":24.4,"test-linux2204-64-wayland/debug-web-platform-tests-webrtc-openh264":24.8,"test-linux2204-64-wayland/debug-web-platform-tests-webrtc-openh264-cisco":24.3,"test-linux2204-64-wayland/opt-cppunittest-1proc":1.0,"test-linux2204-64-wayland/opt-crashtest":9.9,"test-linux2204-64-wayland/opt-firefox-ui-functional":2.2,"test-linux2204-64-wayland/opt-jsreftest":16.3,"test-linux2204-64-wayland/opt-mochitest-a11y-1proc":5.3,"test-linux2204-64-wayland/opt-mochitest-browser-media":8.1,"test-linux2204-64-wayland/opt-mochitest-browser-translations":12.9,"test-linux2204-64-wayland/opt-mochitest-chrome-gpu-1proc":1.6,"test-linux2204-64-wayland/opt-mochitest-plain":21.4,"test-linux2204-64-wayland/opt-mochitest-plain-gpu":1.9,"test-linux2204-64-wayland/opt-mochitest-remote":4.0,"test-linux2204-64-wayland/opt-mochitest-webgl1-core":6.5,"test-linux2204-64-wayland/opt-mochitest-webgl1-ext":9.1,"test-linux2204-64-wayland/opt-mochitest-webgl2-ext":23.2,"test-linux2204-64-wayland/opt-telemetry-tests-client":2.7,"test-linux2204-64-wayland/opt-test-verify":1.3,"test-linux2204-64-wayland/opt-test-verify-gpu":1.3,"test-linux2204-64-wayland/opt-test-verify-nofis":1.3,"test-linux2204-64-wayland/opt-test-verify-wpt":1.3,"test-linux2204-64-wayland/opt-web-platform-tests-aam":4.5,"test-linux2204-64-wayland/opt-web-platform-tests-crashtest":25.2,"test-linux2204-64-wayland/opt-web-platform-tests-wdspec":23.7,"test-linux2204-64-wayland/opt-web-platform-tests-wdspec-headless":13.7,"test-linux2204-64-wayland/opt-web-platform-tests-webcodecs":3.3,"test-linux2204-64-wayland/opt-web-platform-tests-webrtc":12.2,"test-linux2404-64-asan/opt-cppunittest-1proc":2.7,"test-linux2404-64-asan/opt-crashtest":14.2,"test-linux2404-64-asan/opt-crashtest-swr":13.7,"test-linux2404-64-asan/opt-firefox-ui-functional":3.1,"test-linux2404-64-asan/opt-gtest-1proc":23.5,"test-linux2404-64-asan/opt-jsreftest":30.1,"test-linux2404-64-asan/opt-jsreftest-nofis":30.7,"test-linux2404-64-asan/opt-marionette-integration":19.0,"test-linux2404-64-asan/opt-marionette-unittest":18.8,"test-linux2404-64-asan/opt-mochitest-a11y-1proc":11.1,"test-linux2404-64-asan/opt-mochitest-browser-a11y":24.2,"test-linux2404-64-asan/opt-mochitest-browser-chrome-swr":21.6,"test-linux2404-64-asan/opt-mochitest-browser-media":10.3,"test-linux2404-64-asan/opt-mochitest-browser-translations":20.1,"test-linux2404-64-asan/opt-mochitest-chrome-1proc":25.4,"test-linux2404-64-asan/opt-mochitest-chrome-gpu-1proc":3.1,"test-linux2404-64-asan/opt-mochitest-devtools-chrome":22.7,"test-linux2404-64-asan/opt-mochitest-media-nofis":25.2,"test-linux2404-64-asan/opt-mochitest-media-spi":26.3,"test-linux2404-64-asan/opt-mochitest-media-spi-nofis":26.3,"test-linux2404-64-asan/opt-mochitest-media-swr-nofis":25.1,"test-linux2404-64-asan/opt-mochitest-plain":21.9,"test-linux2404-64-asan/opt-mochitest-plain-gpu":3.7,"test-linux2404-64-asan/opt-mochitest-plain-gpu-swr-nofis":3.2,"test-linux2404-64-asan/opt-mochitest-plain-headless":23.0,"test-linux2404-64-asan/opt-mochitest-plain-nofis":23.3,"test-linux2404-64-asan/opt-mochitest-remote":8.1,"test-linux2404-64-asan/opt-mochitest-remote-nofis":7.7,"test-linux2404-64-asan/opt-mochitest-webgl1-core":13.9,"test-linux2404-64-asan/opt-mochitest-webgl1-core-nofis":14.2,"test-linux2404-64-asan/opt-mochitest-webgl1-ext":17.4,"test-linux2404-64-asan/opt-mochitest-webgl1-ext-nofis":16.8,"test-linux2404-64-asan/opt-mochitest-webgl2-core":15.8,"test-linux2404-64-asan/opt-mochitest-webgl2-core-nofis":15.8,"test-linux2404-64-asan/opt-mochitest-webgl2-ext":21.6,"test-linux2404-64-asan/opt-mochitest-webgl2-ext-nofis":20.7,"test-linux2404-64-asan/opt-reftest-nofis":24.7,"test-linux2404-64-asan/opt-reftest-swr":22.6,"test-linux2404-64-asan/opt-reftest-swr-nofis":23.1,"test-linux2404-64-asan/opt-telemetry-tests-client":6.2,"test-linux2404-64-asan/opt-test-verify":9.3,"test-linux2404-64-asan/opt-test-verify-gpu":2.0,"test-linux2404-64-asan/opt-test-verify-nofis":9.1,"test-linux2404-64-asan/opt-test-verify-wpt":2.0,"test-linux2404-64-asan/opt-web-platform-tests":25.4,"test-linux2404-64-asan/opt-web-platform-tests-aam":15.4,"test-linux2404-64-asan/opt-web-platform-tests-aam-nofis":15.2,"test-linux2404-64-asan/opt-web-platform-tests-canvas":25.7,"test-linux2404-64-asan/opt-web-platform-tests-canvas-nofis":18.8,"test-linux2404-64-asan/opt-web-platform-tests-crashtest":39.7,"test-linux2404-64-asan/opt-web-platform-tests-crashtest-nofis":44.2,"test-linux2404-64-asan/opt-web-platform-tests-crashtest-swr-nofis":41.3,"test-linux2404-64-asan/opt-web-platform-tests-eme":6.8,"test-linux2404-64-asan/opt-web-platform-tests-nofis":16.3,"test-linux2404-64-asan/opt-web-platform-tests-pb":4.8,"test-linux2404-64-asan/opt-web-platform-tests-print-reftest":32.1,"test-linux2404-64-asan/opt-web-platform-tests-print-reftest-nofis":19.7,"test-linux2404-64-asan/opt-web-platform-tests-print-reftest-swr-nofis":19.9,"test-linux2404-64-asan/opt-web-platform-tests-reftest":33.6,"test-linux2404-64-asan/opt-web-platform-tests-reftest-nofis":25.6,"test-linux2404-64-asan/opt-web-platform-tests-reftest-swr-nofis":24.2,"test-linux2404-64-asan/opt-web-platform-tests-wdspec":22.3,"test-linux2404-64-asan/opt-web-platform-tests-wdspec-headless":23.9,"test-linux2404-64-asan/opt-web-platform-tests-wdspec-nofis":23.5,"test-linux2404-64-asan/opt-web-platform-tests-webcodecs":7.5,"test-linux2404-64-asan/opt-web-platform-tests-webrtc":25.7,"test-linux2404-64-asan/opt-xpcshell":20.3,"test-linux2404-64-ccov/opt-test-verify":10.3,"test-linux2404-64-ccov/opt-test-verify-gpu":2.5,"test-linux2404-64-ccov/opt-test-verify-nofis":9.5,"test-linux2404-64-ccov/opt-test-verify-wpt":2.7,"test-linux2404-64-devedition/opt-mochitest-browser-chrome-swr":22.2,"test-linux2404-64-devedition/opt-mochitest-devtools-chrome":23.1,"test-linux2404-64-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3":12.1,"test-linux2404-64-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3-native-profiling":26.0,"test-linux2404-64-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3-no-nv":12.0,"test-linux2404-64-shippable/opt-awsy-base":4.2,"test-linux2404-64-shippable/opt-awsy-tp6":12.6,"test-linux2404-64-shippable/opt-browsertime-benchmark-firefox-jetstream3":5.4,"test-linux2404-64-shippable/opt-browsertime-benchmark-firefox-speedometer3":11.0,"test-linux2404-64-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling":23.7,"test-linux2404-64-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling-no-nv":23.8,"test-linux2404-64-shippable/opt-browsertime-benchmark-firefox-speedometer3-no-nv":10.9,"test-linux2404-64-shippable/opt-browsertime-nav-bench-firefox-nav-bench":3.9,"test-linux2404-64-shippable/opt-browsertime-responsiveness-firefox-reddit-billgates-post":11.8,"test-linux2404-64-shippable/opt-crashtest":7.2,"test-linux2404-64-shippable/opt-firefox-ui-functional":2.2,"test-linux2404-64-shippable/opt-marionette-integration-headless":11.2,"test-linux2404-64-shippable/opt-marionette-unittest":7.9,"test-linux2404-64-shippable/opt-mochitest-browser-chrome-ml-models":2.9,"test-linux2404-64-shippable/opt-mochitest-browser-chrome-swr":21.9,"test-linux2404-64-shippable/opt-mochitest-browser-media":5.8,"test-linux2404-64-shippable/opt-mochitest-chrome-gpu-1proc":2.4,"test-linux2404-64-shippable/opt-mochitest-devtools-chrome":23.5,"test-linux2404-64-shippable/opt-mochitest-media-spi":19.4,"test-linux2404-64-shippable/opt-mochitest-plain":21.7,"test-linux2404-64-shippable/opt-mochitest-plain-gpu":2.0,"test-linux2404-64-shippable/opt-mochitest-plain-headless":20.3,"test-linux2404-64-shippable/opt-mochitest-remote":3.9,"test-linux2404-64-shippable/opt-mochitest-webgl2-ext":18.2,"test-linux2404-64-shippable/opt-reftest":21.5,"test-linux2404-64-shippable/opt-reftest-nogpu":21.4,"test-linux2404-64-shippable/opt-telemetry-tests-client":2.4,"test-linux2404-64-shippable/opt-test-verify":4.9,"test-linux2404-64-shippable/opt-test-verify-gpu":1.3,"test-linux2404-64-shippable/opt-test-verify-nofis":4.9,"test-linux2404-64-shippable/opt-test-verify-wpt":1.4,"test-linux2404-64-shippable/opt-web-platform-tests":23.5,"test-linux2404-64-shippable/opt-web-platform-tests-backlog":26.2,"test-linux2404-64-shippable/opt-web-platform-tests-canvas":7.9,"test-linux2404-64-shippable/opt-web-platform-tests-pb":2.1,"test-linux2404-64-shippable/opt-web-platform-tests-reftest":23.2,"test-linux2404-64-shippable/opt-web-platform-tests-wdspec":20.8,"test-linux2404-64-shippable/opt-web-platform-tests-wdspec-headless":26.6,"test-linux2404-64-shippable/opt-web-platform-tests-webrtc":12.1,"test-linux2404-64-shippable/opt-xpcshell":14.6,"test-linux2404-64-tsan/opt-cppunittest-1proc":2.5,"test-linux2404-64-tsan/opt-crashtest":21.6,"test-linux2404-64-tsan/opt-crashtest-swr":21.4,"test-linux2404-64-tsan/opt-firefox-ui-functional":3.7,"test-linux2404-64-tsan/opt-gtest-1proc":41.7,"test-linux2404-64-tsan/opt-jsreftest":24.3,"test-linux2404-64-tsan/opt-marionette-integration":21.4,"test-linux2404-64-tsan/opt-marionette-unittest":41.8,"test-linux2404-64-tsan/opt-mochitest-a11y-1proc":20.3,"test-linux2404-64-tsan/opt-mochitest-browser-a11y":22.9,"test-linux2404-64-tsan/opt-mochitest-browser-chrome-swr":21.5,"test-linux2404-64-tsan/opt-mochitest-browser-media":12.4,"test-linux2404-64-tsan/opt-mochitest-browser-translations":31.7,"test-linux2404-64-tsan/opt-mochitest-chrome-1proc":21.4,"test-linux2404-64-tsan/opt-mochitest-chrome-gpu-1proc":3.2,"test-linux2404-64-tsan/opt-mochitest-devtools-chrome":21.8,"test-linux2404-64-tsan/opt-mochitest-media-spi":19.8,"test-linux2404-64-tsan/opt-mochitest-plain":22.1,"test-linux2404-64-tsan/opt-mochitest-plain-gpu":4.4,"test-linux2404-64-tsan/opt-mochitest-plain-headless":22.1,"test-linux2404-64-tsan/opt-mochitest-remote":11.8,"test-linux2404-64-tsan/opt-reftest":22.4,"test-linux2404-64-tsan/opt-reftest-nogpu":22.1,"test-linux2404-64-tsan/opt-reftest-swr":22.4,"test-linux2404-64-tsan/opt-telemetry-tests-client":13.1,"test-linux2404-64-tsan/opt-test-verify":15.5,"test-linux2404-64-tsan/opt-test-verify-gpu":1.8,"test-linux2404-64-tsan/opt-test-verify-nofis":15.1,"test-linux2404-64-tsan/opt-test-verify-wpt":1.8,"test-linux2404-64-tsan/opt-web-platform-tests":25.9,"test-linux2404-64-tsan/opt-web-platform-tests-aam":26.1,"test-linux2404-64-tsan/opt-web-platform-tests-canvas":27.8,"test-linux2404-64-tsan/opt-web-platform-tests-crashtest":45.9,"test-linux2404-64-tsan/opt-web-platform-tests-eme":6.7,"test-linux2404-64-tsan/opt-web-platform-tests-pb":5.0,"test-linux2404-64-tsan/opt-web-platform-tests-print-reftest":46.7,"test-linux2404-64-tsan/opt-web-platform-tests-reftest":33.5,"test-linux2404-64-tsan/opt-web-platform-tests-wdspec":22.6,"test-linux2404-64-tsan/opt-web-platform-tests-wdspec-headless":22.0,"test-linux2404-64-tsan/opt-web-platform-tests-webcodecs":10.8,"test-linux2404-64-tsan/opt-web-platform-tests-webrtc":29.7,"test-linux2404-64-tsan/opt-xpcshell":20.0,"test-linux2404-64-tsan/opt-xpcshell-nofis":24.7,"test-linux2404-64/debug-cppunittest-1proc":2.6,"test-linux2404-64/debug-crashtest":13.7,"test-linux2404-64/debug-crashtest-nofis":13.5,"test-linux2404-64/debug-crashtest-swr":13.4,"test-linux2404-64/debug-crashtest-swr-nofis":13.3,"test-linux2404-64/debug-firefox-ui-functional":2.9,"test-linux2404-64/debug-gtest-1proc":25.3,"test-linux2404-64/debug-jsreftest":19.3,"test-linux2404-64/debug-jsreftest-nofis":19.4,"test-linux2404-64/debug-marionette-integration":29.9,"test-linux2404-64/debug-marionette-integration-swr":28.9,"test-linux2404-64/debug-marionette-unittest":15.4,"test-linux2404-64/debug-marionette-unittest-swr":14.6,"test-linux2404-64/debug-mochitest-a11y-1proc":9.3,"test-linux2404-64/debug-mochitest-a11y-swr-1proc":9.1,"test-linux2404-64/debug-mochitest-browser-a11y":23.0,"test-linux2404-64/debug-mochitest-browser-chrome-standalone":22.8,"test-linux2404-64/debug-mochitest-browser-chrome-swr":22.3,"test-linux2404-64/debug-mochitest-browser-chrome-vt":15.6,"test-linux2404-64/debug-mochitest-browser-media":10.1,"test-linux2404-64/debug-mochitest-browser-translations":20.4,"test-linux2404-64/debug-mochitest-chrome-1proc":24.1,"test-linux2404-64/debug-mochitest-chrome-gpu-1proc":3.0,"test-linux2404-64/debug-mochitest-chrome-gpu-swr-1proc":2.9,"test-linux2404-64/debug-mochitest-chrome-standalone":23.5,"test-linux2404-64/debug-mochitest-chrome-swr-1proc":23.5,"test-linux2404-64/debug-mochitest-devtools-chrome":22.5,"test-linux2404-64/debug-mochitest-devtools-chrome-http3":22.6,"test-linux2404-64/debug-mochitest-devtools-chrome-standalone":23.2,"test-linux2404-64/debug-mochitest-media-nofis":25.8,"test-linux2404-64/debug-mochitest-media-spi":25.9,"test-linux2404-64/debug-mochitest-media-spi-nofis":25.8,"test-linux2404-64/debug-mochitest-media-swr":25.6,"test-linux2404-64/debug-mochitest-media-swr-nofis":25.6,"test-linux2404-64/debug-mochitest-plain":23.4,"test-linux2404-64/debug-mochitest-plain-gpu":3.4,"test-linux2404-64/debug-mochitest-plain-gpu-nofis":3.3,"test-linux2404-64/debug-mochitest-plain-gpu-swr":3.3,"test-linux2404-64/debug-mochitest-plain-gpu-swr-nofis":3.3,"test-linux2404-64/debug-mochitest-plain-headless":21.9,"test-linux2404-64/debug-mochitest-plain-http2":21.0,"test-linux2404-64/debug-mochitest-plain-http3":21.6,"test-linux2404-64/debug-mochitest-plain-nofis":23.1,"test-linux2404-64/debug-mochitest-plain-standalone":22.5,"test-linux2404-64/debug-mochitest-plain-xorig":23.1,"test-linux2404-64/debug-mochitest-remote":7.3,"test-linux2404-64/debug-mochitest-remote-nofis":7.1,"test-linux2404-64/debug-mochitest-webgl1-core":11.0,"test-linux2404-64/debug-mochitest-webgl1-core-nofis":11.0,"test-linux2404-64/debug-mochitest-webgl1-core-swr":10.9,"test-linux2404-64/debug-mochitest-webgl1-core-swr-nofis":10.7,"test-linux2404-64/debug-mochitest-webgl1-ext":13.8,"test-linux2404-64/debug-mochitest-webgl1-ext-nofis":13.9,"test-linux2404-64/debug-mochitest-webgl1-ext-swr":13.6,"test-linux2404-64/debug-mochitest-webgl1-ext-swr-nofis":13.4,"test-linux2404-64/debug-mochitest-webgl2-core":14.6,"test-linux2404-64/debug-mochitest-webgl2-core-nofis":14.6,"test-linux2404-64/debug-mochitest-webgl2-core-swr":14.4,"test-linux2404-64/debug-mochitest-webgl2-core-swr-nofis":14.2,"test-linux2404-64/debug-mochitest-webgl2-ext":17.8,"test-linux2404-64/debug-mochitest-webgl2-ext-nofis":17.7,"test-linux2404-64/debug-mochitest-webgl2-ext-swr":17.4,"test-linux2404-64/debug-mochitest-webgl2-ext-swr-nofis":31.9,"test-linux2404-64/debug-mochitest-webgpu":2.9,"test-linux2404-64/debug-reftest":20.7,"test-linux2404-64/debug-reftest-nofis":20.7,"test-linux2404-64/debug-reftest-nogpu":20.8,"test-linux2404-64/debug-reftest-s":20.4,"test-linux2404-64/debug-reftest-swr":20.5,"test-linux2404-64/debug-reftest-swr-nofis":25.1,"test-linux2404-64/debug-telemetry-tests-client":5.2,"test-linux2404-64/debug-test-verify":3.0,"test-linux2404-64/debug-test-verify-gpu":2.9,"test-linux2404-64/debug-test-verify-wpt":2.9,"test-linux2404-64/debug-web-platform-tests":24.7,"test-linux2404-64/debug-web-platform-tests-aam":9.8,"test-linux2404-64/debug-web-platform-tests-aam-nofis":9.6,"test-linux2404-64/debug-web-platform-tests-backlog":33.9,"test-linux2404-64/debug-web-platform-tests-canvas":24.1,"test-linux2404-64/debug-web-platform-tests-canvas-nofis":17.3,"test-linux2404-64/debug-web-platform-tests-crashtest":46.7,"test-linux2404-64/debug-web-platform-tests-crashtest-nofis":34.1,"test-linux2404-64/debug-web-platform-tests-crashtest-swr":9.2,"test-linux2404-64/debug-web-platform-tests-crashtest-swr-nofis":32.7,"test-linux2404-64/debug-web-platform-tests-eme":6.1,"test-linux2404-64/debug-web-platform-tests-nofis":15.2,"test-linux2404-64/debug-web-platform-tests-pb":2.5,"test-linux2404-64/debug-web-platform-tests-print-reftest":29.7,"test-linux2404-64/debug-web-platform-tests-print-reftest-nofis":18.0,"test-linux2404-64/debug-web-platform-tests-print-reftest-swr":29.5,"test-linux2404-64/debug-web-platform-tests-print-reftest-swr-nofis":17.9,"test-linux2404-64/debug-web-platform-tests-reftest":29.6,"test-linux2404-64/debug-web-platform-tests-reftest-nofis":17.6,"test-linux2404-64/debug-web-platform-tests-reftest-s":27.9,"test-linux2404-64/debug-web-platform-tests-reftest-swr":27.9,"test-linux2404-64/debug-web-platform-tests-reftest-swr-nofis":20.1,"test-linux2404-64/debug-web-platform-tests-wdspec":23.3,"test-linux2404-64/debug-web-platform-tests-wdspec-headless":25.2,"test-linux2404-64/debug-web-platform-tests-wdspec-nofis":23.1,"test-linux2404-64/debug-web-platform-tests-webcodecs":5.7,"test-linux2404-64/debug-web-platform-tests-webcodecs-openh264":7.1,"test-linux2404-64/debug-web-platform-tests-webcodecs-openh264-cisco":6.8,"test-linux2404-64/debug-web-platform-tests-webgpu":23.4,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog":20.2,"test-linux2404-64/debug-web-platform-tests-webgpu-backlog-long":43.3,"test-linux2404-64/debug-web-platform-tests-webgpu-long":39.7,"test-linux2404-64/debug-web-platform-tests-webrtc":23.0,"test-linux2404-64/debug-web-platform-tests-webrtc-openh264":22.9,"test-linux2404-64/debug-web-platform-tests-webrtc-openh264-cisco":22.0,"test-linux2404-64/debug-xpcshell":21.5,"test-linux2404-64/debug-xpcshell-nofis":22.6,"test-linux2404-64/opt-browsertime-regression-tests-firefox-constant-regression":0.6,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-av1-q":3.1,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-av1-q-cam":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-av1-q-i420":3.3,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-av1-rt":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-av1-rt-cam":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-av1-rt-i420":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp8-q":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp8-q-cam":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp8-q-i420":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp8-rt":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp8-rt-cam":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp8-rt-i420":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp9-q":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp9-q-cam":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp9-q-i420":3.1,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp9-rt":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp9-rt-cam":3.0,"test-linux2404-64/opt-browsertime-webcodecs-firefox-ve-vp9-rt-i420":3.0,"test-linux2404-64/opt-cppunittest-1proc":2.0,"test-linux2404-64/opt-crashtest":8.0,"test-linux2404-64/opt-firefox-ui-functional":2.4,"test-linux2404-64/opt-gtest-1proc":20.5,"test-linux2404-64/opt-jsreftest":8.7,"test-linux2404-64/opt-marionette-integration":14.5,"test-linux2404-64/opt-marionette-integration-headless":11.8,"test-linux2404-64/opt-marionette-unittest":8.9,"test-linux2404-64/opt-marionette-unittest-headless":7.7,"test-linux2404-64/opt-mochitest-a11y-1proc":4.3,"test-linux2404-64/opt-mochitest-browser-a11y":9.3,"test-linux2404-64/opt-mochitest-browser-chrome-no-nv":23.1,"test-linux2404-64/opt-mochitest-browser-chrome-no-nv-vt":8.7,"test-linux2404-64/opt-mochitest-browser-chrome-standalone":23.9,"test-linux2404-64/opt-mochitest-browser-chrome-swr":23.0,"test-linux2404-64/opt-mochitest-browser-chrome-swr-a11y-checks":23.4,"test-linux2404-64/opt-mochitest-browser-chrome-swr-uipc":21.4,"test-linux2404-64/opt-mochitest-browser-chrome-trainhop-beta":2.7,"test-linux2404-64/opt-mochitest-browser-chrome-trainhop-rel":3.3,"test-linux2404-64/opt-mochitest-browser-chrome-vt":8.6,"test-linux2404-64/opt-mochitest-browser-media":5.7,"test-linux2404-64/opt-mochitest-browser-screenshots":27.9,"test-linux2404-64/opt-mochitest-browser-screenshots-no-nv":27.9,"test-linux2404-64/opt-mochitest-browser-translations":10.3,"test-linux2404-64/opt-mochitest-chrome-1proc":25.5,"test-linux2404-64/opt-mochitest-chrome-gpu-1proc":1.9,"test-linux2404-64/opt-mochitest-chrome-no-nv":25.9,"test-linux2404-64/opt-mochitest-chrome-standalone":24.8,"test-linux2404-64/opt-mochitest-devtools-chrome":25.1,"test-linux2404-64/opt-mochitest-devtools-chrome-a11y-checks":22.6,"test-linux2404-64/opt-mochitest-devtools-chrome-standalone":23.5,"test-linux2404-64/opt-mochitest-media-spi":20.5,"test-linux2404-64/opt-mochitest-plain":23.1,"test-linux2404-64/opt-mochitest-plain-condprof":19.1,"test-linux2404-64/opt-mochitest-plain-gpu":2.6,"test-linux2404-64/opt-mochitest-plain-standalone":24.1,"test-linux2404-64/opt-mochitest-plain-xorig":23.4,"test-linux2404-64/opt-mochitest-remote":3.7,"test-linux2404-64/opt-mochitest-remote-nofis":3.7,"test-linux2404-64/opt-mochitest-webgl1-core":6.3,"test-linux2404-64/opt-mochitest-webgl1-core-nofis":6.1,"test-linux2404-64/opt-mochitest-webgl1-ext":7.7,"test-linux2404-64/opt-mochitest-webgl1-ext-nofis":7.9,"test-linux2404-64/opt-mochitest-webgl2-core":6.9,"test-linux2404-64/opt-mochitest-webgl2-core-nofis":6.8,"test-linux2404-64/opt-mochitest-webgl2-ext":19.4,"test-linux2404-64/opt-mochitest-webgl2-ext-nofis":19.1,"test-linux2404-64/opt-mochitest-webgpu":2.4,"test-linux2404-64/opt-reftest":23.3,"test-linux2404-64/opt-reftest-nogpu":23.3,"test-linux2404-64/opt-reftest-swr":9.0,"test-linux2404-64/opt-talos-bcv":9.8,"test-linux2404-64/opt-telemetry-tests-client":3.2,"test-linux2404-64/opt-test-verify":2.8,"test-linux2404-64/opt-test-verify-gpu":2.4,"test-linux2404-64/opt-test-verify-nofis":6.3,"test-linux2404-64/opt-test-verify-wpt":2.5,"test-linux2404-64/opt-web-platform-tests":25.1,"test-linux2404-64/opt-web-platform-tests-aam":5.5,"test-linux2404-64/opt-web-platform-tests-backlog":26.2,"test-linux2404-64/opt-web-platform-tests-canvas":8.9,"test-linux2404-64/opt-web-platform-tests-crashtest":3.3,"test-linux2404-64/opt-web-platform-tests-eme":3.2,"test-linux2404-64/opt-web-platform-tests-pb":2.1,"test-linux2404-64/opt-web-platform-tests-print-reftest":23.4,"test-linux2404-64/opt-web-platform-tests-reftest":24.3,"test-linux2404-64/opt-web-platform-tests-wdspec":22.4,"test-linux2404-64/opt-web-platform-tests-wdspec-headless":28.6,"test-linux2404-64/opt-web-platform-tests-webcodecs":3.6,"test-linux2404-64/opt-web-platform-tests-webgpu":19.3,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog":14.1,"test-linux2404-64/opt-web-platform-tests-webgpu-backlog-long":26.6,"test-linux2404-64/opt-web-platform-tests-webgpu-long":40.1,"test-linux2404-64/opt-web-platform-tests-webrtc":11.8,"test-linux2404-64/opt-xpcshell":13.5,"test-linux2404-64/opt-xpcshell-condprof":4.0,"test-macosx1015-64-qr/debug-cppunittest-1proc":2.4,"test-macosx1015-64-qr/debug-crashtest":16.9,"test-macosx1015-64-qr/debug-crashtest-swr":16.8,"test-macosx1015-64-qr/debug-jittest-1proc":14.6,"test-macosx1015-64-qr/debug-mochitest-media":20.4,"test-macosx1015-64-qr/debug-mochitest-media-mda-gpu":24.8,"test-macosx1015-64-qr/debug-mochitest-media-nogpu":20.4,"test-macosx1015-64-qr/debug-mochitest-media-spi":20.9,"test-macosx1015-64-qr/debug-mochitest-media-swr":36.6,"test-macosx1015-64-qr/debug-mochitest-webgl1-core":14.8,"test-macosx1015-64-qr/debug-mochitest-webgl1-ext":16.9,"test-macosx1015-64-qr/debug-mochitest-webgl2-core":14.3,"test-macosx1015-64-qr/debug-mochitest-webgl2-ext":21.8,"test-macosx1015-64-qr/debug-xpcshell":20.8,"test-macosx1015-64-qr/opt-jittest-1proc":11.3,"test-macosx1015-64-qr/opt-mochitest-media":21.2,"test-macosx1015-64-qr/opt-mochitest-media-mda-gpu":18.2,"test-macosx1015-64-qr/opt-mochitest-media-nogpu":21.2,"test-macosx1015-64-qr/opt-mochitest-media-spi":21.3,"test-macosx1015-64-qr/opt-mochitest-webgl1-ext":7.6,"test-macosx1015-64-qr/opt-xpcshell":22.8,"test-macosx1015-64-shippable-qr/opt-mochitest-media":21.4,"test-macosx1015-64-shippable-qr/opt-mochitest-media-nogpu":21.6,"test-macosx1015-64-shippable-qr/opt-mochitest-media-spi":22.8,"test-macosx1470-64-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3":12.2,"test-macosx1470-64-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3-native-profiling":31.4,"test-macosx1470-64-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3-no-nv":12.2,"test-macosx1470-64-shippable/opt-awsy-base":4.9,"test-macosx1470-64-shippable/opt-awsy-tp6":13.3,"test-macosx1470-64-shippable/opt-browsertime-benchmark-firefox-jetstream3":7.1,"test-macosx1470-64-shippable/opt-browsertime-benchmark-firefox-speedometer3":12.2,"test-macosx1470-64-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling":28.6,"test-macosx1470-64-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling-no-nv":28.6,"test-macosx1470-64-shippable/opt-browsertime-benchmark-firefox-speedometer3-no-nv":11.7,"test-macosx1470-64-shippable/opt-browsertime-responsiveness-firefox-reddit-billgates-post":15.2,"test-macosx1470-64/debug-cppunittest-1proc":2.3,"test-macosx1470-64/debug-mochitest-webgpu":3.2,"test-macosx1470-64/debug-web-platform-tests-webgpu":30.8,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog":11.3,"test-macosx1470-64/debug-web-platform-tests-webgpu-backlog-long":54.5,"test-macosx1470-64/debug-web-platform-tests-webgpu-long":54.2,"test-macosx1470-64/opt-mochitest-webgpu":1.7,"test-macosx1470-64/opt-web-platform-tests-webgpu":27.2,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog":9.7,"test-macosx1470-64/opt-web-platform-tests-webgpu-backlog-long":43.5,"test-macosx1470-64/opt-web-platform-tests-webgpu-long":51.4,"test-macosx1500-aarch64-devedition/opt-mochitest-browser-chrome":20.9,"test-macosx1500-aarch64-devedition/opt-mochitest-devtools-chrome":23.0,"test-macosx1500-aarch64-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3":7.3,"test-macosx1500-aarch64-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3-native-profiling":14.1,"test-macosx1500-aarch64-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3-no-nv":7.4,"test-macosx1500-aarch64-shippable/opt-browsertime-benchmark-firefox-jetstream3":3.4,"test-macosx1500-aarch64-shippable/opt-browsertime-benchmark-firefox-speedometer3":7.7,"test-macosx1500-aarch64-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling":14.3,"test-macosx1500-aarch64-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling-no-nv":14.6,"test-macosx1500-aarch64-shippable/opt-browsertime-benchmark-firefox-speedometer3-no-nv":7.9,"test-macosx1500-aarch64-shippable/opt-mochitest-browser-chrome":20.7,"test-macosx1500-aarch64-shippable/opt-mochitest-browser-chrome-ml-models":1.3,"test-macosx1500-aarch64-shippable/opt-mochitest-chrome-1proc":12.3,"test-macosx1500-aarch64-shippable/opt-mochitest-devtools-chrome":23.7,"test-macosx1500-aarch64-shippable/opt-mochitest-plain":18.6,"test-macosx1500-aarch64-shippable/opt-reftest":16.3,"test-macosx1500-aarch64-shippable/opt-reftest-nogpu":15.5,"test-macosx1500-aarch64-shippable/opt-web-platform-tests":21.8,"test-macosx1500-aarch64-shippable/opt-web-platform-tests-reftest":20.9,"test-macosx1500-aarch64-shippable/opt-web-platform-tests-wdspec":23.9,"test-macosx1500-aarch64-shippable/opt-web-platform-tests-wdspec-headless":23.1,"test-macosx1500-aarch64-shippable/opt-xpcshell":9.6,"test-macosx1500-aarch64-vms-shippable/opt-mochitest-chrome-1proc":18.0,"test-macosx1500-aarch64-vms-shippable/opt-mochitest-plain":22.8,"test-macosx1500-aarch64-vms/debug-cppunittest-1proc":2.1,"test-macosx1500-aarch64-vms/debug-jittest-1proc":8.6,"test-macosx1500-aarch64-vms/debug-telemetry-tests-client":3.8,"test-macosx1500-aarch64-vms/debug-xpcshell":24.5,"test-macosx1500-aarch64-vms/opt-jittest-1proc":14.2,"test-macosx1500-aarch64-vms/opt-jsreftest":5.7,"test-macosx1500-aarch64-vms/opt-marionette-integration":5.7,"test-macosx1500-aarch64-vms/opt-marionette-unittest":6.4,"test-macosx1500-aarch64-vms/opt-mochitest-chrome-1proc":18.4,"test-macosx1500-aarch64-vms/opt-mochitest-plain":18.2,"test-macosx1500-aarch64-vms/opt-xpcshell":20.6,"test-macosx1500-aarch64/debug-cppunittest-1proc":0.9,"test-macosx1500-aarch64/debug-crashtest":8.6,"test-macosx1500-aarch64/debug-crashtest-swr":9.4,"test-macosx1500-aarch64/debug-firefox-ui-functional":1.6,"test-macosx1500-aarch64/debug-gtest-1proc":15.8,"test-macosx1500-aarch64/debug-jittest-1proc":4.6,"test-macosx1500-aarch64/debug-jsreftest":12.0,"test-macosx1500-aarch64/debug-marionette-integration":12.2,"test-macosx1500-aarch64/debug-marionette-integration-swr":4.6,"test-macosx1500-aarch64/debug-marionette-unittest":9.3,"test-macosx1500-aarch64/debug-marionette-unittest-swr":9.1,"test-macosx1500-aarch64/debug-mochitest-a11y-1proc":4.5,"test-macosx1500-aarch64/debug-mochitest-browser-a11y":13.4,"test-macosx1500-aarch64/debug-mochitest-browser-chrome":21.4,"test-macosx1500-aarch64/debug-mochitest-browser-chrome-vt":8.3,"test-macosx1500-aarch64/debug-mochitest-browser-media":3.4,"test-macosx1500-aarch64/debug-mochitest-browser-translations":14.4,"test-macosx1500-aarch64/debug-mochitest-chrome-1proc":22.1,"test-macosx1500-aarch64/debug-mochitest-chrome-gpu-1proc":1.2,"test-macosx1500-aarch64/debug-mochitest-devtools-chrome":21.4,"test-macosx1500-aarch64/debug-mochitest-media":24.5,"test-macosx1500-aarch64/debug-mochitest-media-mda-gpu":18.5,"test-macosx1500-aarch64/debug-mochitest-media-nogpu":19.2,"test-macosx1500-aarch64/debug-mochitest-media-spi":24.5,"test-macosx1500-aarch64/debug-mochitest-media-swr":25.2,"test-macosx1500-aarch64/debug-mochitest-plain":21.2,"test-macosx1500-aarch64/debug-mochitest-plain-gpu":1.4,"test-macosx1500-aarch64/debug-mochitest-plain-xorig":21.2,"test-macosx1500-aarch64/debug-mochitest-remote":4.2,"test-macosx1500-aarch64/debug-mochitest-webgl1-core":4.8,"test-macosx1500-aarch64/debug-mochitest-webgl1-ext":6.2,"test-macosx1500-aarch64/debug-mochitest-webgl2-core":6.5,"test-macosx1500-aarch64/debug-mochitest-webgl2-ext":18.9,"test-macosx1500-aarch64/debug-reftest":23.2,"test-macosx1500-aarch64/debug-reftest-nogpu":23.1,"test-macosx1500-aarch64/debug-reftest-swr":22.5,"test-macosx1500-aarch64/debug-telemetry-tests-client":3.3,"test-macosx1500-aarch64/debug-test-verify":42.1,"test-macosx1500-aarch64/debug-test-verify-wpt":1.5,"test-macosx1500-aarch64/debug-web-platform-tests":22.9,"test-macosx1500-aarch64/debug-web-platform-tests-canvas":10.3,"test-macosx1500-aarch64/debug-web-platform-tests-crashtest":21.5,"test-macosx1500-aarch64/debug-web-platform-tests-eme":4.4,"test-macosx1500-aarch64/debug-web-platform-tests-pb":2.4,"test-macosx1500-aarch64/debug-web-platform-tests-print-reftest":26.8,"test-macosx1500-aarch64/debug-web-platform-tests-reftest":24.7,"test-macosx1500-aarch64/debug-web-platform-tests-wdspec":21.6,"test-macosx1500-aarch64/debug-web-platform-tests-wdspec-headless":25.5,"test-macosx1500-aarch64/debug-web-platform-tests-webcodecs":2.4,"test-macosx1500-aarch64/debug-web-platform-tests-webcodecs-openh264":5.2,"test-macosx1500-aarch64/debug-web-platform-tests-webcodecs-openh264-cisco":4.9,"test-macosx1500-aarch64/debug-web-platform-tests-webrtc":18.9,"test-macosx1500-aarch64/debug-web-platform-tests-webrtc-openh264":25.3,"test-macosx1500-aarch64/debug-web-platform-tests-webrtc-openh264-cisco":19.1,"test-macosx1500-aarch64/debug-xpcshell":19.4,"test-macosx1500-aarch64/opt-firefox-ui-functional":2.0,"test-macosx1500-aarch64/opt-gtest-1proc":15.4,"test-macosx1500-aarch64/opt-jittest-1proc":5.5,"test-macosx1500-aarch64/opt-jsreftest":3.4,"test-macosx1500-aarch64/opt-marionette-integration":3.8,"test-macosx1500-aarch64/opt-marionette-unittest":5.7,"test-macosx1500-aarch64/opt-mochitest-a11y-1proc":2.8,"test-macosx1500-aarch64/opt-mochitest-browser-a11y":6.5,"test-macosx1500-aarch64/opt-mochitest-browser-chrome":20.4,"test-macosx1500-aarch64/opt-mochitest-browser-chrome-no-nv":20.2,"test-macosx1500-aarch64/opt-mochitest-browser-chrome-no-nv-vt":5.6,"test-macosx1500-aarch64/opt-mochitest-browser-chrome-trainhop-beta":2.2,"test-macosx1500-aarch64/opt-mochitest-browser-chrome-trainhop-rel":2.1,"test-macosx1500-aarch64/opt-mochitest-browser-chrome-uipc":21.2,"test-macosx1500-aarch64/opt-mochitest-browser-chrome-vt":5.5,"test-macosx1500-aarch64/opt-mochitest-browser-media":2.7,"test-macosx1500-aarch64/opt-mochitest-browser-translations":10.1,"test-macosx1500-aarch64/opt-mochitest-chrome-1proc":16.6,"test-macosx1500-aarch64/opt-mochitest-chrome-no-nv":18.5,"test-macosx1500-aarch64/opt-mochitest-devtools-chrome":22.7,"test-macosx1500-aarch64/opt-mochitest-media-mda-gpu":16.3,"test-macosx1500-aarch64/opt-mochitest-plain":19.7,"test-macosx1500-aarch64/opt-mochitest-plain-gpu":0.9,"test-macosx1500-aarch64/opt-mochitest-plain-xorig":20.2,"test-macosx1500-aarch64/opt-mochitest-webgl1-core":1.1,"test-macosx1500-aarch64/opt-mochitest-webgl1-ext":3.3,"test-macosx1500-aarch64/opt-mochitest-webgl2-core":2.7,"test-macosx1500-aarch64/opt-reftest":16.9,"test-macosx1500-aarch64/opt-reftest-nogpu":16.0,"test-macosx1500-aarch64/opt-test-verify":12.5,"test-macosx1500-aarch64/opt-test-verify-wpt":1.2,"test-macosx1500-aarch64/opt-web-platform-tests":21.9,"test-macosx1500-aarch64/opt-web-platform-tests-canvas":3.7,"test-macosx1500-aarch64/opt-web-platform-tests-crashtest":5.3,"test-macosx1500-aarch64/opt-web-platform-tests-pb":1.4,"test-macosx1500-aarch64/opt-web-platform-tests-print-reftest":23.5,"test-macosx1500-aarch64/opt-web-platform-tests-reftest":7.9,"test-macosx1500-aarch64/opt-web-platform-tests-wdspec":25.1,"test-macosx1500-aarch64/opt-web-platform-tests-wdspec-headless":22.9,"test-macosx1500-aarch64/opt-web-platform-tests-webcodecs":1.8,"test-macosx1500-aarch64/opt-web-platform-tests-webrtc":10.2,"test-macosx1500-aarch64/opt-xpcshell":12.7,"test-windows10-64-2009-qr/debug-cppunittest-1proc":2.7,"test-windows10-64-2009-qr/debug-gtest-1proc":25.7,"test-windows10-64-2009-qr/debug-mochitest-chrome-1proc":24.2,"test-windows10-64-2009-qr/debug-mochitest-chrome-gpu-1proc":1.9,"test-windows10-64-2009-qr/debug-mochitest-plain":22.4,"test-windows10-64-2009-qr/debug-mochitest-plain-gpu":2.2,"test-windows10-64-2009-qr/debug-xpcshell":26.7,"test-windows10-64-2009-qr/opt-gtest-1proc":24.4,"test-windows10-64-2009-qr/opt-mochitest-chrome-1proc":22.4,"test-windows10-64-2009-qr/opt-mochitest-chrome-gpu-1proc":1.4,"test-windows10-64-2009-qr/opt-mochitest-plain":22.9,"test-windows10-64-2009-qr/opt-mochitest-plain-gpu":1.5,"test-windows10-64-2009-qr/opt-xpcshell":17.7,"test-windows10-64-2009-shippable-qr/opt-cppunittest-1proc":1.3,"test-windows10-64-2009-shippable-qr/opt-gtest-1proc":23.3,"test-windows10-64-2009-shippable-qr/opt-mochitest-chrome-1proc":22.7,"test-windows10-64-2009-shippable-qr/opt-mochitest-plain":22.3,"test-windows11-32-25h2-shippable/opt-cppunittest-1proc":0.9,"test-windows11-32-25h2-shippable/opt-crashtest":7.5,"test-windows11-32-25h2-shippable/opt-gtest-1proc":19.1,"test-windows11-32-25h2-shippable/opt-marionette-integration":19.2,"test-windows11-32-25h2-shippable/opt-marionette-unittest":7.2,"test-windows11-32-25h2-shippable/opt-mochitest-browser-chrome":22.3,"test-windows11-32-25h2-shippable/opt-mochitest-browser-media":5.6,"test-windows11-32-25h2-shippable/opt-mochitest-chrome-1proc":23.3,"test-windows11-32-25h2-shippable/opt-mochitest-media":24.2,"test-windows11-32-25h2-shippable/opt-mochitest-media-nogpu":24.7,"test-windows11-32-25h2-shippable/opt-mochitest-media-spi":27.4,"test-windows11-32-25h2-shippable/opt-mochitest-media-wmfme":10.7,"test-windows11-32-25h2-shippable/opt-reftest":19.3,"test-windows11-32-25h2-shippable/opt-reftest-wr-dc0":18.6,"test-windows11-32-25h2-shippable/opt-reftest-wr-dc1-p":19.1,"test-windows11-32-25h2-shippable/opt-reftest-wr-dc2-o":19.2,"test-windows11-32-25h2-shippable/opt-reftest-wr-dc3-c":22.2,"test-windows11-32-25h2-shippable/opt-web-platform-tests":23.7,"test-windows11-32-25h2-shippable/opt-web-platform-tests-pb":3.2,"test-windows11-32-25h2/debug-cppunittest-1proc":1.3,"test-windows11-32-25h2/debug-crashtest":10.5,"test-windows11-32-25h2/debug-firefox-ui-functional":1.7,"test-windows11-32-25h2/debug-gtest-1proc":19.2,"test-windows11-32-25h2/debug-jsreftest":15.2,"test-windows11-32-25h2/debug-marionette-integration":17.3,"test-windows11-32-25h2/debug-marionette-integration-swr":9.1,"test-windows11-32-25h2/debug-marionette-unittest":10.6,"test-windows11-32-25h2/debug-marionette-unittest-swr":10.0,"test-windows11-32-25h2/debug-mochitest-a11y-1proc":7.2,"test-windows11-32-25h2/debug-mochitest-browser-a11y":16.1,"test-windows11-32-25h2/debug-mochitest-browser-chrome":22.0,"test-windows11-32-25h2/debug-mochitest-browser-chrome-standalone":20.2,"test-windows11-32-25h2/debug-mochitest-browser-media":6.3,"test-windows11-32-25h2/debug-mochitest-browser-media-wmfme":2.9,"test-windows11-32-25h2/debug-mochitest-chrome-1proc":20.6,"test-windows11-32-25h2/debug-mochitest-chrome-standalone":19.7,"test-windows11-32-25h2/debug-mochitest-media":19.4,"test-windows11-32-25h2/debug-mochitest-media-nogpu":19.3,"test-windows11-32-25h2/debug-mochitest-media-spi":19.4,"test-windows11-32-25h2/debug-mochitest-media-wmfme":10.6,"test-windows11-32-25h2/debug-reftest":21.9,"test-windows11-32-25h2/debug-reftest-wr-dc0":21.2,"test-windows11-32-25h2/debug-reftest-wr-dc1-p":21.3,"test-windows11-32-25h2/debug-reftest-wr-dc2-o":21.4,"test-windows11-32-25h2/debug-reftest-wr-dc3-c":23.5,"test-windows11-32-25h2/debug-test-verify":33.4,"test-windows11-32-25h2/debug-test-verify-wpt":2.6,"test-windows11-32-25h2/debug-web-platform-tests":24.6,"test-windows11-32-25h2/debug-web-platform-tests-crashtest":3.9,"test-windows11-32-25h2/debug-web-platform-tests-pb":3.1,"test-windows11-32-25h2/debug-xpcshell":15.2,"test-windows11-32-25h2/opt-crashtest":5.4,"test-windows11-32-25h2/opt-firefox-ui-functional":1.9,"test-windows11-32-25h2/opt-gtest-1proc":18.8,"test-windows11-32-25h2/opt-jsreftest":11.1,"test-windows11-32-25h2/opt-marionette-integration":8.7,"test-windows11-32-25h2/opt-marionette-unittest":6.5,"test-windows11-32-25h2/opt-mochitest-a11y-1proc":4.2,"test-windows11-32-25h2/opt-mochitest-browser-a11y":8.3,"test-windows11-32-25h2/opt-mochitest-browser-chrome":22.0,"test-windows11-32-25h2/opt-mochitest-browser-media":3.1,"test-windows11-32-25h2/opt-mochitest-browser-media-wmfme":2.2,"test-windows11-32-25h2/opt-mochitest-chrome-1proc":21.6,"test-windows11-32-25h2/opt-mochitest-media":25.1,"test-windows11-32-25h2/opt-mochitest-media-nogpu":23.8,"test-windows11-32-25h2/opt-mochitest-media-spi":27.4,"test-windows11-32-25h2/opt-mochitest-media-wmfme":8.2,"test-windows11-32-25h2/opt-reftest":19.9,"test-windows11-32-25h2/opt-reftest-wr-dc0":19.5,"test-windows11-32-25h2/opt-reftest-wr-dc1-p":20.1,"test-windows11-32-25h2/opt-reftest-wr-dc2-o":20.0,"test-windows11-32-25h2/opt-reftest-wr-dc3-c":22.7,"test-windows11-32-25h2/opt-test-verify":6.9,"test-windows11-32-25h2/opt-test-verify-wpt":2.2,"test-windows11-32-25h2/opt-web-platform-tests":7.2,"test-windows11-32-25h2/opt-web-platform-tests-crashtest":2.9,"test-windows11-32-25h2/opt-web-platform-tests-pb":2.7,"test-windows11-32-25h2/opt-xpcshell":10.7,"test-windows11-64-24h2-asan/opt-crashtest":12.9,"test-windows11-64-24h2-asan/opt-crashtest-swr":11.8,"test-windows11-64-24h2-asan/opt-jsreftest":13.1,"test-windows11-64-24h2-asan/opt-reftest":22.8,"test-windows11-64-24h2-asan/opt-reftest-swr":20.5,"test-windows11-64-24h2-asan/opt-reftest-wr-dc0":22.4,"test-windows11-64-24h2-asan/opt-reftest-wr-dc1-p":22.8,"test-windows11-64-24h2-asan/opt-reftest-wr-dc2-o":22.8,"test-windows11-64-24h2-asan/opt-reftest-wr-dc3-c":21.0,"test-windows11-64-24h2-hw-ref-shippable/opt-browsertime-benchmark-chrome-speedometer3":12.8,"test-windows11-64-24h2-hw-ref-shippable/opt-browsertime-benchmark-firefox-speedometer3":13.5,"test-windows11-64-24h2-hw-ref-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling":30.3,"test-windows11-64-24h2-hw-ref-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling-no-nv":30.1,"test-windows11-64-24h2-hw-ref-shippable/opt-browsertime-benchmark-firefox-speedometer3-no-nv":13.6,"test-windows11-64-24h2-hw-ref-shippable/opt-browsertime-nav-bench-firefox-nav-bench":71.0,"test-windows11-64-24h2-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3":9.6,"test-windows11-64-24h2-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3-native-profiling":29.1,"test-windows11-64-24h2-nightlyasrelease/opt-browsertime-benchmark-firefox-speedometer3-no-nv":10.8,"test-windows11-64-24h2-shippable/opt-browsertime-benchmark-chrome-speedometer3":8.0,"test-windows11-64-24h2-shippable/opt-browsertime-benchmark-chrome-speedometer3-native-profiling":19.1,"test-windows11-64-24h2-shippable/opt-browsertime-benchmark-custom-car-speedometer3":9.4,"test-windows11-64-24h2-shippable/opt-browsertime-benchmark-firefox-jetstream3":5.8,"test-windows11-64-24h2-shippable/opt-browsertime-benchmark-firefox-speedometer3":11.0,"test-windows11-64-24h2-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling":27.4,"test-windows11-64-24h2-shippable/opt-browsertime-benchmark-firefox-speedometer3-native-profiling-no-nv":27.2,"test-windows11-64-24h2-shippable/opt-browsertime-benchmark-firefox-speedometer3-no-nv":10.3,"test-windows11-64-24h2-shippable/opt-browsertime-nav-bench-firefox-nav-bench":57.9,"test-windows11-64-24h2-shippable/opt-browsertime-responsiveness-firefox-reddit-billgates-post":11.2,"test-windows11-64-24h2-shippable/opt-crashtest":7.3,"test-windows11-64-24h2-shippable/opt-reftest":18.6,"test-windows11-64-24h2-shippable/opt-reftest-wr-dc0":18.2,"test-windows11-64-24h2-shippable/opt-reftest-wr-dc1-p":18.7,"test-windows11-64-24h2-shippable/opt-reftest-wr-dc2-o":18.4,"test-windows11-64-24h2-shippable/opt-reftest-wr-dc3-c":20.6,"test-windows11-64-24h2/debug-crashtest":10.8,"test-windows11-64-24h2/debug-crashtest-swr":10.2,"test-windows11-64-24h2/debug-jsreftest":14.6,"test-windows11-64-24h2/debug-reftest":20.6,"test-windows11-64-24h2/debug-reftest-wr-dc0":20.4,"test-windows11-64-24h2/debug-reftest-wr-dc1-p":20.4,"test-windows11-64-24h2/debug-reftest-wr-dc2-o":20.4,"test-windows11-64-24h2/debug-reftest-wr-dc3-c":22.6,"test-windows11-64-24h2/opt-jsreftest":10.5,"test-windows11-64-24h2/opt-reftest":19.4,"test-windows11-64-24h2/opt-reftest-wr-dc0":19.2,"test-windows11-64-24h2/opt-reftest-wr-dc1-p":19.4,"test-windows11-64-24h2/opt-reftest-wr-dc2-o":18.9,"test-windows11-64-24h2/opt-reftest-wr-dc3-c":21.9,"test-windows11-64-25h2-asan/opt-cppunittest-1proc":1.2,"test-windows11-64-25h2-asan/opt-gtest-1proc":38.6,"test-windows11-64-25h2-asan/opt-marionette-integration":20.5,"test-windows11-64-25h2-asan/opt-marionette-unittest":13.9,"test-windows11-64-25h2-asan/opt-mochitest-a11y-1proc":15.7,"test-windows11-64-25h2-asan/opt-mochitest-browser-a11y":16.4,"test-windows11-64-25h2-asan/opt-mochitest-browser-chrome":21.3,"test-windows11-64-25h2-asan/opt-mochitest-browser-media":11.8,"test-windows11-64-25h2-asan/opt-mochitest-browser-media-wmfme":3.8,"test-windows11-64-25h2-asan/opt-mochitest-chrome-1proc":20.9,"test-windows11-64-25h2-asan/opt-mochitest-chrome-gpu-1proc":2.4,"test-windows11-64-25h2-asan/opt-mochitest-devtools-chrome":21.4,"test-windows11-64-25h2-asan/opt-mochitest-media":20.7,"test-windows11-64-25h2-asan/opt-mochitest-media-nogpu":21.0,"test-windows11-64-25h2-asan/opt-mochitest-media-wmfme":13.4,"test-windows11-64-25h2-asan/opt-mochitest-plain":21.9,"test-windows11-64-25h2-asan/opt-mochitest-plain-gpu":2.7,"test-windows11-64-25h2-asan/opt-mochitest-remote":8.5,"test-windows11-64-25h2-asan/opt-mochitest-webgl1-core":14.3,"test-windows11-64-25h2-asan/opt-mochitest-webgl1-ext":22.2,"test-windows11-64-25h2-asan/opt-mochitest-webgl2-core":18.3,"test-windows11-64-25h2-asan/opt-mochitest-webgl2-ext":20.5,"test-windows11-64-25h2-asan/opt-telemetry-tests-client":2.4,"test-windows11-64-25h2-devedition/opt-mochitest-browser-chrome":21.5,"test-windows11-64-25h2-devedition/opt-mochitest-devtools-chrome":23.5,"test-windows11-64-25h2-shippable/opt-awsy-base":4.3,"test-windows11-64-25h2-shippable/opt-awsy-tp6":11.9,"test-windows11-64-25h2-shippable/opt-cppunittest-1proc":1.2,"test-windows11-64-25h2-shippable/opt-gtest-1proc":16.5,"test-windows11-64-25h2-shippable/opt-marionette-unittest":6.2,"test-windows11-64-25h2-shippable/opt-mochitest-a11y-1proc":4.4,"test-windows11-64-25h2-shippable/opt-mochitest-browser-a11y":8.9,"test-windows11-64-25h2-shippable/opt-mochitest-browser-chrome":21.8,"test-windows11-64-25h2-shippable/opt-mochitest-browser-chrome-ml-models":1.5,"test-windows11-64-25h2-shippable/opt-mochitest-browser-chrome-msix":23.2,"test-windows11-64-25h2-shippable/opt-mochitest-browser-translations":10.1,"test-windows11-64-25h2-shippable/opt-mochitest-chrome-1proc":21.1,"test-windows11-64-25h2-shippable/opt-mochitest-devtools-chrome":23.9,"test-windows11-64-25h2-shippable/opt-mochitest-media":24.1,"test-windows11-64-25h2-shippable/opt-mochitest-media-msix":24.6,"test-windows11-64-25h2-shippable/opt-mochitest-media-nogpu":18.3,"test-windows11-64-25h2-shippable/opt-mochitest-media-spi":23.9,"test-windows11-64-25h2-shippable/opt-mochitest-media-wmfme":10.7,"test-windows11-64-25h2-shippable/opt-mochitest-plain":21.5,"test-windows11-64-25h2-shippable/opt-mochitest-webgl1-core":5.0,"test-windows11-64-25h2-shippable/opt-telemetry-tests-client":1.1,"test-windows11-64-25h2-shippable/opt-web-platform-tests":24.6,"test-windows11-64-25h2-shippable/opt-web-platform-tests-backlog":27.8,"test-windows11-64-25h2-shippable/opt-web-platform-tests-crashtest":24.6,"test-windows11-64-25h2-shippable/opt-web-platform-tests-reftest":25.2,"test-windows11-64-25h2-shippable/opt-web-platform-tests-wdspec":19.2,"test-windows11-64-25h2-shippable/opt-web-platform-tests-wdspec-headless":26.0,"test-windows11-64-25h2-shippable/opt-web-platform-tests-webcodecs":3.9,"test-windows11-64-25h2/debug-cppunittest-1proc":1.5,"test-windows11-64-25h2/debug-gtest-1proc":17.5,"test-windows11-64-25h2/debug-marionette-integration":16.8,"test-windows11-64-25h2/debug-marionette-integration-swr":3.3,"test-windows11-64-25h2/debug-marionette-unittest":10.6,"test-windows11-64-25h2/debug-marionette-unittest-swr":10.4,"test-windows11-64-25h2/debug-mochitest-a11y-1proc":7.0,"test-windows11-64-25h2/debug-mochitest-browser-a11y":14.9,"test-windows11-64-25h2/debug-mochitest-browser-chrome":21.5,"test-windows11-64-25h2/debug-mochitest-browser-chrome-msix":21.8,"test-windows11-64-25h2/debug-mochitest-browser-chrome-standalone":21.1,"test-windows11-64-25h2/debug-mochitest-browser-chrome-vt":10.6,"test-windows11-64-25h2/debug-mochitest-browser-media":5.4,"test-windows11-64-25h2/debug-mochitest-browser-media-wmfme":2.8,"test-windows11-64-25h2/debug-mochitest-browser-translations":15.4,"test-windows11-64-25h2/debug-mochitest-chrome-1proc":20.3,"test-windows11-64-25h2/debug-mochitest-chrome-gpu-1proc":2.1,"test-windows11-64-25h2/debug-mochitest-chrome-standalone":21.7,"test-windows11-64-25h2/debug-mochitest-devtools-chrome":22.3,"test-windows11-64-25h2/debug-mochitest-devtools-chrome-standalone":21.5,"test-windows11-64-25h2/debug-mochitest-media":19.0,"test-windows11-64-25h2/debug-mochitest-media-msix":36.2,"test-windows11-64-25h2/debug-mochitest-media-nogpu":19.2,"test-windows11-64-25h2/debug-mochitest-media-spi":19.3,"test-windows11-64-25h2/debug-mochitest-media-wmfme":10.9,"test-windows11-64-25h2/debug-mochitest-plain":21.1,"test-windows11-64-25h2/debug-mochitest-plain-gpu":2.2,"test-windows11-64-25h2/debug-mochitest-plain-standalone":21.1,"test-windows11-64-25h2/debug-mochitest-remote":5.2,"test-windows11-64-25h2/debug-mochitest-webgl1-core":9.0,"test-windows11-64-25h2/debug-mochitest-webgl1-ext":13.1,"test-windows11-64-25h2/debug-mochitest-webgl2-core":12.8,"test-windows11-64-25h2/debug-mochitest-webgl2-ext":20.7,"test-windows11-64-25h2/debug-mochitest-webgpu":2.7,"test-windows11-64-25h2/debug-telemetry-tests-client":1.9,"test-windows11-64-25h2/debug-test-verify":5.8,"test-windows11-64-25h2/debug-test-verify-wpt":2.4,"test-windows11-64-25h2/debug-web-platform-tests":24.5,"test-windows11-64-25h2/debug-web-platform-tests-canvas":19.5,"test-windows11-64-25h2/debug-web-platform-tests-crashtest":3.8,"test-windows11-64-25h2/debug-web-platform-tests-crashtest-swr":3.5,"test-windows11-64-25h2/debug-web-platform-tests-eme-emewmf":11.1,"test-windows11-64-25h2/debug-web-platform-tests-pb":3.0,"test-windows11-64-25h2/debug-web-platform-tests-print-reftest":27.1,"test-windows11-64-25h2/debug-web-platform-tests-print-reftest-swr":15.6,"test-windows11-64-25h2/debug-web-platform-tests-reftest":15.0,"test-windows11-64-25h2/debug-web-platform-tests-reftest-swr":22.0,"test-windows11-64-25h2/debug-web-platform-tests-wdspec":22.0,"test-windows11-64-25h2/debug-web-platform-tests-wdspec-headless":23.2,"test-windows11-64-25h2/debug-web-platform-tests-webcodecs":4.8,"test-windows11-64-25h2/debug-web-platform-tests-webcodecs-openh264":7.3,"test-windows11-64-25h2/debug-web-platform-tests-webcodecs-openh264-cisco":7.6,"test-windows11-64-25h2/debug-web-platform-tests-webgpu":25.6,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog":10.8,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-backlog-long":36.0,"test-windows11-64-25h2/debug-web-platform-tests-webgpu-long":37.3,"test-windows11-64-25h2/debug-web-platform-tests-webrtc":20.5,"test-windows11-64-25h2/debug-web-platform-tests-webrtc-openh264":20.6,"test-windows11-64-25h2/debug-web-platform-tests-webrtc-openh264-cisco":20.8,"test-windows11-64-25h2/debug-xpcshell":15.1,"test-windows11-64-25h2/debug-xpcshell-msix":10.7,"test-windows11-64-25h2/opt-gtest-1proc":16.7,"test-windows11-64-25h2/opt-marionette-integration":5.8,"test-windows11-64-25h2/opt-marionette-unittest":6.2,"test-windows11-64-25h2/opt-mochitest-a11y-1proc":4.1,"test-windows11-64-25h2/opt-mochitest-browser-a11y":3.5,"test-windows11-64-25h2/opt-mochitest-browser-chrome":21.6,"test-windows11-64-25h2/opt-mochitest-browser-chrome-msix":22.6,"test-windows11-64-25h2/opt-mochitest-browser-chrome-no-nv":21.8,"test-windows11-64-25h2/opt-mochitest-browser-chrome-no-nv-vt":6.9,"test-windows11-64-25h2/opt-mochitest-browser-chrome-standalone":20.8,"test-windows11-64-25h2/opt-mochitest-browser-chrome-trainhop-beta":2.4,"test-windows11-64-25h2/opt-mochitest-browser-chrome-trainhop-rel":2.4,"test-windows11-64-25h2/opt-mochitest-browser-chrome-uipc":19.1,"test-windows11-64-25h2/opt-mochitest-browser-chrome-vt":6.8,"test-windows11-64-25h2/opt-mochitest-browser-media":3.1,"test-windows11-64-25h2/opt-mochitest-browser-media-wmfme":2.1,"test-windows11-64-25h2/opt-mochitest-browser-translations":9.8,"test-windows11-64-25h2/opt-mochitest-chrome-1proc":22.1,"test-windows11-64-25h2/opt-mochitest-chrome-gpu-1proc":1.5,"test-windows11-64-25h2/opt-mochitest-chrome-no-nv":20.4,"test-windows11-64-25h2/opt-mochitest-chrome-standalone":20.4,"test-windows11-64-25h2/opt-mochitest-devtools-chrome":24.5,"test-windows11-64-25h2/opt-mochitest-devtools-chrome-standalone":23.6,"test-windows11-64-25h2/opt-mochitest-media":24.4,"test-windows11-64-25h2/opt-mochitest-media-msix":25.1,"test-windows11-64-25h2/opt-mochitest-media-nogpu":18.9,"test-windows11-64-25h2/opt-mochitest-media-spi":19.4,"test-windows11-64-25h2/opt-mochitest-media-wmfme":8.1,"test-windows11-64-25h2/opt-mochitest-plain":21.5,"test-windows11-64-25h2/opt-mochitest-plain-gpu":1.8,"test-windows11-64-25h2/opt-mochitest-plain-standalone":22.4,"test-windows11-64-25h2/opt-mochitest-remote":3.9,"test-windows11-64-25h2/opt-mochitest-webgl1-core":5.5,"test-windows11-64-25h2/opt-mochitest-webgl1-ext":7.5,"test-windows11-64-25h2/opt-mochitest-webgl2-ext":24.3,"test-windows11-64-25h2/opt-mochitest-webgpu":2.0,"test-windows11-64-25h2/opt-test-verify":3.7,"test-windows11-64-25h2/opt-test-verify-wpt":2.4,"test-windows11-64-25h2/opt-web-platform-tests":7.4,"test-windows11-64-25h2/opt-web-platform-tests-canvas":8.9,"test-windows11-64-25h2/opt-web-platform-tests-crashtest":3.0,"test-windows11-64-25h2/opt-web-platform-tests-eme-emewmf":6.9,"test-windows11-64-25h2/opt-web-platform-tests-pb":2.8,"test-windows11-64-25h2/opt-web-platform-tests-print-reftest":3.2,"test-windows11-64-25h2/opt-web-platform-tests-reftest":8.6,"test-windows11-64-25h2/opt-web-platform-tests-wdspec":3.6,"test-windows11-64-25h2/opt-web-platform-tests-wdspec-headless":3.7,"test-windows11-64-25h2/opt-web-platform-tests-webcodecs":4.5,"test-windows11-64-25h2/opt-web-platform-tests-webgpu":20.5,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog":10.1,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-backlog-long":26.9,"test-windows11-64-25h2/opt-web-platform-tests-webgpu-long":37.3,"test-windows11-64-25h2/opt-web-platform-tests-webrtc":10.0,"test-windows11-64-25h2/opt-xpcshell":10.6,"test-windows11-64-25h2/opt-xpcshell-condprof":3.1,"test-windows11-64-25h2/opt-xpcshell-msix":6.7,"test-windows11-aarch64-25h2/debug-cppunittest-1proc":3.5,"toolchain-linux32-llvm-symbolizer":5.0,"toolchain-linux64-aarch64-clang-tidy":17.5,"toolchain-linux64-aarch64-webspec-index":5.2,"toolchain-linux64-android-gradle-dependencies":13.1,"toolchain-linux64-breakpad-injector":4.2,"toolchain-linux64-clang":2.3,"toolchain-linux64-clang-22-mingw-x64":5.4,"toolchain-linux64-clang-22-mingw-x86":3.8,"toolchain-linux64-clang-tidy":18.5,"toolchain-linux64-clang-tidy-external":18.6,"toolchain-linux64-clang-trunk-stage1":3.7,"toolchain-linux64-gcc":26.9,"toolchain-linux64-llvm-symbolizer":5.2,"toolchain-linux64-mar-tools":1.9,"toolchain-linux64-mingw-fxc2-x86":3.7,"toolchain-linux64-mingw32-nsis":3.3,"toolchain-linux64-node":3.8,"toolchain-linux64-zucchini-bin":3.4,"toolchain-macosx64-aarch64-clang-tidy":21.4,"toolchain-macosx64-aarch64-llvm-symbolizer":6.0,"toolchain-macosx64-clang-tidy":20.6,"toolchain-macosx64-llvm-symbolizer":6.0,"toolchain-onnxruntime-aarch64-apple-darwin":16.0,"toolchain-onnxruntime-aarch64-linux-android":5.3,"toolchain-onnxruntime-arm-linux-androideabi":6.5,"toolchain-onnxruntime-i686-windows-msvc":15.3,"toolchain-onnxruntime-x86_64-apple-darwin":16.1,"toolchain-onnxruntime-x86_64-linux-android":6.8,"toolchain-onnxruntime-x86_64-linux-gnu":8.1,"toolchain-onnxruntime-x86_64-windows-msvc":17.6,"toolchain-sysroot-wasm32-wasi-clang":1.2,"toolchain-wasm32-wasi-compiler-rt":2.4,"toolchain-win64-aarch64-clang-tidy":20.6,"toolchain-win64-clang":2.9,"toolchain-win64-clang-22-profile":30.0,"toolchain-win64-clang-22-raw":12.8,"toolchain-win64-clang-22-stage2":7.0,"toolchain-win64-clang-tidy":20.4,"toolchain-win64-cmake":7.2,"toolchain-win64-llvm-symbolizer":6.3,"toolchain-win64-nasm":2.2,"toolchain-win64-rust-1.95-dev":49.2,"toolchain-win64-upx":15.0,"ui-test-apk-fenix-arm-beta":6.2,"ui-test-apk-fenix-arm-debug":10.0,"ui-test-apk-fenix-arm-debug-smoke":4.4,"ui-test-apk-fenix-tae-arm-debug":10.8,"ui-test-apk-fenix-tae-behavior-arm-debug":4.0,"ui-test-apk-fenix-tae-interaction-arm-debug":3.4,"ui-test-apk-fenix-tae-reachability-arm-debug":6.8,"ui-test-apk-focus-arm-beta":5.6,"ui-test-apk-focus-arm-debug":5.2,"upload-generated-sources-android-aarch64-shippable/opt":2.3,"upload-generated-sources-android-x86_64-shippable-lite/opt":4.5,"upload-generated-sources-linux64-aarch64-shippable/opt":4.5,"upload-generated-sources-win32-devedition/opt":3.0,"upload-generated-sources-win64-devedition/opt":1.8,"webrender-android-emulator-debug":8.7,"webrender-android-emulator-release":7.8,"webrender-android-hw-p6-opt":2.7,"webrender-cargotest-macos-build":7.4,"webrender-linux64-debug":14.3,"webrender-linux64-release":11.7,"webrender-macos-debug":2.7,"webrender-macos-release":4.1,"webrender-windows":20.0,"webrender-wrench-android-debug":6.9,"webrender-wrench-android-release":9.7,"webrender-wrench-macos-build":9.8},"generated":"2026-08-26","global":20.8,"jobsSampled":69654,"platform":{"AC-android-all|opt":13.6,"AC-ui-test|opt":24.6,"android-5-0-aarch64-shippable|opt":24.4,"android-5-0-aarch64|debug":39.3,"android-5-0-aarch64|opt":16.2,"android-5-0-armv7-shippable|opt":24.0,"android-5-0-armv7|debug":40.8,"android-5-0-armv7|opt":15.5,"android-5-0-geckoview-fat-aar-shippable|opt":8.1,"android-5-0-geckoview-fat-aar|opt":6.2,"android-5-0-x86_64-shippable|opt":27.0,"android-5-0-x86_64|asan":25.2,"android-5-0-x86_64|debug":19.0,"android-5-0-x86_64|opt":17.6,"android-aarch64-shippable|opt":29.1,"android-armv7-shippable|opt":32.1,"android-em-14-x86_64-lite|opt":12.2,"android-em-14-x86_64-shippable-lite|opt":26.3,"android-em-14-x86_64-shippable|opt":26.6,"android-em-14-x86_64|debug":24.1,"android-em-14-x86_64|debug-isolated-process":23.6,"android-em-14-x86_64|opt":22.0,"android-hw-a55-14-0-aarch64-shippable|opt":12.1,"android-hw-a55-14-0-aarch64|opt":19.9,"android-hw-p6-13-0-aarch64-shippable|opt":13.6,"android-hw-p6-13-0-aarch64|opt":2.7,"android-hw-s24-14-0-aarch64-shippable|opt":12.8,"android-x86_64-shippable|opt":21.2,"diff|opt":1.1,"doc|opt":8.8,"fenix-android-all|opt":10.7,"fetch|opt":0.2,"focus-android-all|opt":8.6,"gecko-decision|opt":2.2,"ios|debug":28.1,"ios|opt":24.4,"ios|plain":32.6,"lint|opt":3.9,"linux2204-64-wayland-shippable|opt":12.3,"linux2204-64-wayland|debug":21.7,"linux2204-64-wayland|opt":12.8,"linux2404-64-asan|opt":22.0,"linux2404-64-ccov|opt":5.9,"linux2404-64-devedition|opt":22.6,"linux2404-64-nightlyasrelease|opt":10.7,"linux2404-64-shippable|opt":10.9,"linux2404-64-tsan|opt":21.9,"linux2404-64|debug":22.4,"linux2404-64|opt":22.6,"linux32|debug":43.4,"linux32|opt":26.1,"linux64-aarch64-devedition|opt":5.9,"linux64-aarch64-shippable|opt":6.2,"linux64-aarch64|debug":11.3,"linux64-aarch64|opt":11.6,"linux64-add-on-devel|opt":38.1,"linux64-ccov|debug":65.0,"linux64-ccov|opt":58.9,"linux64-devedition|opt":5.6,"linux64-nightlyasrelease|opt":26.7,"linux64-noopt|asan":33.9,"linux64-noopt|debug":34.3,"linux64-qr|debug":14.3,"linux64-qr|opt":11.7,"linux64-shippable|opt":18.0,"linux64-snap|debug":32.3,"linux64-snap|opt":31.2,"linux64|asan":36.0,"linux64|debug":21.4,"linux64|opt":12.0,"linux64|plain":50.8,"linux64|tsan":13.1,"macosx1015-64-qr|debug":20.3,"macosx1015-64-qr|opt":19.4,"macosx1015-64-shippable-qr|opt":20.2,"macosx1015-64-shippable|opt":18.6,"macosx1470-64-nightlyasrelease|opt":4.0,"macosx1470-64-shippable|opt":12.0,"macosx1470-64|debug":30.1,"macosx1470-64|opt":17.7,"macosx1500-aarch64-devedition|opt":21.3,"macosx1500-aarch64-nightlyasrelease|opt":3.1,"macosx1500-aarch64-shippable|opt":7.6,"macosx1500-aarch64-vms-shippable|opt":13.9,"macosx1500-aarch64-vms|debug":19.3,"macosx1500-aarch64-vms|opt":17.0,"macosx1500-aarch64|debug":21.4,"macosx1500-aarch64|opt":19.9,"macosx64-aarch64|opt":3.9,"macosx64|opt":5.9,"osx-aarch64-devedition|opt":58.4,"osx-aarch64-nightlyasrelease|opt":42.8,"osx-aarch64-shippable|opt":16.4,"osx-cross-aarch64-add-on-devel|opt":40.5,"osx-cross-aarch64|asan":36.4,"osx-cross-aarch64|debug":6.9,"osx-cross-aarch64|opt":4.9,"osx-cross-add-on-devel|opt":23.8,"osx-cross-devedition|opt":11.9,"osx-cross-noopt|debug":34.0,"osx-cross|asan":33.6,"osx-cross|debug":17.1,"osx-cross|opt":6.7,"osx-cross|plain":31.9,"osx-nightlyasrelease|opt":58.3,"osx-shippable|opt":13.8,"osx|debug":97.8,"osx|opt":82.7,"packages|opt":1.4,"taskcluster-images|opt":1.3,"toolchains|opt":5.0,"win32|opt":4.2,"win64-nightlyasrelease|opt":31.5,"win64|opt":2.3,"windows-mingw32|all":31.5,"windows10-64-2009-qr|debug":23.5,"windows10-64-2009-qr|opt":22.6,"windows10-64-2009-shippable-qr|opt":22.4,"windows11-32-25h2-shippable|opt":22.2,"windows11-32-25h2|debug":21.4,"windows11-32-25h2|opt":20.2,"windows11-64-24h2-hw-ref-shippable|opt":13.7,"windows11-64-24h2-nightlyasrelease|opt":9.5,"windows11-64-24h2-shippable|opt":6.6,"windows11-64-24h2|debug":20.4,"windows11-64-24h2|opt":19.3,"windows11-64-24h2|release":20.0,"windows11-64-25h2-devedition|opt":21.9,"windows11-64-25h2-shippable|opt":23.8,"windows11-64-25h2|asan":21.3,"windows11-64-25h2|debug":21.2,"windows11-64-25h2|opt":20.7,"windows11-64|opt":17.4,"windows2012-32-add-on-devel|opt":43.9,"windows2012-32-devedition|opt":1.6,"windows2012-32-noopt|debug":40.0,"windows2012-32-shippable|opt":18.6,"windows2012-32|debug":12.4,"windows2012-32|opt":4.8,"windows2012-64-add-on-devel|opt":45.8,"windows2012-64-devedition|opt":3.1,"windows2012-64-noopt|debug":38.8,"windows2012-64-shippable|opt":23.7,"windows2012-64|asan":35.5,"windows2012-64|ccov":73.1,"windows2012-64|debug":8.3,"windows2012-64|opt":2.7,"windows2012-aarch64-devedition|opt":3.9,"windows2012-aarch64-shippable|opt":19.2,"windows2012-aarch64|debug":35.8,"windows2012-aarch64|opt":6.8}} \ No newline at end of file diff --git a/BuildWatch/Services/TreeHerderService.swift b/BuildWatch/Services/TreeHerderService.swift index 83d4a0a..5c02c6d 100644 --- a/BuildWatch/Services/TreeHerderService.swift +++ b/BuildWatch/Services/TreeHerderService.swift @@ -129,13 +129,13 @@ nonisolated final class TreeHerderService: Sendable { /// Column offsets into TreeHerder's positional job rows, resolved once per response. /// - /// The response carries 37 columns; BuildWatch reads 14. Resolving them up front turns + /// The response carries 37 columns; BuildWatch reads 15. Resolving them up front turns /// the hot loop into plain integer indexing instead of one string hash per field per row - /// (~17k dictionary lookups on a 1,262-job push). + /// (~19k dictionary lookups on a 1,262-job push). private struct ColumnMap { let id, state, platform, platformOption: Int let jobTypeName, jobTypeSymbol, jobGroupName, jobGroupSymbol: Int - let result, startTimestamp, endTimestamp, tier: Int + let result, submitTimestamp, startTimestamp, endTimestamp, tier: Int let taskId, resultSetId, pushId, lastModified: Int init(_ names: [String]) { @@ -152,6 +152,7 @@ nonisolated final class TreeHerderService: Sendable { jobGroupName = at("job_group_name") jobGroupSymbol = at("job_group_symbol") result = at("result") + submitTimestamp = at("submit_timestamp") startTimestamp = at("start_timestamp") endTimestamp = at("end_timestamp") tier = at("tier") @@ -178,6 +179,11 @@ nonisolated final class TreeHerderService: Sendable { let count = row.count func str(_ i: Int) -> String? { i >= 0 && i < count ? row[i] as? String : nil } func int(_ i: Int) -> Int? { i >= 0 && i < count ? row[i] as? Int : nil } + // TreeHerder writes an *absent* timestamp as 0, not null. Left as 0 it decodes + // to a valid 1 January 1970, which makes an unstarted job look like one that + // started 56 years ago — so every queued job reads as already running, and the + // ETA's percentiles are computed over a pile of 1970 dates. + func stamp(_ i: Int) -> Int? { int(i).flatMap { $0 == 0 ? nil : $0 } } guard let id = int(col.id), @@ -201,10 +207,14 @@ nonisolated final class TreeHerderService: Sendable { jobTypeSymbol: str(col.jobTypeSymbol) ?? "", jobGroupName: str(col.jobGroupName) ?? "", jobGroupSymbol: str(col.jobGroupSymbol) ?? "", - state: JobState(rawValue: stateStr) ?? .completed, + // Defaulting an unrecognised state to `.pending` rather than `.completed`: + // guessing "done" on a state we don't model is what fires a completion + // notification early, and the watch is one-shot so no correction follows. + state: JobState(rawValue: stateStr) ?? .pending, result: JobResult(rawValue: str(col.result) ?? "") ?? .unknown, - startTimestamp: int(col.startTimestamp), - endTimestamp: int(col.endTimestamp), + submitTimestamp: stamp(col.submitTimestamp), + startTimestamp: stamp(col.startTimestamp), + endTimestamp: stamp(col.endTimestamp), tier: int(col.tier) ?? 1 )) } diff --git a/BuildWatch/ViewModels/DashboardViewModel.swift b/BuildWatch/ViewModels/DashboardViewModel.swift index 06d837b..f229066 100644 --- a/BuildWatch/ViewModels/DashboardViewModel.swift +++ b/BuildWatch/ViewModels/DashboardViewModel.swift @@ -254,7 +254,7 @@ final class DashboardViewModel { } jobsByPush[push.id] = merged - summaries[push.id] = PushSummary(jobs: merged) + summaries[push.id] = PushSummary(jobs: merged, pushedAt: push.date) if let mark = snapshot.latestModified { watermarks[push.id] = max(mark, watermarks[push.id] ?? mark) } diff --git a/BuildWatch/Views/DashboardView.swift b/BuildWatch/Views/DashboardView.swift index a04bebb..6b89a04 100644 --- a/BuildWatch/Views/DashboardView.swift +++ b/BuildWatch/Views/DashboardView.swift @@ -198,6 +198,18 @@ struct PushRowView: View { private func accessibilityLabel(_ summary: PushSummary?) -> String { var parts = [push.displayTitle, "by \(push.authorHandle)", push.date.timeAgo()] parts.append(summary?.accessibilityLabel ?? "jobs still loading") + if let eta = summary?.eta { + switch eta.confidence { + case .firm: + parts.append("most results in \(eta.mostResultsBy.timeIntervalSinceNow.etaSpoken)") + case .blockedOnBuild: + if let build = eta.blockingBuild { + parts.append("tests start in about \(build.releasesAt.timeIntervalSinceNow.etaSpoken)") + } + case .estimating: + break + } + } if viewModel.watchedPushIds.contains(push.id) { parts.append("watched") } return parts.joined(separator: ", ") } @@ -206,12 +218,22 @@ struct PushRowView: View { private func statusBadge(_ summary: PushSummary?) -> some View { if let summary { if summary.failureCount > 0 { + // A red push that is still running wants both numbers: the failure count + // and how long the rest of it has left. Previously the badge won and the + // ETA never appeared on exactly the pushes being watched most closely. Text("\(summary.failureCount)") .font(.caption2.weight(.bold)) .foregroundStyle(.white) .padding(.horizontal, 6) .padding(.vertical, 2) .background(StatusPalette.failed, in: Capsule()) + if let eta = summary.eta, eta.confidence != .estimating { + ETAPill(eta: eta) + } + } else if let eta = summary.eta, eta.confidence != .estimating { + // Once there is a real estimate the countdown says strictly more than a + // spinner does, in the same space. + ETAPill(eta: eta) } else if summary.isRunning { Image(systemName: "arrow.trianglehead.clockwise.rotate.90") .font(.caption) diff --git a/BuildWatch/Views/ETAView.swift b/BuildWatch/Views/ETAView.swift new file mode 100644 index 0000000..44c6d4f --- /dev/null +++ b/BuildWatch/Views/ETAView.swift @@ -0,0 +1,423 @@ +import SwiftUI + +// MARK: - Hero card + +/// The ETA, as the first thing you see on a push. +/// +/// Leads with the number that is actually reliable — when 90% of the jobs will be in — and +/// keeps the full finish as a softer secondary, because the last job is the one part of a +/// try push that genuinely cannot be pinned down. See `PushETA` for the measurements behind +/// that split. +struct PushETACard: View { + let eta: PushETA + let summary: PushSummary + + @Environment(\.accessibilityReduceMotion) private var reduceMotion + @ScaledMetric(relativeTo: .largeTitle) private var trackHeight: CGFloat = 10 + + var body: some View { + VStack(alignment: .leading, spacing: 14) { + switch eta.confidence { + case .firm: + headline + TimelineView(.periodic(from: .now, by: 15)) { context in + ETATimelineTrack( + eta: eta, + summary: summary, + now: context.date, + height: trackHeight, + animates: !reduceMotion + ) + } + footer + + case .blockedOnBuild: + // Show the build's finish, not the push's. The build's is sharp and the + // push's is not, and "nothing can start until this lands" is the actual + // answer to why the screen looks frozen. + if let build = eta.blockingBuild { buildHeadline(build) } + JobCountTrack(summary: summary, height: trackHeight, animates: !reduceMotion) + estimatingFooter + + case .estimating: + // No clock times anywhere in this branch. Showing a "most results by" + // marker while also saying "estimating" would be claiming the number we + // just declined to make. + estimatingHeadline + JobCountTrack(summary: summary, height: trackHeight, animates: !reduceMotion) + estimatingFooter + } + } + .padding(.vertical, 6) + .accessibilityElement(children: .ignore) + .accessibilityLabel(accessibilityLabel) + } + + // MARK: Headline + + private var headline: some View { + TimelineView(.periodic(from: .now, by: 5)) { context in + let remaining = eta.mostResultsBy.timeIntervalSince(context.date) + + VStack(alignment: .leading, spacing: 2) { + Text("MOST RESULTS IN") + .font(.caption2.weight(.semibold)) + .foregroundStyle(.secondary) + .tracking(0.6) + + HStack(alignment: .firstTextBaseline, spacing: 8) { + Text(remaining <= 30 ? "any moment" : remaining.etaCountdown) + .font(.system(.largeTitle, design: .rounded, weight: .semibold)) + .monospacedDigit() + .contentTransition(.numericText(countsDown: true)) + .foregroundStyle(StatusPalette.running) + + if remaining > 30 { + Text("by \(eta.mostResultsBy.clockTime)") + .font(.subheadline) + .foregroundStyle(.secondary) + } + } + } + .animation(reduceMotion ? nil : .easeInOut, value: Int(remaining / 60)) + } + } + + private func buildHeadline(_ build: PushETA.BlockingBuild) -> some View { + TimelineView(.periodic(from: .now, by: 5)) { context in + let remaining = build.releasesAt.timeIntervalSince(context.date) + VStack(alignment: .leading, spacing: 3) { + Text("TESTS START IN") + .font(.caption2.weight(.semibold)) + .foregroundStyle(.secondary) + .tracking(0.6) + + HStack(alignment: .firstTextBaseline, spacing: 8) { + Text(remaining <= 30 ? "any moment" : remaining.etaCountdown) + .font(.system(.title, design: .rounded, weight: .semibold)) + .monospacedDigit() + .contentTransition(.numericText(countsDown: true)) + .foregroundStyle(StatusPalette.busted) + Image(systemName: "hammer.fill") + .font(.caption) + .foregroundStyle(StatusPalette.busted.opacity(0.7)) + } + + Text("building · \(build.currentStage)") + .font(.caption.monospaced()) + .foregroundStyle(.secondary) + .lineLimit(1) + .truncationMode(.middle) + + if build.blockedJobs > 0 { + Text("\(build.blockedJobs) job\(build.blockedJobs == 1 ? "" : "s") waiting on it") + .font(.caption2) + .foregroundStyle(.tertiary) + } + } + .animation(reduceMotion ? nil : .easeInOut, value: Int(remaining / 60)) + } + } + + /// Before the first jobs in each pool start there is nothing to go on — an estimate made + /// in that window is off by roughly 113 minutes, so it isn't offered. + private var estimatingHeadline: some View { + VStack(alignment: .leading, spacing: 2) { + Text("ESTIMATING") + .font(.caption2.weight(.semibold)) + .foregroundStyle(.secondary) + .tracking(0.6) + + HStack(spacing: 8) { + Text("Waiting for jobs to start") + .font(.system(.title3, design: .rounded, weight: .medium)) + .foregroundStyle(.secondary) + PulsingDots() + } + } + } + + /// What is knowable before the estimate is: how much has landed, and how long it's been. + private var estimatingFooter: some View { + let resolved = summary.successCount + summary.failureCount + let total = summary.totalCount + summary.lowerTierTotal + return HStack(spacing: 4) { + Text("\(resolved) of \(total) jobs done") + .foregroundStyle(.secondary) + Text("·") + .foregroundStyle(.tertiary) + Text("\(eta.pushedAt.shortTimeAgo()) elapsed") + .foregroundStyle(.tertiary) + } + .font(.caption.monospacedDigit()) + } + + // MARK: Footer + + @ViewBuilder + private var footer: some View { + HStack(alignment: .top, spacing: 10) { + if let longPole = eta.longPole { + Label { + HStack(spacing: 4) { + Text(longPole).fontWeight(.medium) + if eta.longPoleRemaining > 0 { + Text("· \(eta.longPoleRemaining) left").foregroundStyle(.secondary) + } + } + } icon: { + Image(systemName: "tortoise") + } + .font(.caption) + .foregroundStyle(StatusPalette.busted) + .lineLimit(2) + } + + Spacer(minLength: 0) + + if eta.confidence != .estimating { + Text("all done ~\(eta.allDoneBy.etaShortClock)") + .font(.caption.monospacedDigit()) + .foregroundStyle(.tertiary) + .fixedSize() + } + } + } + + private var accessibilityLabel: String { + if eta.confidence == .estimating { + return "Estimating completion time, waiting for jobs to start" + } + if let build = eta.blockingBuild, eta.confidence == .blockedOnBuild { + return "Tests start in about \(build.releasesAt.timeIntervalSinceNow.etaSpoken), " + + "currently building \(build.currentStage), " + + "\(build.blockedJobs) jobs waiting" + } + var parts = [ + "Most results in \(eta.mostResultsBy.timeIntervalSinceNow.etaSpoken), by \(eta.mostResultsBy.clockTime)", + "all jobs done around \(eta.allDoneBy.clockTime)", + ] + if let longPole = eta.longPole { + parts.append("\(longPole) is the long pole, \(eta.longPoleRemaining) jobs left") + } + return parts.joined(separator: ", ") + } +} + +// MARK: - Timeline track + +/// Push → now → done, as one bar. +/// +/// The filled span is the push's actual outcome so far, split green/red/blue by what the +/// jobs did, so the bar carries the counts and the timing in one object instead of two. The +/// faint remainder is what's left, and the notch is `mostResultsBy` — which is why the notch +/// usually sits well short of the end. +private struct ETATimelineTrack: View { + let eta: PushETA + let summary: PushSummary + let now: Date + let height: CGFloat + let animates: Bool + + var body: some View { + VStack(alignment: .leading, spacing: 5) { + GeometryReader { geo in + let width = geo.size.width + let elapsed = eta.progress(asOf: now) + let notch = eta.mostResultsFraction() + + ZStack(alignment: .leading) { + Capsule() + .fill(Color(uiColor: .systemGray5)) + + // Outcome so far, in proportion. + let filled = max(height, width * elapsed) + HStack(spacing: 0) { + ForEach(segments, id: \.0) { _, color, share in + Rectangle().fill(color).frame(width: filled * share) + } + } + .frame(width: filled, alignment: .leading) + .clipShape(Capsule()) + + // Where most of the answers land. + Capsule() + .fill(.background) + .frame(width: 2.5, height: height + 5) + .offset(x: min(width - 2.5, width * notch)) + .opacity(notch < 0.99 ? 1 : 0) + } + .animation(animates ? .easeInOut(duration: 0.5) : nil, value: elapsed) + } + .frame(height: height) + + HStack(spacing: 4) { + Text(eta.pushedAt.clockTime) + Spacer() + Text("most results") + .foregroundStyle(StatusPalette.running) + Spacer() + Text(eta.allDoneBy.clockTime) + } + .font(.caption2.monospacedDigit()) + .foregroundStyle(.tertiary) + } + } + + /// Resolved-so-far, split by outcome. Shares sum to 1, so the filled span reads as the + /// push's actual result mix rather than an undifferentiated blue bar. + private var segments: [(String, Color, Double)] { + let counts: [(String, Color, Int)] = [ + ("pass", StatusPalette.success, summary.successCount), + ("fail", StatusPalette.failed, summary.failureCount), + ("run", StatusPalette.running, summary.runningCount), + ].filter { $0.2 > 0 } + let total = counts.reduce(0) { $0 + $1.2 } + guard total > 0 else { return [("run", StatusPalette.running, 1)] } + return counts.map { ($0.0, $0.1, Double($0.2) / Double(total)) } + } +} + +// MARK: - Job-count track + +/// Progress by job count rather than by time — used while there is no trustworthy ETA, so +/// the card still shows something true. +private struct JobCountTrack: View { + let summary: PushSummary + let height: CGFloat + let animates: Bool + + var body: some View { + GeometryReader { geo in + let width = geo.size.width + let total = max(1, summary.totalCount + summary.lowerTierTotal) + let done = Double(summary.successCount + summary.failureCount) / Double(total) + let running = Double(summary.runningCount) / Double(total) + + ZStack(alignment: .leading) { + Capsule().fill(Color(uiColor: .systemGray5)) + HStack(spacing: 0) { + Rectangle().fill(StatusPalette.success) + .frame(width: width * done * successShare) + Rectangle().fill(StatusPalette.failed) + .frame(width: width * done * (1 - successShare)) + Rectangle().fill(StatusPalette.running) + .frame(width: width * running) + } + .clipShape(Capsule()) + } + .animation(animates ? .easeInOut(duration: 0.5) : nil, value: done + running) + } + .frame(height: height) + } + + private var successShare: Double { + let resolved = summary.successCount + summary.failureCount + return resolved == 0 ? 1 : Double(summary.successCount) / Double(resolved) + } +} + +// MARK: - Compact pill + +/// The same estimate, shrunk to fit a list row beside the status dots. +struct ETAPill: View { + let eta: PushETA + + var body: some View { + switch eta.confidence { + case .estimating: + EmptyView() + case .blockedOnBuild: + if let build = eta.blockingBuild { + pill(target: build.releasesAt, icon: "hammer.fill", tint: StatusPalette.busted) + } + case .firm: + pill(target: eta.mostResultsBy, icon: "clock", tint: StatusPalette.running) + } + } + + private func pill(target: Date, icon: String, tint: Color) -> some View { + TimelineView(.periodic(from: .now, by: 30)) { context in + let remaining = target.timeIntervalSince(context.date) + HStack(spacing: 3) { + Image(systemName: icon) + Text(remaining <= 60 ? "now" : remaining.etaCountdown) + .monospacedDigit() + .contentTransition(.numericText(countsDown: true)) + } + .font(.caption2.weight(.semibold)) + .foregroundStyle(tint) + .padding(.horizontal, 6) + .padding(.vertical, 2) + .background(tint.opacity(0.12), in: Capsule()) + } + .accessibilityHidden(true) // the row speaks this as part of one phrase + } +} + +// MARK: - Pulsing dots + +/// Reuses the push list's loading idiom so "estimating" reads as the same kind of waiting. +private struct PulsingDots: View { + @Environment(\.accessibilityReduceMotion) private var reduceMotion + @State private var pulse = false + + var body: some View { + HStack(spacing: 3) { + ForEach(0..<3, id: \.self) { index in + Circle() + .fill(Color(uiColor: .systemGray3)) + .frame(width: 4, height: 4) + .opacity(pulse ? 0.3 : 1) + .animation( + reduceMotion + ? nil + : .easeInOut(duration: 0.7).repeatForever().delay(Double(index) * 0.15), + value: pulse + ) + } + } + .onAppear { pulse = true } + } +} + +// MARK: - Formatting + +extension TimeInterval { + /// `"2h 15m"`, `"45m"`, `"< 1m"` — tight enough for a countdown that ticks. + var etaCountdown: String { + let minutes = Int((self / 60).rounded(.down)) + if minutes < 1 { return "< 1m" } + if minutes < 60 { return "\(minutes)m" } + let hours = minutes / 60 + let rest = minutes % 60 + if hours >= 24 { return "\(hours / 24)d \(hours % 24)h" } + return rest == 0 ? "\(hours)h" : "\(hours)h \(rest)m" + } + + /// Spelled out, for VoiceOver. + var etaSpoken: String { + let minutes = Int((self / 60).rounded()) + if minutes < 1 { return "under a minute" } + if minutes < 60 { return "\(minutes) minute\(minutes == 1 ? "" : "s")" } + let hours = minutes / 60, rest = minutes % 60 + var text = "\(hours) hour\(hours == 1 ? "" : "s")" + if rest > 0 { text += " \(rest) minute\(rest == 1 ? "" : "s")" } + return text + } +} + +extension Date { + /// `15:48` or `3:48 PM`, per the reader's locale. + var clockTime: String { + formatted(date: .omitted, time: .shortened) + } + + /// Same, but says the day when the estimate runs past midnight — a backed-up hardware + /// pool really can push a try job into tomorrow, and "3:48 AM" alone reads as a bug. + var etaShortClock: String { + Calendar.current.isDateInToday(self) + ? clockTime + : "\(formatted(.dateTime.weekday(.abbreviated))) \(clockTime)" + } +} diff --git a/BuildWatch/Views/PushDetailView.swift b/BuildWatch/Views/PushDetailView.swift index 4e51032..9dfde67 100644 --- a/BuildWatch/Views/PushDetailView.swift +++ b/BuildWatch/Views/PushDetailView.swift @@ -28,6 +28,7 @@ struct PushDetailView: View { var body: some View { List { + etaSection pushHeader actionsSection jobsSection @@ -45,6 +46,17 @@ struct PushDetailView: View { } } + // MARK: - ETA + + /// First thing on the screen when a push is still going, and gone the moment it isn't — + /// a finished push has no ETA, and `PushETA` returns nil rather than a stale one. + @ViewBuilder + private var etaSection: some View { + if let eta = summary?.eta, let summary { + Section { PushETACard(eta: eta, summary: summary) } + } + } + // MARK: - Push Header private var pushHeader: some View { @@ -270,6 +282,11 @@ struct JobRowView: View { case .pending: Image(systemName: "clock.fill") .foregroundStyle(.secondary) + case .unscheduled: + // Distinct from pending: this one isn't even in a queue yet, it's waiting on + // a dependency. Worth telling apart when you're wondering why nothing moves. + Image(systemName: "clock.badge.questionmark.fill") + .foregroundStyle(.tertiary) case .completed: Image(systemName: job.result.systemImage) .foregroundStyle(job.result.color) diff --git a/README.md b/README.md index d721feb..5cb1884 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,50 @@ Bug numbers in commit messages become tappable links. Every job row deep-links t Taskcluster task. All external links (TreeHerder, Taskcluster, Bugzilla) open in an in-app Safari sheet — one tap to dismiss, no app switch. +### The ETA + +The reason a try push is annoying is not that it fails, it's that you don't know when it +lands. Each running push carries an estimate: a countdown on the list row, and a card at the +top of the push detail. + +It shows **two numbers, not one**, because a push doesn't finish smoothly. On a sampled +907-job push, 90% of the jobs were done at 47 minutes and the *last* one at 144 — and the +tail wasn't slow work, it was waiting. Those final jobs ran for 12–25 minutes after queueing +for 95–117. So the headline is **when 90% of your jobs are in**, which is both the reliable +number and the one that answers "when will I know if this is green". The full finish is shown +alongside it, deliberately as an approximation. + +Backtested by replaying 77 completed pushes at nine points each: + +| | median error | within ±25% | within ±50% | overruns by >30 min | +|---|---|---|---|---| +| Most results (90% of jobs) | **2 min** | **70%** | **88%** | **1%** | +| All done (last job) | 13 min | 39% | 62% | 32% | + +**How.** Run time is the predictable part — a job's duration has a median coefficient of +variation of 5%, so a table of per-job-type medians shipped with the app predicts it to +within 5%. Queue *wait* is the hard part, and it's read live from the push itself: jobs in a +worker pool that have already started tell you what the ones that haven't will wait. On one +push, 76 jobs in `macosx1500-aarch64-shippable` had a p25, median and p90 queue wait of +140.7, 140.7 and 144.6 minutes, because they're all gated on the same build and released +together. + +**When it says nothing.** The estimate needs a pool to have someone in it who has started. +Before that it is wrong by about 113 minutes, so instead of a number you get progress and +elapsed time. 83% of pushes clear the bar, at a median of 30 minutes in, and then stay clear +for a median 72% of what's left. + +**When it's waiting on a build.** The most common reason a push looks frozen is that its +tests are `unscheduled` behind a build — one live Talos push had 32 of its 37 unresolved jobs +in exactly that state, with no pool observation to go on at all. Rather than a vague push +ETA, the card switches to the precise thing: which build stage is running and when tests get +released. Gecko's shippable pipeline is three stages deep +(`instrumented-build-` → `generate-profile-` → `build-`), so the chain is walked rather than +just the running stage. Predicted build finishes land within 5 minutes 71% of the time. + +The one thing it can't do is see the future: retrigger a job three hours later and the +estimate simply recomputes. + ### Failure Summary The reason the app exists. It pulls TreeHerder's structured `text_log_errors` for up to 15 @@ -92,6 +136,11 @@ opt-in that shows its live authorization status. | [Taskcluster](https://firefox-ci-tc.services.mozilla.com) | Task deep links | | [Bugzilla](https://bugzilla.mozilla.org) | Bug links parsed out of commit messages | +The ETA adds no fourth source and makes no extra requests: it runs off the job rows +BuildWatch already fetches, plus one bundled 137 KB table of historical job durations +(`BuildWatch/Resources/JobDurations.json`, regenerate with +`tools/generate-duration-table.py`). + All read-only, all public, all unauthenticated. BuildWatch stores nothing but your LDAP handle and your watch list, both in `UserDefaults` on-device. @@ -107,6 +156,8 @@ BuildWatch/ ├── Models/ │ ├── Push.swift — Push, PushRevision, try-message cleanup │ ├── Job.swift — Job, JobResult, JobState, PlatformGroup +│ ├── PushETA.swift — completion estimate, queue-wait model, build chain +│ ├── JobDurationTable.swift — bundled per-job-type run times │ └── FailureLine.swift — TextLogError, FailureGroup ├── Services/ │ └── TreeHerderService.swift — TreeHerder API, compact-job parser @@ -114,6 +165,7 @@ BuildWatch/ │ └── DashboardViewModel.swift — @Observable state for both tabs └── Views/ ├── DashboardView.swift — push list (TryPushesView) + ├── ETAView.swift — ETA card, timeline track, list-row pill ├── PushDetailView.swift — jobs, quick actions, counts bar ├── FailureSummaryView.swift — grouped failure sheet └── SettingsView.swift — preferences @@ -275,6 +327,7 @@ swiftc -O Benchmarks/ParserBenchmark.swift -o /tmp/bwbench - [ ] Acknowledge / classify failures (needs sign-in) - [ ] Backout via Lando API - [ ] File a bug pre-filled with failure details +- [x] Estimated time to completion - [ ] WebSocket live updates from TreeHerder - [ ] Intermittent failure history - [ ] Sheriff mode — tree management quick actions diff --git a/tools/generate-duration-table.py b/tools/generate-duration-table.py new file mode 100755 index 0000000..62c5b25 --- /dev/null +++ b/tools/generate-duration-table.py @@ -0,0 +1,141 @@ +#!/usr/bin/env python3 +"""Rebuild BuildWatch/Resources/JobDurations.json from real try pushes. + +The ETA's accuracy rests on this table: the same estimator built only from a push's own +completed jobs lands within +/-25% just 12% of the time, versus 63% with the table. + +Run it when job definitions have drifted enough that the miss rate matters -- every few +months is plenty, since a job's run time has a median coefficient of variation of 5%. + + python3 tools/generate-duration-table.py --days 3 -o BuildWatch/Resources/JobDurations.json + +Reads only public, unauthenticated TreeHerder endpoints. Takes ~15 minutes and makes a few +hundred requests against a shared public service, so it sleeps between them. +""" +import argparse, collections, json, random, re, statistics, sys, time, urllib.request + +BASE = "https://treeherder.mozilla.org/api/project/try" +UA = {"User-Agent": "BuildWatch-table-builder/1.0 (+https://github.com/mozilla-platform-ops/BuildWatch)"} + +# Anything longer than this is a hung job, not a duration worth learning from. +MAX_JOB_MINUTES = 720 +# An entry needs at least this many observations before its median means anything. +MIN_OBSERVATIONS = 2 +# Keep an exact per-job-type entry only when it differs from its chunk family by more than +# this -- chunks of one suite run near-identically, so most exact entries are redundant. +# Pruning on this cut the table from 286 KB to 137 KB with no loss of accuracy. +FAMILY_TOLERANCE = 0.10 + + +def get(url, attempts=4): + for attempt in range(attempts): + try: + return json.load(urllib.request.urlopen(urllib.request.Request(url, headers=UA), timeout=120)) + except Exception as exc: # noqa: BLE001 - transient network, retry + print(f" retry {attempt}: {type(exc).__name__}", file=sys.stderr) + time.sleep(4) + return None + + +def recent_pushes(days): + """Walk back `days` of try pushes. + + Paginated with `id__lt`, never `?page=` or `?offset=`: TreeHerder's push endpoint + silently ignores both and re-serves page one, which duplicates rows without erroring. + """ + newest = get(f"{BASE}/push/?count=1")["results"][0] + cutoff = newest["push_timestamp"] - days * 86400 + cursor, out, seen = newest["id"], [], set() + while True: + batch = get(f"{BASE}/push/?count=100&id__lt={cursor}") + if not batch or not batch["results"]: + break + for push in batch["results"]: + if push["id"] not in seen: + seen.add(push["id"]) + out.append(push) + cursor = min(p["id"] for p in batch["results"]) + if min(p["push_timestamp"] for p in batch["results"]) < cutoff: + break + return out + + +def family_key(job_type_name): + return re.sub(r"-\d+$", "", job_type_name) + + +def main(): + ap = argparse.ArgumentParser() + ap.add_argument("--days", type=int, default=3) + ap.add_argument("--pushes", type=int, default=400, help="how many pushes to sample") + ap.add_argument("-o", "--out", default="BuildWatch/Resources/JobDurations.json") + args = ap.parse_args() + + pushes = recent_pushes(args.days) + print(f"{len(pushes)} pushes in the last {args.days} days", file=sys.stderr) + random.seed(7) + sample = random.sample(pushes, min(args.pushes, len(pushes))) + + exact, family, platform, everything = ( + collections.defaultdict(list), collections.defaultdict(list), + collections.defaultdict(list), [], + ) + for i, push in enumerate(sample): + payload = get(f"{BASE}/jobs/?push_id={push['id']}&count=2000&return_type=list") + if not payload or not payload.get("job_property_names"): + continue + # A response of exactly 2000 rows is TreeHerder's cap, not a job count -- the rest + # are silently dropped, so the push is unusable rather than merely incomplete. + if len(payload["results"]) >= 2000: + continue + col = {name: n for n, name in enumerate(payload["job_property_names"])} + for row in payload["results"]: + start, end = row[col["start_timestamp"]], row[col["end_timestamp"]] + if not start or not end or end <= start: + continue + minutes = (end - start) / 60 + if minutes <= 0 or minutes > MAX_JOB_MINUTES: + continue + name = row[col["job_type_name"]] + exact[name].append(minutes) + family[family_key(name)].append(minutes) + platform[f'{row[col["platform"]]}|{row[col["platform_option"]]}'].append(minutes) + everything.append(minutes) + if i % 25 == 0: + print(f" {i}/{len(sample)} pushes, {len(everything)} jobs", file=sys.stderr) + time.sleep(0.15) + + if not everything: + sys.exit("no jobs collected") + + med = lambda vs: round(statistics.median(vs), 1) # noqa: E731 + fam_table = {k: med(v) for k, v in family.items() if len(v) >= MIN_OBSERVATIONS} + exact_table = {} + for name, values in exact.items(): + if len(values) < MIN_OBSERVATIONS: + continue + value = med(values) + inherited = fam_table.get(family_key(name)) + if inherited is None or abs(value - inherited) > max(1.0, FAMILY_TOLERANCE * inherited): + exact_table[name] = value + + table = { + "generated": time.strftime("%Y-%m-%d"), + "jobsSampled": len(everything), + "global": med(everything), + "exact": exact_table, + "family": fam_table, + "platform": {k: med(v) for k, v in platform.items() if len(v) >= 3}, + } + blob = json.dumps(table, separators=(",", ":"), sort_keys=True) + with open(args.out, "w") as fh: + fh.write(blob) + print( + f"wrote {args.out}: {len(exact_table)} exact, {len(fam_table)} family, " + f"{len(table['platform'])} platform, {len(blob) // 1024} KB", + file=sys.stderr, + ) + + +if __name__ == "__main__": + main() From 51e7d01ee70f55ade7ab13486d6b645db3f284b2 Mon Sep 17 00:00:00 2001 From: Ryan Curran Date: Wed, 26 Aug 2026 11:31:11 -0400 Subject: [PATCH 2/2] Ship the ETA as 1.2 (10) Feature bump rather than a build-only bump: the push list and detail view both gain a new element. Release build verified carrying JobDurations.json -- without the bundled table the estimator silently falls back to a single 20.8 minute global median for every job. --- BuildWatch.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/BuildWatch.xcodeproj/project.pbxproj b/BuildWatch.xcodeproj/project.pbxproj index 5adcadc..7baca8d 100644 --- a/BuildWatch.xcodeproj/project.pbxproj +++ b/BuildWatch.xcodeproj/project.pbxproj @@ -252,7 +252,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 9; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = KA6H3Z2C59; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; @@ -265,7 +265,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.1; + MARKETING_VERSION = 1.2; PRODUCT_BUNDLE_IDENTIFIER = com.ryancurran.ios.BuildWatch; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES; @@ -284,7 +284,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 9; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = KA6H3Z2C59; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; @@ -297,7 +297,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.1; + MARKETING_VERSION = 1.2; PRODUCT_BUNDLE_IDENTIFIER = com.ryancurran.ios.BuildWatch; PRODUCT_NAME = "$(TARGET_NAME)"; STRING_CATALOG_GENERATE_SYMBOLS = YES;