Refactor local dev stack scheduler
This commit is contained in:
134
scripts/dev-utils.test.ts
Normal file
134
scripts/dev-utils.test.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import { mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join } from 'node:path';
|
||||
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import {
|
||||
formatApiServerLogTimestamp,
|
||||
mergeApiServerEnv,
|
||||
resolveApiServerLogFile,
|
||||
} from './dev-utils.mjs';
|
||||
|
||||
type EnvMap = Record<string, string>;
|
||||
|
||||
function withTempEnvFiles(
|
||||
files: Record<string, string>,
|
||||
assertEnv: (env: EnvMap, tempDir: string) => void,
|
||||
) {
|
||||
const tempDir = mkdtempSync(join(tmpdir(), 'genarrative-api-env-'));
|
||||
|
||||
try {
|
||||
for (const [fileName, content] of Object.entries(files)) {
|
||||
writeFileSync(join(tempDir, fileName), content, 'utf8');
|
||||
}
|
||||
|
||||
assertEnv(mergeApiServerEnv(tempDir, {}) as EnvMap, tempDir);
|
||||
} finally {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
describe('dev utils env merge', () => {
|
||||
test('.env.local 和 .env.secrets.local 可以覆盖 .env 默认值', () => {
|
||||
withTempEnvFiles(
|
||||
{
|
||||
'.env': [
|
||||
'SMS_AUTH_ENABLED=false',
|
||||
'HYPER3D_API_KEY=',
|
||||
'GENARRATIVE_SPACETIME_DATABASE=from-env',
|
||||
].join('\n'),
|
||||
'.env.local': [
|
||||
'SMS_AUTH_ENABLED=true',
|
||||
'HYPER3D_API_KEY=local-key',
|
||||
].join('\n'),
|
||||
'.env.secrets.local': 'HYPER3D_API_KEY=secret-key',
|
||||
},
|
||||
(env) => {
|
||||
expect(env.SMS_AUTH_ENABLED).toBe('true');
|
||||
expect(env.HYPER3D_API_KEY).toBe('secret-key');
|
||||
expect(env.GENARRATIVE_SPACETIME_DATABASE).toBe('from-env');
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('外层 shell 变量优先于本地 env 文件', () => {
|
||||
withTempEnvFiles(
|
||||
{
|
||||
'.env': 'HYPER3D_API_KEY=from-env',
|
||||
'.env.local': 'HYPER3D_API_KEY=from-local',
|
||||
'.env.secrets.local': 'HYPER3D_API_KEY=from-secrets',
|
||||
},
|
||||
(_env, tempDir) => {
|
||||
expect(
|
||||
mergeApiServerEnv(tempDir, { HYPER3D_API_KEY: 'from-shell' })
|
||||
.HYPER3D_API_KEY,
|
||||
).toBe('from-shell');
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
test('空外层 shell 变量不会遮蔽本地私密配置', () => {
|
||||
withTempEnvFiles(
|
||||
{
|
||||
'.env.local': [
|
||||
'ALIYUN_OSS_BUCKET=dev-bucket',
|
||||
'ALIYUN_OSS_ENDPOINT=oss-cn-shanghai.aliyuncs.com',
|
||||
].join('\n'),
|
||||
'.env.secrets.local': [
|
||||
'ALIYUN_OSS_ACCESS_KEY_ID=local-access-key',
|
||||
'ALIYUN_OSS_ACCESS_KEY_SECRET=local-access-secret',
|
||||
].join('\n'),
|
||||
},
|
||||
(_env, tempDir) => {
|
||||
const env = mergeApiServerEnv(tempDir, {
|
||||
ALIYUN_OSS_BUCKET: '',
|
||||
ALIYUN_OSS_ENDPOINT: ' ',
|
||||
ALIYUN_OSS_ACCESS_KEY_ID: 'shell-access-key',
|
||||
ALIYUN_OSS_ACCESS_KEY_SECRET: '',
|
||||
});
|
||||
|
||||
expect(env.ALIYUN_OSS_BUCKET).toBe('dev-bucket');
|
||||
expect(env.ALIYUN_OSS_ENDPOINT).toBe('oss-cn-shanghai.aliyuncs.com');
|
||||
expect(env.ALIYUN_OSS_ACCESS_KEY_ID).toBe('shell-access-key');
|
||||
expect(env.ALIYUN_OSS_ACCESS_KEY_SECRET).toBe('local-access-secret');
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dev utils log file resolution', () => {
|
||||
const fixedDate = new Date(2026, 4, 15, 6, 7, 8);
|
||||
|
||||
test('默认写入 logs/api-server 的时间戳文件', () => {
|
||||
const tempDir = mkdtempSync(join(tmpdir(), 'genarrative-api-log-'));
|
||||
|
||||
try {
|
||||
expect(formatApiServerLogTimestamp(fixedDate)).toBe('20260515-060708');
|
||||
expect(resolveApiServerLogFile(tempDir, {}, fixedDate)).toBe(
|
||||
join(tempDir, 'logs/api-server/api-server-20260515-060708.log'),
|
||||
);
|
||||
} finally {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('GENARRATIVE_API_SERVER_LOG_FILE 优先于日志目录默认值', () => {
|
||||
const tempDir = mkdtempSync(join(tmpdir(), 'genarrative-api-log-'));
|
||||
|
||||
try {
|
||||
expect(
|
||||
resolveApiServerLogFile(
|
||||
tempDir,
|
||||
{
|
||||
GENARRATIVE_API_SERVER_LOG_DIR: 'logs/ignored',
|
||||
GENARRATIVE_API_SERVER_LOG_FILE: 'logs/custom/api.log',
|
||||
},
|
||||
fixedDate,
|
||||
),
|
||||
).toBe(join(tempDir, 'logs/custom/api.log'));
|
||||
} finally {
|
||||
rmSync(tempDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user