fix12: разделение env-артефактов и стабилизация smoke

This commit is contained in:
2026-04-30 23:54:15 +05:00
parent a41f14067b
commit b228928e99
6 changed files with 42 additions and 29 deletions
+31 -19
View File
@@ -3,24 +3,31 @@ import { info } from "../lib/log";
import { runHidden, runSecret, runVisible } from "../lib/process";
async function retry<T>(
label: string,
attempts: number,
delayMs: number,
action: () => Promise<T>,
validate: (value: T) => boolean,
errorFactory: (value: T) => Error,
errorFactory: (value: T | undefined, error: unknown) => Error,
): Promise<T> {
let lastValue: T | undefined;
let lastError: unknown;
for (let i = 0; i < attempts; i += 1) {
const value = await action();
lastValue = value;
if (validate(value)) {
return value;
try {
const value = await action();
lastValue = value;
if (validate(value)) {
return value;
}
} catch (error) {
lastError = error;
}
if (i < attempts - 1) {
info(`${label}: retry ${i + 1}/${attempts}`);
await runHidden`sleep ${Math.max(1, Math.ceil(delayMs / 1000))}`;
}
}
throw errorFactory(lastValue as T);
throw errorFactory(lastValue, lastError);
}
export async function smoke(context: RuntimeContext): Promise<void> {
@@ -62,11 +69,12 @@ export async function smoke(context: RuntimeContext): Promise<void> {
await runVisible`! ss -H -ltn | grep -q '\[::\]:${context.config.uiPort} '`;
await runVisible`! ss -H -lun | grep -q '\[::\]:${context.config.hysteriaPort} '`;
const invalidAuthResponse = await retry(
"auth invalid credentials",
5,
1000,
async () => runSecret`curl -sS --max-time 5 -X POST -H 'Content-Type: application/json' --data '{"addr":"127.0.0.1:12345","auth":"invalid","tx":"0"}' http://127.0.0.1:${context.config.uiPort}/hui/hysteria2/auth`,
(response) => /"ok"\s*:\s*false/.test(response),
(response) => new Error(`unexpected auth response for invalid credentials: ${response}`),
(response, error) => new Error(`unexpected auth response for invalid credentials: ${response ?? String(error)}`),
);
for (let i = 0; i < 10; i += 1) {
@@ -76,25 +84,29 @@ export async function smoke(context: RuntimeContext): Promise<void> {
}
}
const adminConPass = (await runSecret`grep '^ADMIN_CON_PASS=' ${context.config.bootstrapAdminSecretPath} | head -n1 | cut -d= -f2-`).trim();
if (!adminConPass) {
throw new Error("admin connection password is empty in bootstrap secret file");
if (context.mode === "install") {
const adminConPass = (await runSecret`grep '^ADMIN_CON_PASS=' ${context.config.bootstrapAdminSecretPath} | head -n1 | cut -d= -f2-`).trim();
if (!adminConPass) {
throw new Error("admin connection password is empty in bootstrap secret file");
}
await retry(
"auth valid credentials",
10,
1000,
async () => runSecret`curl -sS --max-time 5 -X POST -H 'Content-Type: application/json' --data '{"addr":"127.0.0.1:12345","auth":"${adminConPass}","tx":"0"}' http://127.0.0.1:${context.config.uiPort}/hui/hysteria2/auth`,
(response) => /"ok"\s*:\s*true/.test(response),
(response, error) => new Error(`unexpected auth response for valid credentials: ${response ?? String(error)}`),
);
}
const validAuthResponse = await retry(
10,
1000,
async () => runSecret`curl -sS --max-time 5 -X POST -H 'Content-Type: application/json' --data '{"addr":"127.0.0.1:12345","auth":"${adminConPass}","tx":"0"}' http://127.0.0.1:${context.config.uiPort}/hui/hysteria2/auth`,
(response) => /"ok"\s*:\s*true/.test(response),
() => new Error("unexpected auth response for valid credentials"),
);
await retry(
"trafficStats valid secret",
10,
1000,
async () => runSecret`curl -sS --max-time 5 -o /dev/null -w '%{http_code}' -H 'Authorization: ${context.config.hysteriaTrafficStatsSecret}' http://127.0.0.1:${context.config.hysteriaTrafficStatsPort}/online`,
(code) => /^2\d\d$/.test(code.trim()),
(code) => new Error(`unexpected trafficStats status for valid secret: ${code}`),
(code, error) => new Error(`unexpected trafficStats status for valid secret: ${code ?? String(error)}`),
);
const deniedCode = await runSecret`curl -sS --max-time 5 -o /dev/null -w '%{http_code}' -H 'Authorization: invalid-hy2xs-secret' http://127.0.0.1:${context.config.hysteriaTrafficStatsPort}/online`;
if (!/(401|403)/.test(deniedCode)) {