mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-07-10 01:28:35 +00:00
fix(tests): use URL-based mock routing in hetzner orphan IP test to prevent flaky parallel failures
This commit is contained in:
parent
2221f1155b
commit
41229b10de
1 changed files with 47 additions and 36 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import { afterEach, beforeEach, describe, expect, it, mock, spyOn } from "bun:test";
|
||||
import { isString } from "@openrouter/spawn-shared";
|
||||
import { mockBunSpawn, mockClackPrompts } from "./test-helpers";
|
||||
|
||||
mockClackPrompts();
|
||||
|
|
@ -585,21 +586,14 @@ describe("hetzner/createServer", () => {
|
|||
},
|
||||
},
|
||||
};
|
||||
let createAttempts = 0;
|
||||
let callCount = 0;
|
||||
global.fetch = mock(() => {
|
||||
const mockFetch = mock((url: string | URL | Request, init?: RequestInit) => {
|
||||
callCount++;
|
||||
if (callCount <= 1) {
|
||||
// Token validation
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
servers: [],
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
if (callCount <= 2) {
|
||||
// SSH keys
|
||||
const urlStr = isString(url) ? url : url instanceof URL ? url.href : url.url;
|
||||
const method = init?.method ?? "GET";
|
||||
// SSH keys lookup
|
||||
if (urlStr.includes("/ssh_keys")) {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
|
|
@ -608,24 +602,16 @@ describe("hetzner/createServer", () => {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (callCount <= 3) {
|
||||
// First create attempt — resource_limit_exceeded (HTTP 403)
|
||||
// Delete orphaned IP (DELETE /primary_ips/NNN — must come before list check)
|
||||
if (urlStr.includes("/primary_ips/") && method === "DELETE") {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
error: {
|
||||
code: "resource_limit_exceeded",
|
||||
message: "primary_ip_limit",
|
||||
},
|
||||
}),
|
||||
{
|
||||
status: 403,
|
||||
},
|
||||
),
|
||||
new Response("", {
|
||||
status: 204,
|
||||
}),
|
||||
);
|
||||
}
|
||||
if (callCount <= 4) {
|
||||
// List primary IPs for cleanup
|
||||
// List primary IPs for cleanup
|
||||
if (urlStr.includes("/primary_ips")) {
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
|
|
@ -645,22 +631,47 @@ describe("hetzner/createServer", () => {
|
|||
),
|
||||
);
|
||||
}
|
||||
if (callCount <= 5) {
|
||||
// Delete orphaned IP 100
|
||||
// Create server (POST /servers)
|
||||
if (urlStr.includes("/servers") && method === "POST") {
|
||||
createAttempts++;
|
||||
if (createAttempts <= 1) {
|
||||
// First create attempt — resource_limit_exceeded (HTTP 403)
|
||||
return Promise.resolve(
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
error: {
|
||||
code: "resource_limit_exceeded",
|
||||
message: "primary_ip_limit",
|
||||
},
|
||||
}),
|
||||
{
|
||||
status: 403,
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
// Retry create — success
|
||||
return Promise.resolve(new Response(JSON.stringify(serverResp)));
|
||||
}
|
||||
// Token validation — GET /servers (and any other GET)
|
||||
if (urlStr.includes("/servers")) {
|
||||
return Promise.resolve(
|
||||
new Response("", {
|
||||
status: 204,
|
||||
}),
|
||||
new Response(
|
||||
JSON.stringify({
|
||||
servers: [],
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
// Retry create — success
|
||||
return Promise.resolve(new Response(JSON.stringify(serverResp)));
|
||||
// Fallback
|
||||
return Promise.resolve(new Response(JSON.stringify({})));
|
||||
});
|
||||
global.fetch = mockFetch;
|
||||
const { ensureHcloudToken, createServer } = await import("../hetzner/hetzner");
|
||||
await ensureHcloudToken();
|
||||
const conn = await createServer("test-retry", "cx23", "fsn1");
|
||||
expect(conn.ip).toBe("10.0.0.5");
|
||||
// Should have called: token(1), ssh_keys(2), create-fail(3), list-ips(4), delete-ip(5), create-ok(6)
|
||||
// Should have called: token, ssh_keys, create-fail, list-ips, delete-ip, create-ok
|
||||
expect(callCount).toBeGreaterThanOrEqual(6);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue