95 lines
3.8 KiB
JavaScript
95 lines
3.8 KiB
JavaScript
import { test } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import './test-support.mjs'
|
|
const { PerformanceRecording } = await import('../src/performanceRecording.ts')
|
|
|
|
function frame(time, drew, phase = 'idle') {
|
|
return {
|
|
callbackTimestampMs: time, startedAtMs: time + 0.1, drew,
|
|
mode: 'Inspect', phase, updateMs: 0.05, submitMs: drew ? 0.2 : null,
|
|
callbackWorkMs: drew ? 0.3 : 0.06, drawCalls: drew ? 4 : 0,
|
|
triangles: drew ? 300 : 0, textures: 8, programs: 6,
|
|
}
|
|
}
|
|
|
|
test('logs distinguish 30Hz idle callbacks from actual drawing and unavailable GPU time', () => {
|
|
const log = new PerformanceRecording()
|
|
log.start(0, { gpuTimerSupported: false })
|
|
for (let i = 0; i < 60; i++) log.frame(frame(i * 33, i >= 30, i >= 30 ? 'sweep' : 'idle'))
|
|
log.stop(1980)
|
|
const report = log.report()
|
|
assert.equal(report.summary.callbacks, 60)
|
|
assert.equal(report.summary.draws, 30)
|
|
assert.equal(report.summary.callbacksAfterIdle.medianMs, 33)
|
|
assert.equal(report.summary.callbacksAfterDraw.medianMs, 33)
|
|
assert.equal(report.summary.intervalBuckets.over28To38ms, 59)
|
|
assert.equal(report.summary.cpuSubmit.count, 30)
|
|
assert.equal(report.summary.phases.find(phase => phase.phase === 'idle').draws, 0)
|
|
assert.equal(report.summary.phases.find(phase => phase.phase === 'sweep').cpuSubmit.count, 30)
|
|
assert.ok(Math.abs(report.summary.actualArrivalIntervals.medianMs - 33) < 0.001)
|
|
assert.equal(report.summary.gpuRender, null)
|
|
})
|
|
|
|
test('GPU results stay attached to issue frames, including results delivered after stop', () => {
|
|
const log = new PerformanceRecording()
|
|
log.start(0, {})
|
|
log.frame(frame(0, true, 'revealing'))
|
|
log.frame(frame(33, true, 'inspecting'))
|
|
log.stop(34)
|
|
log.gpuSample(0, 12)
|
|
log.gpuSample(-33, 100)
|
|
const report = log.report()
|
|
assert.deepEqual(report.gpuSamples, [{ frameIndex: 0, elapsedMs: 12 }])
|
|
assert.equal(report.frames[report.gpuSamples[0].frameIndex].phase, 'revealing')
|
|
assert.equal(report.summary.gpuRender.medianMs, 12)
|
|
})
|
|
|
|
test('visibility discontinuities do not become slow foreground frames, but real stalls remain logged', () => {
|
|
const log = new PerformanceRecording()
|
|
log.start(0, {})
|
|
log.frame(frame(0, false))
|
|
log.event(20, 'visibilitychange', { visibility: 'hidden' })
|
|
log.breakContinuity()
|
|
log.frame(frame(5000, false))
|
|
log.frame(frame(6000, true))
|
|
const report = log.report()
|
|
assert.equal(report.frames[1].intervalMs, null)
|
|
assert.equal(report.frames[2].intervalMs, 1000)
|
|
assert.equal(report.summary.callbackIntervals.worstMs, 1000)
|
|
assert.equal(report.events.length, 1)
|
|
})
|
|
|
|
test('recordings stop at 30 seconds and cap frames/events without growing indefinitely', () => {
|
|
const log = new PerformanceRecording()
|
|
log.start(0, {})
|
|
log.frame(frame(0, true))
|
|
log.frame(frame(30001, true))
|
|
assert.equal(log.active, false)
|
|
assert.equal(log.report().durationMs, 30000)
|
|
assert.equal(log.frameCount, 1)
|
|
log.start(0, {})
|
|
for (let i = 0; i < 1000; i++) log.event(i, 'input')
|
|
for (let i = 0; i < 8000; i++) log.frame(frame(i, true))
|
|
const report = log.report()
|
|
assert.equal(report.frames.length, 7200)
|
|
assert.equal(report.stopReason, 'frame-limit')
|
|
assert.equal(report.events.length, 256)
|
|
assert.equal(report.droppedEvents, 744)
|
|
})
|
|
|
|
test('exports are independent snapshots and starting again clears previous evidence', () => {
|
|
const log = new PerformanceRecording()
|
|
const metadata = { gpu: 'test', initialState: { mode: 'Inspect' } }
|
|
log.start(0, metadata)
|
|
metadata.initialState.mode = 'Pack'
|
|
log.frame(frame(0, true))
|
|
const first = log.report()
|
|
first.frames[0].phase = 'changed'
|
|
assert.equal(log.report().frames[0].phase, 'idle')
|
|
assert.equal(log.report().environment.initialState.mode, 'Inspect')
|
|
log.start(100, {})
|
|
log.gpuSample(0, 12)
|
|
assert.equal(log.frameCount, 0)
|
|
assert.equal(log.report().gpuSamples.length, 0)
|
|
})
|