Use internal API route for edge E2E in CI
This commit is contained in:
@@ -84,6 +84,29 @@ function baseUrlWithHost(baseUrl, host, port = null) {
|
||||
return normalizeBaseUrl(url.toString());
|
||||
}
|
||||
|
||||
function directCaddyBaseUrl(baseUrl) {
|
||||
const url = new URL(normalizeBaseUrl(baseUrl));
|
||||
url.hostname = "caddy";
|
||||
url.port = "";
|
||||
if (url.pathname === "/api" || url.pathname === "/api/") {
|
||||
url.pathname = "/";
|
||||
}
|
||||
return normalizeBaseUrl(url.toString());
|
||||
}
|
||||
|
||||
function resolveBrokerWebSocketUrl(rawUrl, apiBaseUrl) {
|
||||
const websocketUrl = new URL(String(rawUrl));
|
||||
const apiUrl = new URL(normalizeBaseUrl(apiBaseUrl));
|
||||
|
||||
if (apiUrl.hostname === "caddy" && websocketUrl.hostname === "caddy") {
|
||||
websocketUrl.hostname = "edge-broker";
|
||||
websocketUrl.port = "4300";
|
||||
websocketUrl.pathname = websocketUrl.pathname.replace(/^\/edge-broker(?=\/|$)/, "") || "/";
|
||||
}
|
||||
|
||||
return websocketUrl.toString();
|
||||
}
|
||||
|
||||
async function readDefaultGatewayHost() {
|
||||
if (process.platform === "win32") {
|
||||
return null;
|
||||
@@ -185,6 +208,18 @@ async function connectCurrentContainerToComposeNetwork(rootDir, composeProject)
|
||||
return false;
|
||||
}
|
||||
|
||||
async function disconnectCurrentContainerFromComposeNetwork(rootDir, composeProject) {
|
||||
const containerRef = await readCurrentContainerRef();
|
||||
if (!containerRef) {
|
||||
return;
|
||||
}
|
||||
|
||||
await runCommand("docker", ["network", "disconnect", composeNetworkName(composeProject), containerRef], {
|
||||
cwd: rootDir,
|
||||
allowFailure: true,
|
||||
});
|
||||
}
|
||||
|
||||
async function readComposeServiceHost(rootDir, composeProject, serviceName) {
|
||||
const ps = await runCommand("docker", composeArgs(composeProject, ["ps", "-q", serviceName]), {
|
||||
cwd: rootDir,
|
||||
@@ -216,15 +251,17 @@ async function readComposeServiceHost(rootDir, composeProject, serviceName) {
|
||||
return null;
|
||||
}
|
||||
|
||||
async function candidateApiBaseUrls(baseUrl, rootDir, composeProject) {
|
||||
async function candidateApiBaseUrls(baseUrl, rootDir, composeProject, useComposeNetwork = false) {
|
||||
const normalized = normalizeBaseUrl(baseUrl);
|
||||
const candidates = [normalized];
|
||||
const url = new URL(normalized);
|
||||
|
||||
if (["localhost", "127.0.0.1", "::1"].includes(url.hostname)) {
|
||||
if (rootDir && composeProject) {
|
||||
await connectCurrentContainerToComposeNetwork(rootDir, composeProject);
|
||||
candidates.push(baseUrlWithHost(normalized, "traefik", ""));
|
||||
if (useComposeNetwork) {
|
||||
candidates.push(directCaddyBaseUrl(normalized));
|
||||
candidates.push(baseUrlWithHost(normalized, "traefik", ""));
|
||||
}
|
||||
|
||||
const traefikHost = await readComposeServiceHost(rootDir, composeProject, "traefik");
|
||||
if (traefikHost) {
|
||||
@@ -264,8 +301,8 @@ async function ensureComposeServices(rootDir, composeProject) {
|
||||
});
|
||||
}
|
||||
|
||||
async function waitForApiReady(baseUrl, rootDir, composeProject, attempts = 60) {
|
||||
const candidates = await candidateApiBaseUrls(baseUrl, rootDir, composeProject);
|
||||
async function waitForApiReady(baseUrl, rootDir, composeProject, useComposeNetwork = false, attempts = 60) {
|
||||
const candidates = await candidateApiBaseUrls(baseUrl, rootDir, composeProject, useComposeNetwork);
|
||||
let lastError = "API never responded";
|
||||
|
||||
for (let attempt = 0; attempt < attempts; attempt += 1) {
|
||||
@@ -526,10 +563,12 @@ async function main() {
|
||||
let gatewayId = null;
|
||||
let streamSocket = null;
|
||||
let shellSocket = null;
|
||||
let runnerNetworkAttached = false;
|
||||
|
||||
try {
|
||||
await ensureComposeServices(rootDir, composeProject);
|
||||
baseUrl = await waitForApiReady(baseUrl, rootDir, composeProject);
|
||||
runnerNetworkAttached = await connectCurrentContainerToComposeNetwork(rootDir, composeProject);
|
||||
baseUrl = await waitForApiReady(baseUrl, rootDir, composeProject, runnerNetworkAttached);
|
||||
process.stdout.write(`Using API base URL ${baseUrl}\n`);
|
||||
|
||||
fixture = await runPhpFixture(rootDir, composeProject, "create");
|
||||
@@ -643,7 +682,10 @@ async function main() {
|
||||
scopes: ["overview", "tasks", "logs", "statistics"],
|
||||
},
|
||||
});
|
||||
const streamWsUrl = buildSocketUrl(String(streamSession?.data?.ws_url || ""), String(streamSession?.data?.token || ""));
|
||||
const streamWsUrl = buildSocketUrl(
|
||||
resolveBrokerWebSocketUrl(String(streamSession?.data?.ws_url || ""), baseUrl),
|
||||
String(streamSession?.data?.token || "")
|
||||
);
|
||||
streamSocket = new WebSocketImpl(streamWsUrl);
|
||||
const streamMessages = collectSocketMessages(streamSocket);
|
||||
|
||||
@@ -771,7 +813,10 @@ async function main() {
|
||||
rows: 40,
|
||||
},
|
||||
});
|
||||
const shellWsUrl = buildSocketUrl(String(shellSession?.data?.ws_url || ""), String(shellSession?.data?.token || ""));
|
||||
const shellWsUrl = buildSocketUrl(
|
||||
resolveBrokerWebSocketUrl(String(shellSession?.data?.ws_url || ""), baseUrl),
|
||||
String(shellSession?.data?.token || "")
|
||||
);
|
||||
shellSocket = new WebSocketImpl(shellWsUrl);
|
||||
const shellMessages = collectSocketMessages(shellSocket);
|
||||
|
||||
@@ -843,6 +888,10 @@ async function main() {
|
||||
}
|
||||
|
||||
await fs.rm(configDir, { recursive: true, force: true }).catch(() => {});
|
||||
|
||||
if (runnerNetworkAttached) {
|
||||
await disconnectCurrentContainerFromComposeNetwork(rootDir, composeProject).catch(() => {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user