Files
kdletters 83f07fc58d
Project CI / Repository checks (push) Failing after 1m2s
Project CI / Frontend tests (push) Successful in 3m19s
Project CI / Backend tests (push) Successful in 4m18s
Project CI / Native shell tests (push) Failing after 11m47s
统一 AGC 开发端口分配
将 AGC Vite 纳入 Linux 用户端口段第六槽位
同步 Tauri devUrl、Vite 监听和配套后端端口预留
兼容迁移旧五端口注册记录并阻止重复分配
补齐动态配置顺序、跨平台和进程生命周期回归测试
更新开发运维文档、端口 skill 与项目共享记忆
2026-08-08 16:18:45 +08:00

131 lines
3.9 KiB
TypeScript

import { describe, expect, test, vi } from 'vitest';
import {
createAgcDevEndpoint,
resolveAgcDevEndpoint,
withAgcDevEndpointEnv,
} from '../scripts/dev-port.mjs';
describe('AI 游戏创作 dev 端口', () => {
test('Linux 使用用户端口段的 start + 5 槽位', async () => {
const findPort = vi.fn(async ({ preferredPort }) => preferredPort);
const endpoint = await resolveAgcDevEndpoint({
env: { USER: 'alice', LOGNAME: 'alice' },
platform: 'linux',
reservePortRange: async () => ({
username: 'alice',
range: { start: 10000, end: 10099, label: '10000-10099' },
}),
findPort,
});
expect(endpoint).toMatchObject({
port: 10005,
url: 'http://127.0.0.1:10005/',
markerUrl: 'http://127.0.0.1:10005/__agc_dev_server.json',
});
expect(findPort).toHaveBeenCalledWith(
expect.objectContaining({
preferredPort: 10005,
portRange: { start: 10000, end: 10099, label: '10000-10099' },
strict: false,
}),
);
});
test('Linux 槽位被占时接受本用户端口段内的漂移结果', async () => {
const endpoint = await resolveAgcDevEndpoint({
env: { USER: 'alice', LOGNAME: 'alice' },
platform: 'linux',
reservePortRange: async () => ({
username: 'alice',
range: { start: 10000, end: 10099, label: '10000-10099' },
}),
findPort: async ({ preferredPort, portRange }) => {
expect(preferredPort).toBe(10005);
expect(portRange?.label).toBe('10000-10099');
return 10006;
},
});
expect(endpoint.port).toBe(10006);
});
test('父启动器选定端口后子启动器严格使用同一端口', async () => {
const findPort = vi.fn(async ({ preferredPort }) => preferredPort);
await resolveAgcDevEndpoint({
env: {
USER: 'alice',
LOGNAME: 'alice',
GENARRATIVE_AGC_VITE_PORT: '10007',
},
platform: 'linux',
strictConfigured: true,
reservePortRange: async () => ({
username: 'alice',
range: { start: 10000, end: 10099, label: '10000-10099' },
}),
findPort,
});
expect(findPort).toHaveBeenCalledWith(
expect.objectContaining({ preferredPort: 10007, strict: true }),
);
});
test('旧五端口段无法安全扩容时 AGC 明确失败而不越界', async () => {
await expect(
resolveAgcDevEndpoint({
env: { USER: 'alice', LOGNAME: 'alice' },
platform: 'linux',
reservePortRange: async () => ({
username: 'alice',
range: { start: 10000, end: 10004, label: '10000-10004' },
}),
findPort: async () => 10005,
}),
).rejects.toThrow('缺少 AGC Vite 槽位');
});
test('Linux 显式 AGC 端口不能占用前五个服务槽位', async () => {
await expect(
resolveAgcDevEndpoint({
env: {
USER: 'alice',
LOGNAME: 'alice',
GENARRATIVE_AGC_VITE_PORT: '10004',
},
platform: 'linux',
reservePortRange: async () => ({
username: 'alice',
range: { start: 10000, end: 10099, label: '10000-10099' },
}),
findPort: async () => 10004,
}),
).rejects.toThrow('前五个服务槽位');
});
test('非 Linux 保留 3080 兼容优先端口并允许统一漂移', async () => {
const findPort = vi.fn(async () => 3081);
const endpoint = await resolveAgcDevEndpoint({
env: {},
platform: 'win32',
findPort,
});
expect(endpoint.port).toBe(3081);
expect(findPort).toHaveBeenCalledWith(
expect.objectContaining({ preferredPort: 3080, portRange: null }),
);
});
test('最终端口通过单一环境变量传给 Tauri 和 Vite 子进程', () => {
expect(
withAgcDevEndpointEnv(createAgcDevEndpoint(10008), { KEEP_ME: 'yes' }),
).toMatchObject({
KEEP_ME: 'yes',
GENARRATIVE_AGC_VITE_PORT: '10008',
});
});
});