Add regression coverage for resolved issue reports

This commit is contained in:
ushan0v
2026-07-11 00:10:54 +03:00
parent 9ce314e5c4
commit 045ea42562
2 changed files with 167 additions and 4 deletions
+6 -4
View File
@@ -333,7 +333,7 @@ cat >"$WORK_DIR/vpn-domain-resolver-fixture.json" <<'JSON'
},
"section": [
{
".name": "vpn",
".name": "renamed_awg",
".type": "section",
"enabled": "1",
"action": "vpn",
@@ -691,9 +691,11 @@ assert(vmess.tls.utls.fingerprint == "chrome", "manual VMess fingerprint");
assert(outbound(manual, "proxy-3-out").type == "shadowsocks", "manual Shadowsocks link");
let vpn = cfg("vpn");
assert(outbound(vpn, "vpn-out").bind_interface == "tun0", "VPN interface outbound");
assert(outbound(vpn, "vpn-out").domain_resolver == "vpn-domain-resolver", "VPN domain resolver tag");
assert(dns_server(vpn, r => r.tag == "vpn-domain-resolver") != null, "VPN domain resolver DNS server");
assert(outbound(vpn, "renamed_awg-out").bind_interface == "tun0", "renamed VPN interface outbound");
assert(outbound(vpn, "renamed_awg-out").domain_resolver == "renamed_awg-domain-resolver", "renamed VPN domain resolver tag");
assert(dns_server(vpn, r => r.tag == "renamed_awg-domain-resolver") != null, "renamed VPN domain resolver DNS server");
assert(route_rule(vpn, r => r.outbound == "renamed_awg-out" && contains(r.domain_suffix, "vpn.example")) != null, "renamed VPN custom domain route");
assert(dns_rule(vpn, r => contains(r.domain_suffix, "vpn.example")) != null, "renamed VPN custom domain DNS rule");
let download = cfg("download");
assert(inbound(download, "service-mixed-in") != null, "service mixed inbound");
@@ -0,0 +1,161 @@
#!/usr/bin/env bash
set -eo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
UPDATES_UC="$ROOT_DIR/podkop/files/usr/lib/components/updates.uc"
REAL_LIB="$ROOT_DIR/podkop/files/usr/lib"
WORK_DIR="$(mktemp -d)"
cleanup() {
rm -rf "$WORK_DIR"
}
trap cleanup EXIT
fail() {
printf 'FAIL: %s\n' "$1" >&2
exit 1
}
write_stub() {
local path="$1"
local body="$2"
mkdir -p "$(dirname "$path")"
printf '%s\n' "$body" >"$path"
}
stub_header='#!/usr/bin/env ucode
let fs = require("fs");
function as_string(value) {
return value == null ? "" : "" + value;
}
function shell_quote(value) {
return "'"'"'" + replace(as_string(value), /'"'"'/g, "'"'"'\\'"'"''"'"'") + "'"'"'";
}
function record(line) {
let path = getenv("FAKE_CALL_LOG") || "";
if (path != "")
system("printf '"'"'%s\\n'"'"' " + shell_quote(line) + " >> " + shell_quote(path));
}
'
FAKE_LIB="$WORK_DIR/lib"
write_stub "$FAKE_LIB/config/migration.uc" "$stub_header"'
record("config/migration:" + as_string(ARGV[0]));
exit(ARGV[0] == "migrate" ? 0 : 64);
'
write_stub "$FAKE_LIB/subscription/cache.uc" "$stub_header"'
let mode = as_string(ARGV[0]);
record("subscription/cache:" + mode);
if (mode == "ensure-runtime-dirs")
exit(0);
if (mode == "update-request") {
print(getenv("FAKE_SUBSCRIPTION_UPDATE_SUMMARY") || "1 0 0 0", "\n");
exit(0);
}
exit(64);
'
write_stub "$FAKE_LIB/service/state.uc" "$stub_header"'
let mode = as_string(ARGV[0]);
record("service/state:" + mode);
if (mode == "acquire-runtime-dir-lock" ||
mode == "acquire-runtime-dir-lock-wait" ||
mode == "release-runtime-dir-lock" ||
mode == "reload-sing-box-runtime" ||
mode == "write-current-reload-state-clean" ||
mode == "run-pending-reload-if-requested")
exit(0);
exit(64);
'
write_stub "$FAKE_LIB/server/service.uc" "$stub_header"'
record("server/service:" + as_string(ARGV[0]));
exit(ARGV[0] == "prepare-all-defaults" ? 0 : 64);
'
write_stub "$FAKE_LIB/config/validator.uc" "$stub_header"'
record("config/validator:" + as_string(ARGV[0]));
exit(ARGV[0] == "validate-runtime" ? 0 : 64);
'
write_stub "$FAKE_LIB/singbox/runtime.uc" "$stub_header"'
let mode = as_string(ARGV[0]);
if (mode == "init-config")
record("singbox/runtime:init-config:" + as_string(ARGV[1]) + ":" + as_string(ARGV[2]) + ":" + as_string(ARGV[3]));
else
record("singbox/runtime:" + mode);
if (mode == "configure-service" || mode == "init-config")
exit(0);
exit(64);
'
run_update() {
local summary="$1"
local log="$2"
: >"$log"
env \
PODKOP_LIB="$FAKE_LIB" \
PODKOP_RUNTIME_STATE_DIR="$WORK_DIR/run" \
PODKOP_SUBSCRIPTION_UPDATE_LOCK_DIR="$WORK_DIR/run/subscription-update.lock" \
PODKOP_RELOAD_LOCK_DIR="$WORK_DIR/run/reload.lock" \
PODKOP_SUBSCRIPTION_UPDATE_STATE_DIR="$WORK_DIR/run/subscription-update" \
PODKOP_SUBSCRIPTION_UPDATE_JOB_DIR="$WORK_DIR/run/subscription-update-jobs" \
PODKOP_SUBSCRIPTION_LINKS_DIR="$WORK_DIR/run/subscription-links" \
PODKOP_SUBSCRIPTION_METADATA_DIR="$WORK_DIR/run/subscription-metadata" \
PODKOP_OUTBOUND_METADATA_DIR="$WORK_DIR/run/outbound-metadata" \
PODKOP_SECTION_CACHE_DIR="$WORK_DIR/run/section-cache" \
PODKOP_RUNTIME_CACHE_FORMAT_FILE="$WORK_DIR/run/cache-format" \
PODKOP_PERSISTENT_SUBSCRIPTION_CACHE_DIR="$WORK_DIR/persistent/subscription-cache" \
PODKOP_PERSISTENT_SUBSCRIPTION_CACHE_FORMAT_FILE="$WORK_DIR/persistent/subscription-cache/cache-format" \
PODKOP_PENDING_RELOAD_FILE="$WORK_DIR/run/reload.pending" \
PODKOP_RELOAD_STATE_FILE="$WORK_DIR/run/reload-state" \
PODKOP_RULE_CONDITION_CACHE_DIR="$WORK_DIR/run/rule-condition-cache" \
FAKE_CALL_LOG="$log" \
FAKE_SUBSCRIPTION_UPDATE_SUMMARY="$summary" \
ucode -L "$REAL_LIB" "$UPDATES_UC" subscription-update-if-due
}
updated_log="$WORK_DIR/updated.log"
run_update "1 0 0 0" "$updated_log"
node - "$updated_log" <<'JS'
const fs = require("fs");
const calls = fs.readFileSync(process.argv[2], "utf8").trim().split(/\n+/);
const expected = [
"subscription/cache:update-request",
"server/service:prepare-all-defaults",
"config/validator:validate-runtime",
"singbox/runtime:configure-service",
"singbox/runtime:init-config:0:1:1",
"service/state:reload-sing-box-runtime",
"service/state:write-current-reload-state-clean",
"service/state:run-pending-reload-if-requested"
];
let position = -1;
for (const item of expected) {
const next = calls.indexOf(item, position + 1);
if (next === -1) {
console.error(`missing or out-of-order call: ${item}`);
console.error(calls.join("\n"));
process.exit(1);
}
position = next;
}
JS
unchanged_log="$WORK_DIR/unchanged.log"
run_update "0 0 1 0" "$unchanged_log"
if grep -Eq 'server/service|config/validator|singbox/runtime|reload-sing-box-runtime|write-current-reload-state-clean' "$unchanged_log"; then
fail "unchanged subscription update must not rebuild or reload sing-box"
fi
printf 'subscription update reload regression checks passed\n'