test(mediabunny): [PKG-MB-09] start hour-scale installed playback checks

This commit is contained in:
Harvey Zhao committed 2026-09-16 11:20:49 +08:00
1 parent 5795492f0f
commit d71b6fea38
11 files changed
+301 -13

No files matched your search

+147
View File
@@ -0,0 +1,147 @@
{
"schemaVersion": 1,
"task": "PKG-MB-09",
"startedFrom": "5795492f0f6eff9f987b43e2f51643f0131f659d",
"capturedAt": "2026-09-16T03:20:08.923Z",
"status": "running-at-capture",
"completionProven": false,
"node": "v24.21.0",
"yarn": "1.22.22",
"sourceSha256LF": {
"playwright.soak.config.js": "5be535955745716e94353c8d21458b18301bf612f15c3f78d931f4d875d44c69",
"scripts/generate-hls-fixture.mjs": "70468ef1daa00726a985a0fcbd365f43e3ee741f883307cbf63ce24316084dad",
"test/helpers/soak-options.js": "bcb37f317cf34a53a0070715f625cbbc88969bd6914219a95db689e543574995",
"test/soak/mediabunny.spec.js": "f435cf9d04f58ed6786428d72745cb3545f595d0313fefac25d1ad671211d826",
"refactor/scripts/soak-options.test.mjs": "8aa25d5308376b807621f3b3914181a7ad2535e30622f3c8773b796582ea52d5"
},
"prechecks": {
"optionsTests": {
"pass": 3,
"fail": 0
},
"lintExit": 0,
"installedListExit": 0,
"defaultMedia": {
"files": 32,
"completeManifestEqual": true
}
},
"media": {
"path": "refactor/.cache/mb09-hour-hls/manifest.json",
"sha256": "ed988797a4e8c9ccd848b67ea9be85ece0fe1df1b276e88daa80a0c49f6c126a",
"duration": 11000,
"files": 22008,
"bytes": 598523989,
"ffmpeg": "ffmpeg version 2025-11-12-git-6cdd2cbe32-full_build-www.gyan.dev Copyright (c) 2000-2025 the FFmpeg developers"
},
"command": "yarn test:mediabunny-soak --project chromium --project firefox",
"environment": {
"ARTPLAYER_MB_SOAK_SECONDS": "3600",
"ARTPLAYER_MB_SOAK_MEDIA": "refactor/.cache/mb09-hour-hls",
"ARTPLAYER_BROWSER_ARTIFACTS": "refactor/.cache/packages/run-kK0VCe/browser-artifacts.json"
},
"logs": [
{
"path": "refactor/.cache/mb09-hour-options.log",
"sha256": "5d00f6c63329e399579b084fa9898fd3959249a09cbc16533fed0d6ded04ebeb"
},
{
"path": "refactor/.cache/mb09-hour-lint.log",
"sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
},
{
"path": "refactor/.cache/mb09-hour-installed-list.log",
"sha256": "5db98207480cc15e840e3c74dbe444a4c35e86048f7a8ade061b5e9fa274ecb5"
},
{
"path": "refactor/.cache/mb09-hour-generate.log",
"sha256": "7a490ee15ad659fd6303b70d5ace5767a131a7b508fa31a1c6b8ea0cdbd9772a"
},
{
"path": "refactor/.cache/mb09-hour-default-generate.log",
"sha256": "276a5b50b4f169a525ea0ad3fb1fded298c07589d34d0017ad97c3b381820f19"
}
],
"liveLog": "refactor/.cache/mb09-hour-browser.log",
"samples": [
{
"path": "refactor/.cache/soak/results/mediabunny-MediaBunny-sust-71bde-layback-with-published-core-chromium/progress.jsonl",
"started": {
"kind": "started",
"project": "chromium",
"core": "published",
"implementation": "candidate-installed",
"sha256": "662598a27e1757692ce4bd560c376bc96520d172ed67427ec519bd269896fa92",
"manifestSha256": "ed988797a4e8c9ccd848b67ea9be85ece0fe1df1b276e88daa80a0c49f6c126a",
"mediaDuration": 11000,
"requestedPhaseSeconds": 3600,
"capabilities": {
"audio": "function",
"videoDecoder": "function",
"audioDecoder": "function"
},
"outcome": "incomplete",
"phases": [],
"checkpoints": []
},
"latest": {
"kind": "sample",
"phase": "continuous-1x",
"wall": 55981.09999990463,
"time": 56.24,
"rate": 1,
"active": 50,
"queued": 50,
"iterators": 2,
"draws": 1326,
"visibility": "visible",
"paused": false,
"error": null,
"maxAVError": 0.02500000000000213
},
"observations": 11
},
{
"path": "refactor/.cache/soak/results/mediabunny-MediaBunny-sust-828df-layback-with-candidate-core-chromium/progress.jsonl",
"started": {
"kind": "started",
"project": "chromium",
"core": "candidate",
"implementation": "candidate-installed",
"sha256": "662598a27e1757692ce4bd560c376bc96520d172ed67427ec519bd269896fa92",
"manifestSha256": "ed988797a4e8c9ccd848b67ea9be85ece0fe1df1b276e88daa80a0c49f6c126a",
"mediaDuration": 11000,
"requestedPhaseSeconds": 3600,
"capabilities": {
"audio": "function",
"videoDecoder": "function",
"audioDecoder": "function"
},
"outcome": "incomplete",
"phases": [],
"checkpoints": []
},
"latest": {
"kind": "sample",
"phase": "continuous-1x",
"wall": 55933.39999997616,
"time": 56.18933333333334,
"rate": 1,
"active": 53,
"queued": 53,
"iterators": 2,
"draws": 1325,
"visibility": "visible",
"paused": false,
"error": null,
"maxAVError": 0.02500000000000213
},
"observations": 11
}
],
"limitations": [
"This start snapshot is not a terminal browser result. Recheck the live process and report before assessing completion.",
"Fixed installed runtime bytes are tested; shared-tool changes invalidated their original release input fingerprint.",
"No physical-device, acoustic, background or whole-heap proof."
]
}
@@ -0,0 +1,57 @@
# PKG-MB-09:数小时播放验收入口
任务保持 doing。本检查点扩展现有持续播放验收;不以入口实现替代长测结果。
当前核心/MediaBunny 公开接口、运行时代码及发布产物不变。
## 执行与维护
`ARTPLAYER_MB_SOAK_SECONDS` 指定每个连续阶段的实际墙钟秒数,默认仍为 90,
仅允许 90..3600 整数。3600 模式执行连续一小时 1×、一小时 2×,随后保留 seek、
质量/音轨切换和 destroy 清理。两段连续阶段之间不 seek、循环或修改媒体时钟。
每项超时是两段目标墙钟加原有 90 秒操作余量;默认仍是 270 秒,未放宽原有断言。
媒体必须至少覆盖 `max(600, 3 * phaseSeconds + 60)` 秒;不足在启动浏览器前失败。
生成器最大素材时长由 3600 扩展到 14400 秒,仍禁止覆盖既有目录。默认 12 秒素材
已重新生成,32 个文件、FFmpeg 参数和哈希全部与原冻结 manifest 相同。
```powershell
yarn generate:media:hls refactor/.cache/mb09-hour-hls 11000
$env:ARTPLAYER_MB_SOAK_SECONDS = '3600'
$env:ARTPLAYER_MB_SOAK_MEDIA = (Resolve-Path refactor/.cache/mb09-hour-hls).Path
$env:ARTPLAYER_BROWSER_ARTIFACTS = (Resolve-Path refactor/.cache/packages/run-kK0VCe/browser-artifacts.json).Path
Remove-Item Env:ARTPLAYER_MB_ARTIFACT -ErrorAction SilentlyContinue
yarn test:mediabunny-soak --project chromium --project firefox
```
该安装映射对应已登记的 core 6.0.0 / MediaBunny 2.0.0 文件,实际来源由既有校验器
及浏览器附件记录。共享工程变动后旧候选输入指纹失效,使用固定运行时字节测试不表示
通过发布准入;未来运行必须明确选择当时的安装映射。
修复原入口对 `ARTPLAYER_MB_ARTIFACT` 的无条件要求:现在允许显式构建文件或经过
验证的安装映射,仍禁止隐式源码编译,同时指定覆盖值仍由现有 helper 拒绝。
长素材按需读取,只常驻文件索引;初始化核对全部哈希,每次响应前再次核对分片,
不再把整套媒体字节复制到每个 worker 的常驻 Map。
每 5 秒另写逐用例 `progress.jsonl`,记录媒体/墙钟、绘制、节点/迭代器、可见性与
累计最大 AV 偏差;进程中断时也保留采样。原有最终附件、AV 250ms 阈值、活动节点
上限、推进速度和清理检查不变。时长参数位于 `test/helpers/soak-options.js`,
由 Playwright 配置和用例共享,避免超时与媒体长度计算漂移。
## 当前验证与边界
- Node 24.21.0 / Yarn 1.22.22;FFmpeg 与原冻结工具版本相同。
- 参数与启动拒绝测试 3/3:默认时长/超时保持、边界拒绝、缺少显式产物和短素材拒绝。
- 变更文件只读 lint 通过;安装映射模式 `--list` 成功发现六个原有浏览器/核心用例。
- 默认素材重新生成后的完整 manifest 深比较通过,32 文件及命令没有改变。
- 11,000 秒素材生成完成,22,008 文件 / 598,523,989 字节,manifest 摘要和工具信息
见[启动证据](../baselines/mb-hour-soak-start.json)。开始采样时 Chromium 新旧核心都在
1× 实际推进,无媒体错误、活动节点分别 50/53、AV 最大偏差约 25ms。
这些是约 55 秒时的中途状态,不是数小时通过结论。
Chromium/Firefox 新旧核心四项以两个 worker 执行,理想执行约四小时加启动/切换清理。
不要同时启动占用 8084 的普通浏览器测试。运行前归档旧 `refactor/.cache/soak`;
运行中依据实际进程句柄与 progress 文件观察,不把未完成报告或锁文件当成功。
失败时保留日志和采样,不提高阈值或重试直到通过。
即使通过,也不证明声学输出同步、完整堆/GPU无泄漏、后台节流、物理设备或全部插件组合。
WebKit 缺失原生 WebCodecs 的对照不算播放;MB-09 与相关风险继续保留未完成项。
+4
View File
@@ -1,5 +1,9 @@
# MediaBunny proxy 验证入口
数小时专项入口见[2026-09-16 检查点](changes/2026-09-16-PKG-MB-09-hour-soak.md)。
它保留原断言和默认时长,支持已安装候选映射、按需分片读取及持久化采样;长测未终结
前不能据此宣称通过。任务仍为 PKG-MB-09 doing。
开始改动前读取[冻结契约](baselines/mb-contract.md)、[接口快照](baselines/mb-surface.json)、
[归档/源码哈希](baselines/mb-release.json)。MB-01接口基线与
[MB-02行为基线](changes/2026-09-12-PKG-MB-02-baseline.md)分开记录;不得把接口测试称为真实媒体验收。
+1 -1
View File
@@ -669,7 +669,7 @@
- PKG-MB-06: [记录](baselines/mb-audio-source.json) [记录](changes/2026-09-12-PKG-MB-06-audio.md) [记录](baselines/mb-audio-validation.json)
- PKG-MB-07: [记录](baselines/mb-hls-source.json) [记录](changes/2026-09-12-PKG-MB-07-hls.md) [记录](baselines/mb-hls-validation.json)
- PKG-MB-08: [记录](baselines/mb-entry-source.json) [记录](changes/2026-09-12-PKG-MB-08-entry-checkpoint.md) [记录](baselines/mb-entry-checkpoint.json) [记录](baselines/mb-capability-source.json) [记录](changes/2026-09-12-PKG-MB-08-capability.md) [记录](baselines/mb-capability-validation.json)
- PKG-MB-09: [记录](changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md) [记录](baselines/mb-native-pip-checkpoint.json) [记录](changes/2026-09-12-PKG-MB-09-sustained-playback-checkpoint.md) [记录](baselines/mb-sustained-validation.json) [记录](baselines/mb-sustained-media.json)
- PKG-MB-09: [记录](changes/2026-09-12-PKG-MB-09-native-pip-checkpoint.md) [记录](baselines/mb-native-pip-checkpoint.json) [记录](changes/2026-09-12-PKG-MB-09-sustained-playback-checkpoint.md) [记录](baselines/mb-sustained-validation.json) [记录](baselines/mb-sustained-media.json) [记录](changes/2026-09-16-PKG-MB-09-hour-soak.md) [记录](baselines/mb-hour-soak-start.json)
- PKG-IFRAME-01: [记录](changes/2026-09-12-PKG-IFRAME-01-contract.md) [记录](baselines/iframe-release.json) [记录](baselines/iframe-contract.md) [记录](baselines/iframe-contract-validation.json)
- PKG-IFRAME-02: [记录](changes/2026-09-12-PKG-IFRAME-02-behavior.md) [记录](baselines/iframe-behavior-validation.json)
- PKG-IFRAME-03: [记录](changes/2026-09-12-PKG-IFRAME-03-requests-checkpoint.md) [记录](baselines/iframe-requests-checkpoint.json) [记录](changes/2026-09-12-PKG-IFRAME-03-boundaries-checkpoint.md) [记录](baselines/iframe-boundaries-checkpoint.json) [记录](iframe-message-boundary.md) [记录](changes/2026-09-13-PKG-IFRAME-03-navigation.md) [记录](baselines/iframe-navigation-validation.json) [记录](iframe-document-protocol.md)
+12
View File
@@ -1,5 +1,17 @@
# 进度与证据
## PKG-MB-09 数小时播放运行检查点
扩展现有长测为每段90..3600秒,默认时长/超时和断言不变;支持已安装候选映射,
媒体改为按需读取且每次校验哈希,每5秒持久化进度。3项前置测试、定向lint、
安装映射列举通过,默认12秒素材32文件/参数/哈希完全不变。
11000秒素材生成完成,Chromium/Firefox新旧核心四组已启动、两个worker;
[启动快照](baselines/mb-hour-soak-start.json)记录首批Chromium约55秒的正常推进,
不是最终结果。用实际会话句柄和 `refactor/.cache/soak/results/*/progress.jsonl`
检查持续状态,终结后保留完整报告;不要重复启动或让其他浏览器测试占用8084。
[维护与限制](changes/2026-09-16-PKG-MB-09-hour-soak.md)。MB-09仍doing,计数不变。
当前没有正式复盘、推送或发布。
## CI-NPM-03 只读 registry 与部分发布恢复判断
新增 `yarn release:registry`,在真实候选验证前后夹住只读 registry 查询,区分缺失、
+48
View File
@@ -0,0 +1,48 @@
import assert from 'node:assert/strict'
import { spawnSync } from 'node:child_process'
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import process from 'node:process'
// eslint-disable-next-line test/no-import-node-test -- Soak validation runs without launching hours of browsers.
import test from 'node:test'
import { soakOptions } from '../../test/helpers/soak-options.js'
test('Default soak preserves the old duration and deadline; hour phases require enough uninterrupted media', () => {
assert.deepEqual(soakOptions(undefined), { phaseSeconds: 90, minimumMediaSeconds: 600, timeoutMs: 270000 })
const long = soakOptions('3600')
assert.equal(long.phaseSeconds, 3600)
assert.equal(long.minimumMediaSeconds, 10860)
assert.equal(long.timeoutMs, 7290000)
for (const value of ['', '0', '89', '90.5', '3601', 'Infinity', 'NaN', 'abc'])
assert.throws(() => soakOptions(value), /whole seconds/)
})
test('Missing explicit artifacts fail before browser work', () => {
const env = { ...process.env, ARTPLAYER_MB_SOAK_SECONDS: '3600' }
delete env.ARTPLAYER_MB_ARTIFACT
delete env.ARTPLAYER_BROWSER_ARTIFACTS
delete env.ARTPLAYER_MB_BASELINE
const result = spawnSync(process.execPath, ['test/soak/mediabunny.spec.js'], { cwd: process.cwd(), env, encoding: 'utf8' })
assert.notEqual(result.status, 0)
assert.match(result.stderr, /explicit built artifact or verified installed artifact map/)
})
test('Hour phases reject the existing ten-minute fixture before launching a browser', (t) => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'artplayer-soak-options-'))
t.after(() => {
const resolved = fs.realpathSync(directory)
assert.equal(path.dirname(resolved), fs.realpathSync(os.tmpdir()))
assert(path.basename(resolved).startsWith('artplayer-soak-options-'))
fs.rmSync(resolved, { recursive: true })
})
const artifact = path.join(directory, 'artifact.js')
fs.writeFileSync(artifact, '// Not executed: media validation must reject first.\n')
fs.writeFileSync(path.join(directory, 'manifest.json'), JSON.stringify({ duration: 600, files: {} }))
const env = { ...process.env, ARTPLAYER_MB_SOAK_SECONDS: '3600', ARTPLAYER_MB_SOAK_MEDIA: directory, ARTPLAYER_MB_ARTIFACT: artifact }
delete env.ARTPLAYER_BROWSER_ARTIFACTS
delete env.ARTPLAYER_MB_BASELINE
const result = spawnSync(process.execPath, ['test/soak/mediabunny.spec.js'], { cwd: process.cwd(), env, encoding: 'utf8' })
assert.notEqual(result.status, 0)
assert.match(result.stderr, /at least 10860 seconds/)
})
+3 -1
View File
@@ -4021,7 +4021,9 @@
"baselines/mb-native-pip-checkpoint.json",
"changes/2026-09-12-PKG-MB-09-sustained-playback-checkpoint.md",
"baselines/mb-sustained-validation.json",
"baselines/mb-sustained-media.json"
"baselines/mb-sustained-media.json",
"changes/2026-09-16-PKG-MB-09-hour-soak.md",
"baselines/mb-hour-soak-start.json"
]
},
{