mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-08 02:52:15 +00:00
test(docker): harden live acp bind probes
This commit is contained in:
@@ -98,6 +98,26 @@ if [[ -f "$PROFILE_FILE" && -r "$PROFILE_FILE" ]]; then
|
||||
PROFILE_STATUS="$PROFILE_FILE"
|
||||
fi
|
||||
|
||||
openclaw_live_acp_bind_load_factory_api_key_from_profile() {
|
||||
[[ -z "${FACTORY_API_KEY:-}" ]] || return 0
|
||||
[[ -f "$PROFILE_FILE" && -r "$PROFILE_FILE" ]] || return 0
|
||||
[[ "$PROFILE_FILE" != "$HOME/.profile" ]] || return 0
|
||||
|
||||
local line value
|
||||
line="$(sed -nE 's/^(export[[:space:]]+)?FACTORY_API_KEY=//p' "$PROFILE_FILE" | tail -n 1 || true)"
|
||||
[[ -n "$line" ]] || return 0
|
||||
value="$line"
|
||||
if [[ "$value" == \"*\" && "$value" == *\" ]]; then
|
||||
value="${value#\"}"
|
||||
value="${value%\"}"
|
||||
elif [[ "$value" == \'*\' && "$value" == *\' ]]; then
|
||||
value="${value#\'}"
|
||||
value="${value%\'}"
|
||||
fi
|
||||
[[ -n "$value" ]] || return 0
|
||||
export FACTORY_API_KEY="$value"
|
||||
}
|
||||
|
||||
read -r -d '' LIVE_TEST_CMD <<'EOF' || true
|
||||
set -euo pipefail
|
||||
[ -f "$HOME/.profile" ] && [ -r "$HOME/.profile" ] && source "$HOME/.profile" || true
|
||||
@@ -317,6 +337,9 @@ for ACP_AGENT in "${ACP_AGENTS[@]}"; do
|
||||
DOCKER_AUTH_PRESTAGED=1
|
||||
fi
|
||||
|
||||
if [[ "$ACP_AGENT" == "droid" ]]; then
|
||||
openclaw_live_acp_bind_load_factory_api_key_from_profile
|
||||
fi
|
||||
if [[ "$ACP_AGENT" == "droid" && -z "${FACTORY_API_KEY:-}" ]]; then
|
||||
echo "==> Run ACP bind live test in Docker"
|
||||
echo "==> Agent: $ACP_AGENT"
|
||||
|
||||
@@ -580,9 +580,21 @@ async function pollCronJobVisibleViaCli(params: {
|
||||
env: NodeJS.ProcessEnv;
|
||||
expectedName: string;
|
||||
expectedMessage: string;
|
||||
}): Promise<{ job?: Awaited<ReturnType<typeof assertCronJobVisibleViaCli>>; pollsUsed: number }> {
|
||||
}): Promise<{
|
||||
error?: string;
|
||||
job?: Awaited<ReturnType<typeof assertCronJobVisibleViaCli>>;
|
||||
pollsUsed: number;
|
||||
}> {
|
||||
for (let verifyAttempt = 0; verifyAttempt < ACP_CRON_MCP_PROBE_VERIFY_POLLS; verifyAttempt += 1) {
|
||||
const job = await assertCronJobVisibleViaCli(params);
|
||||
let job: Awaited<ReturnType<typeof assertCronJobVisibleViaCli>>;
|
||||
try {
|
||||
job = await assertCronJobVisibleViaCli(params);
|
||||
} catch (error) {
|
||||
return {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
pollsUsed: verifyAttempt + 1,
|
||||
};
|
||||
}
|
||||
if (job) {
|
||||
return { job, pollsUsed: verifyAttempt + 1 };
|
||||
}
|
||||
@@ -1063,6 +1075,14 @@ describeLive("gateway live (ACP bind)", () => {
|
||||
expectedMessage: cronProbe.message,
|
||||
});
|
||||
const createdJob = verifyResult.job;
|
||||
if (verifyResult.error) {
|
||||
lastCronMismatch = verifyResult.error;
|
||||
logLiveStep(
|
||||
`cron cli verification failed after attempt ${String(
|
||||
attempt + 1,
|
||||
)}; polls=${String(verifyResult.pollsUsed)}; error=${lastCronMismatch}`,
|
||||
);
|
||||
}
|
||||
if (createdJob) {
|
||||
try {
|
||||
assertCronJobMatches({
|
||||
|
||||
@@ -918,6 +918,11 @@ describe("package artifact reuse", () => {
|
||||
it("fails Droid ACP Docker live proof when Factory auth is missing", () => {
|
||||
const script = readFileSync("scripts/test-live-acp-bind-docker.sh", "utf8");
|
||||
|
||||
expect(script).toContain("openclaw_live_acp_bind_load_factory_api_key_from_profile");
|
||||
expect(script).not.toContain('source "$PROFILE_FILE"');
|
||||
expect(script.indexOf("openclaw_live_acp_bind_load_factory_api_key_from_profile")).toBeLessThan(
|
||||
script.indexOf('if [[ "$ACP_AGENT" == "droid" && -z "${FACTORY_API_KEY:-}" ]]; then'),
|
||||
);
|
||||
expect(script).toContain(
|
||||
"ERROR: Droid Docker ACP bind requires FACTORY_API_KEY; Factory OAuth/keyring auth in ~/.factory is not portable into the container.",
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user