test(desktop): isolate packaging Git observations from concurrent fixtures
This commit is contained in:
1 parent
df2372fefe
commit
63c7e370ce
5 files changed
+24
-6
No files matched your search
@@ -18,8 +18,8 @@
|
||||
en: c4b4ee8763d8464a
|
||||
zh: ee2159bc08966592
|
||||
/desktop-local-update-verification/evidence:
|
||||
en: bc4634c9a9ceddca
|
||||
zh: 21370a4c088b50df
|
||||
en: 331a6709d0f7d03f
|
||||
zh: 98499192ef9d3a81
|
||||
/desktop-local-update-verification/open-verification:
|
||||
en: 20e9ea47acb1ff50
|
||||
zh: acce24b56d57e12c
|
||||
@@ -42,6 +42,8 @@ With Host, client, and Desktop artifacts built, run `node --import tsx apps/desk
|
||||
|
||||
The local command builds Desktop and executes Electron 44 with the actual HTTP updater, policy client, sandboxed preload, and mandatory renderer. It records each scenario and preserves its report under `.desktop-build/qualification/local-updater-*`. The installer call, external browser, and clipboard are observation substitutes; downloaded bytes are not an executable installer.
|
||||
|
||||
Packaging supervision fixtures control their Git metadata and use real file hashes with inert child processes. Git-head and worktree changes still refuse packaging; concurrent tests cannot change the fixture’s recorded Git inputs.
|
||||
|
||||
| Layer | Observed result |
|
||||
|---|---|
|
||||
| Ordinary updater | Same/older-version rejection, user-authorized full download, SHA-512 rejection, interrupted transfer, stalled-feed/download deadlines, explicit retry, coalesced requests, same-address feed replacement, readiness, and separate install handoff pass |
|
||||
|
||||
@@ -42,6 +42,8 @@ Host、客户端与 Desktop 产物构建完成后,在 Windows 仓库根目录
|
||||
|
||||
本地命令构建 Desktop,并在 Electron 44 中运行真实 HTTP updater、策略客户端、沙箱预加载和强更页面。它记录每个场景,并把报告保存在 `.desktop-build/qualification/local-updater-*`。安装器调用、外部浏览器和剪贴板均替换为观测记录;下载字节不是可执行安装器。
|
||||
|
||||
打包监督 fixture 控制自己的 Git 元数据,并使用真实文件哈希和无签名行为的子进程。Git 提交或工作区变化仍会拒绝打包;并发测试不会改变该 fixture 记录的 Git 输入。
|
||||
|
||||
| 层次 | 观测结果 |
|
||||
|---|---|
|
||||
| 常规 updater | 同版本/旧版本拒绝、用户授权完整下载、SHA-512 拒绝、传输中断、清单/下载停滞截止时间、显式重试、请求合并、同地址清单替换、就绪状态和独立安装交接通过 |
|
||||
|
||||
@@ -5,7 +5,19 @@ import { describe, expect, it, vi } from 'vitest'
|
||||
import { createInstalledUpdateRun } from '../scripts/installed-update-qualification.ts'
|
||||
import { assertInstalledUpdateSigningClear, installedUpdatePackagingEnvironment, packageInstalledUpdate } from '../scripts/installed-update-packaging.ts'
|
||||
|
||||
const state = vi.hoisted(() => ({ home: '', settings: {} as NodeJS.ProcessEnv, loads: 0 }))
|
||||
const state = vi.hoisted(() => ({ home: '', settings: {} as NodeJS.ProcessEnv, loads: 0,
|
||||
sourceCommit: 'a'.repeat(40), dirtyFiles: '' }))
|
||||
// Other test processes create workspace probes; only this fixture controls its recorded Git inputs.
|
||||
vi.mock('node:child_process', async (original) => {
|
||||
const actual = await original<typeof import('node:child_process')>()
|
||||
return { ...actual, execFileSync: (...args: Parameters<typeof actual.execFileSync>) => {
|
||||
if (args[0] !== 'git') return actual.execFileSync(...args)
|
||||
const command = args[1]?.join(' ')
|
||||
if (command === 'rev-parse HEAD') return state.sourceCommit
|
||||
if (command === 'status --porcelain=v1 --untracked-files=normal') return state.dirtyFiles
|
||||
throw new Error(`unexpected fixture Git command: ${String(command)}`)
|
||||
} }
|
||||
})
|
||||
vi.mock('node:os', async original => ({ ...await original<typeof import('node:os')>(), homedir: () => state.home }))
|
||||
vi.mock('../scripts/desktop-package-environment.mjs', () => ({
|
||||
loadDesktopPackageEnvironment: () => { state.loads++; return state.settings },
|
||||
@@ -118,17 +130,19 @@ describe('operator-driven packaging entry', () => {
|
||||
})
|
||||
})
|
||||
|
||||
it.runIf(process.platform === 'win32' && process.arch === 'x64').each(['output', 'source'] as const)(
|
||||
it.runIf(process.platform === 'win32' && process.arch === 'x64').each(['output', 'source', 'git-head', 'git-status'] as const)(
|
||||
'refuses an intervening %s change before launching the builder', async (change) => {
|
||||
await fixture(async (manifest, root) => {
|
||||
await expect(packageInstalledUpdate(manifest, versions[0], { execute: true, confirm: async () => {
|
||||
if (change === 'source') await writeFile(join(root, 'certificate.cer'), 'changed certificate bytes')
|
||||
else if (change === 'git-head') state.sourceCommit = 'b'.repeat(40)
|
||||
else if (change === 'git-status') state.dirtyFiles = ' M apps/desktop/package.json'
|
||||
else {
|
||||
await mkdir(join(manifest, '..', versions[0], 'installer'))
|
||||
await writeFile(join(manifest, '..', versions[0], 'installer/owner.txt'), 'preserve')
|
||||
}
|
||||
return true
|
||||
} })).rejects.toThrow()
|
||||
} })).rejects.toThrow(change === 'output' ? 'EEXIST' : 'recorded source or tool inputs changed before packaging')
|
||||
const parent = join(manifest, '..', versions[0], 'packaging')
|
||||
const record = join(parent, (await readdir(parent))[0]!)
|
||||
expect(await readFile(join(record, 'events.jsonl'), 'utf8')).not.toContain('stage-spawn')
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
- text: Radius example
|
||||
- status: r***@example.com
|
||||
- link "更多账号信息":
|
||||
- /url: https://platform.deepseek.com
|
||||
- /url: https://platform.deepseek.com/
|
||||
- text: 充值余额 ¥128.50 赠金余额 ¥12.00 更多
|
||||
- link "查询用量":
|
||||
- /url: https://platform.deepseek.com/usage
|
||||
|
||||
Reference in new issue
Block a user