mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-18 02:21:20 -08:00
test(performance): [ENG-13] enforce measured teardown observation minimum
This commit is contained in:
1 parent
23a4f22b72
commit
48a7f1ecb0
11 files changed
+22120
-12
No files matched your search
@@ -7,7 +7,7 @@ import { test } from 'node:test'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { hash } from '../refactor/scripts/releases.mjs'
|
||||
import { verifyPerformanceArtifacts } from '../scripts/performance-artifacts.mjs'
|
||||
import { performanceHtml, performanceScript } from '../scripts/performance-fixture.mjs'
|
||||
import { performanceHtml, performanceScript, waitForObservation } from '../scripts/performance-fixture.mjs'
|
||||
import { validatePairedPerformance } from '../scripts/performance-report.mjs'
|
||||
|
||||
const baseline = JSON.parse(fs.readFileSync(new URL('../refactor/baselines/performance.json', import.meta.url), 'utf8')).runs[0]
|
||||
@@ -44,6 +44,7 @@ test('paired performance requires comparable cohorts, real playback and strict c
|
||||
report => report.runs[1].measurements.resources[0].after.timers.push({ kind: 'interval' }),
|
||||
report => report.runs[1].measurements.resources[0].after.lateCallbacks.push({ kind: 'timeout' }),
|
||||
report => report.runs[1].measurements.resources[0].after.lateResizeEvents++,
|
||||
report => report.runs[1].measurements.resources[0].after.observedMs = 349,
|
||||
]) {
|
||||
const report = fixture()
|
||||
mutate(report)
|
||||
@@ -60,17 +61,51 @@ test('paired performance requires comparable cohorts, real playback and strict c
|
||||
assert(comparison.reviewRequired && comparison.groups.every(group => group.reviewSignals.some(signal => signal.metric === 'constructorMs')))
|
||||
})
|
||||
|
||||
test('performance adapter changes only delivery while retaining the frozen measurement procedure', () => {
|
||||
test('performance adapter preserves frozen measurements except delivery and enforcing the observation minimum', () => {
|
||||
const frozen = fs.readFileSync(new URL('../refactor/fixtures/performance.js', import.meta.url), 'utf8')
|
||||
const adapted = performanceScript()
|
||||
const before = 'const response = await fetch(\'/reports/performance\', { method: \'POST\', headers: { \'Content-Type\': \'application/json\' }, body: JSON.stringify(report) })'
|
||||
const after = 'window.artplayerPerformanceReport = report; const response = { ok: true }'
|
||||
assert.equal(adapted.replace(after, before), frozen)
|
||||
const prefix = `${waitForObservation.toString()}\n`
|
||||
assert(adapted.startsWith(prefix))
|
||||
assert.equal(adapted.slice(prefix.length).replace(after, before).replace('await waitForObservation(probe.wait, now, waitStarted, 350)', 'await probe.wait(350)'), frozen)
|
||||
assert.match(performanceHtml('candidate'), /src="\/candidate\/artplayer.js"/)
|
||||
assert.match(performanceHtml('published'), /src="\/published\/artplayer-plugin-chapter.js"/)
|
||||
assert.throws(() => performanceHtml('../uncompiled'))
|
||||
})
|
||||
|
||||
test('resource observation re-arms after an early timer without rounding up evidence', async () => {
|
||||
let clock = 1000
|
||||
const delays = []
|
||||
await waitForObservation(async (delay) => {
|
||||
delays.push(delay)
|
||||
clock += delays.length === 1 ? 349 : 1
|
||||
}, () => clock, 1000, 350)
|
||||
assert.deepEqual(delays, [350, 1])
|
||||
assert.equal(clock - 1000, 350)
|
||||
})
|
||||
|
||||
test('resource observation retains overshoot and does not wait again after the minimum', async () => {
|
||||
let clock = 1000
|
||||
const delays = []
|
||||
const wait = async (delay) => {
|
||||
delays.push(delay)
|
||||
clock += 364
|
||||
}
|
||||
await waitForObservation(wait, () => clock, 1000, 350)
|
||||
assert.deepEqual(delays, [350])
|
||||
assert.equal(clock - 1000, 364)
|
||||
await waitForObservation(wait, () => clock, 1000, 350)
|
||||
assert.deepEqual(delays, [350])
|
||||
})
|
||||
|
||||
test('resource observation propagates timer failures rather than certifying an incomplete window', async () => {
|
||||
const failure = new Error('timer unavailable')
|
||||
await assert.rejects(waitForObservation(async () => {
|
||||
throw failure
|
||||
}, () => 0, 0, 350), error => error === failure)
|
||||
})
|
||||
|
||||
test('performance refuses stale sources, build tools and altered installed bundles', () => {
|
||||
const cache = fileURLToPath(new URL('../refactor/.cache/performance/', import.meta.url))
|
||||
fs.mkdirSync(cache, { recursive: true })
|
||||
|
||||
@@ -9,8 +9,9 @@ worker, no trace/video recording and the same media and viewport within a pair.
|
||||
Each engine runs three alternating published/candidate pairs. Each side retains
|
||||
one warm-up and five timed samples for both core and core + chapter, followed by
|
||||
separate instrumented resource probes. `scripts/performance-fixture.mjs` adapts
|
||||
only the frozen BASE-06 fixture's script URLs and report transport. Its original
|
||||
files remain unchanged and their existing baseline tests still run.
|
||||
the frozen BASE-06 fixture's script URLs, report transport and enforcement of its
|
||||
minimum observation window. The frozen files and all timed samples remain
|
||||
unchanged, and their existing baseline tests still run.
|
||||
|
||||
The candidate must come from an isolated package installation. Artifact hashes,
|
||||
source snapshots, package inputs and build tools are checked before measurement;
|
||||
@@ -28,3 +29,12 @@ A successful test proves the measurement contract and candidate resource cleanup
|
||||
approval. CORE-22 and release reviews must resolve the corresponding risks before
|
||||
publishing. These counters do not measure native heap/GPU memory, real mobile
|
||||
hardware or screen-reader behavior. See `refactor/coverage-performance.md`.
|
||||
|
||||
## Observation window
|
||||
|
||||
The current performance fixture adapter enforces the existing 350 ms teardown
|
||||
observation using the measured clock. It re-arms the probe's original timer if
|
||||
the nominal delay returns before that minimum, without rounding up reported
|
||||
time or relaxing validation. This applies equally to both variants and leaves
|
||||
the frozen BASE-06 fixture and all timed samples unchanged. See
|
||||
`test/performance-report.test.js` and `refactor/changes/2026-09-14-ENG-13-observation-window.md`.
|
||||
Reference in new issue
Block a user