Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
e87e0b3
fix(e2e): restore sandbox fake API reachability
prekshivyas Sep 1, 2026
7165c49
Merge remote-tracking branch 'origin/main' into codex/fix-e2e-proxy-b…
prekshivyas Sep 1, 2026
e450ab9
test(e2e): map Hermes Discord bridge proof
prekshivyas Sep 1, 2026
55d311b
fix(e2e): harden fake API proxy readiness
prekshivyas Sep 1, 2026
ba045b8
test(e2e): complete fake API proxy migration
prekshivyas Sep 1, 2026
5591017
test(e2e): capture fake API startup diagnostics
prekshivyas Sep 1, 2026
6333239
test(e2e): prove proxy upstream reachability
prekshivyas Sep 1, 2026
cef370f
test(e2e): preserve proxy failure diagnostics
prekshivyas Sep 1, 2026
1406187
fix(e2e): handle proxy readiness socket errors
cv Sep 1, 2026
d33e618
test(e2e): handle proxy readiness resets
prekshivyas Sep 1, 2026
d10fdcf
fix(e2e): tighten Discord fixture diagnostics
cv Sep 1, 2026
d1f1bcb
refactor(e2e): consolidate fake API readiness
prekshivyas Sep 1, 2026
848f5fd
test(e2e): map pairing helper parity proof
cv Sep 1, 2026
d545462
test(e2e): remove retired Vitest import
cv Sep 1, 2026
b0bc674
test(e2e): own pairing helper parity
prekshivyas Sep 1, 2026
639f64b
test(e2e): clarify best-effort diagnostics
cv Sep 1, 2026
be75a56
test(e2e): verify fake API Docker topology
prekshivyas Sep 1, 2026
2b796e5
test(e2e): strengthen fake API topology proofs
cv Sep 1, 2026
404dba6
test(e2e): use valid Discord fixture contract
cv Sep 1, 2026
b098f29
test(e2e): complete topology regression proof
prekshivyas Sep 1, 2026
a360c93
refactor(e2e): inline Hermes fixture setup
cv Sep 1, 2026
8f1fccc
test(e2e): use independent topology evidence
prekshivyas Sep 1, 2026
2cba16d
fix(e2e): preserve stopped fixture diagnostics
prekshivyas Sep 1, 2026
be5d0c6
test(e2e): prove fake API Docker topology
prekshivyas Sep 1, 2026
d672507
test(e2e): register topology proof parity
prekshivyas Sep 1, 2026
7e89676
fix(e2e): scope Hermes Discord policy binary
prekshivyas Sep 1, 2026
9eff794
test(e2e): assert diagnostic artifact outcomes
prekshivyas Sep 1, 2026
dc16294
Merge remote-tracking branch 'origin/main' into codex/fix-e2e-proxy-b…
prekshivyas Sep 1, 2026
18ee35f
fix(e2e): keep proxy environment credential-free
prekshivyas Sep 1, 2026
3c8d563
refactor(e2e): consolidate topology validation
prekshivyas Sep 1, 2026
3796452
test(e2e): derive topology from Docker commands
prekshivyas Sep 1, 2026
b3bb16e
test(e2e): isolate proxy proof environment
prekshivyas Sep 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions test/e2e/live/hermes-discord.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const DISCORD_SERVER_IDS = process.env.DISCORD_SERVER_IDS ?? "149159099275359059
const DISCORD_ALLOWED_IDS = process.env.DISCORD_ALLOWED_IDS ?? "1005536447329222676";
const DISCORD_REQUIRE_MENTION = process.env.DISCORD_REQUIRE_MENTION ?? "0";
const HERMES_HEALTH_URL = "http://localhost:8642/health";
const FAKE_DISCORD_HOST = "host.docker.internal";
const FAKE_DISCORD_HOST = "host.openshell.internal";
const HERMES_DISCORD_HTTP_PROXY_GATEWAY_TEMPLATE = hermesDiscordHttpProxyWebSocketUrl(
"{host}",
"{port}",
Expand Down Expand Up @@ -267,7 +267,7 @@ results = []

async def main():
port = int(os.environ["FAKE_DISCORD_GATEWAY_CLIENT_PORT"])
host = os.environ.get("FAKE_DISCORD_GATEWAY_CLIENT_HOST", "host.docker.internal")
host = os.environ.get("FAKE_DISCORD_GATEWAY_CLIENT_HOST", "host.openshell.internal")
token = read_env_token()
client = discord.Client(intents=discord.Intents.none())
setup = getattr(client, "_async_setup_hook", None)
Expand Down
54 changes: 49 additions & 5 deletions test/e2e/live/messaging-providers-helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

import crypto from "node:crypto";
import fs from "node:fs";
import { isIPv4 } from "node:net";
import os from "node:os";
import path from "node:path";

Expand Down Expand Up @@ -41,6 +42,7 @@ export const LIVE_TIMEOUT_MS = 90 * 60_000;
export const OPENSHELL_EXEC_ARGUMENT_LIMIT_BYTES = 32_768;
const FAKE_API_IMAGE =
"node:22-trixie-slim@sha256:db8a96a63e5264607ada2d206758876ebbed6a12be2ada7517793cbfb0c2a29c";
const DEFAULT_OPENSHELL_DOCKER_NETWORK = "openshell-docker";
const FAKE_API_PROXY_SOURCE = String.raw`
const net = require("node:net");
const upstream = process.env.NEMOCLAW_FAKE_API_UPSTREAM;
Expand Down Expand Up @@ -656,6 +658,46 @@ export async function startFakeDockerApi(
const containerPorts = options.kind === "slack" ? [8080, 8081] : [8080];
fs.writeFileSync(captureFile, "");

const openshellNetwork =
options.env.OPENSHELL_DOCKER_NETWORK_NAME ??
process.env.OPENSHELL_DOCKER_NETWORK_NAME ??
DEFAULT_OPENSHELL_DOCKER_NETWORK;
const openshellNetworkInspect = await runHost(
host,
"docker",
["network", "inspect", openshellNetwork],
{
artifactName: `inspect-fake-${options.kind}-openshell-network`,
env: options.env,
redactionValues: options.redactionValues,
timeoutMs: 30_000,
},
);
expectExitZero(openshellNetworkInspect, "inspect OpenShell Docker network");
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
let openshellNetworkRecords: unknown;
try {
openshellNetworkRecords = JSON.parse(openshellNetworkInspect.stdout);
} catch {
throw new Error("OpenShell Docker network inspection returned invalid JSON");
}
const openshellBridgeAddress =
Array.isArray(openshellNetworkRecords) && openshellNetworkRecords.length === 1
? (
openshellNetworkRecords[0] as {
Driver?: unknown;
IPAM?: { Config?: Array<{ Gateway?: unknown }> };
}
).IPAM?.Config?.find((entry) => typeof entry.Gateway === "string" && isIPv4(entry.Gateway))
?.Gateway
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
: undefined;
if (
(openshellNetworkRecords as Array<{ Driver?: unknown }> | undefined)?.[0]?.Driver !==
"bridge" ||
typeof openshellBridgeAddress !== "string"
) {
throw new Error("OpenShell Docker network has no IPv4 bridge gateway");
}

const networkCreate = await runHost(
host,
"docker",
Expand Down Expand Up @@ -772,7 +814,7 @@ export async function startFakeDockerApi(
proxyContainer,
"--network",
"bridge",
...containerPorts.flatMap((port) => ["-p", `127.0.0.1::${String(port)}`]),
...containerPorts.flatMap((port) => ["-p", `${openshellBridgeAddress}::${String(port)}`]),
"--read-only",
"--cap-drop",
"ALL",
Expand Down Expand Up @@ -824,11 +866,13 @@ export async function startFakeDockerApi(
},
);
expectExitZero(result, `read fake ${options.kind} API proxy port`);
const hostPort = result.stdout.trim().match(/^127\.0\.0\.1:(\d+)$/u)?.[1];
if (!hostPort) {
throw new Error(`fake ${options.kind} API proxy port did not bind only to 127.0.0.1`);
const published = result.stdout.trim().match(/^(\d+\.\d+\.\d+\.\d+):(\d+)$/u);
if (published?.[1] !== openshellBridgeAddress || !published[2]) {
throw new Error(
`fake ${options.kind} API proxy port did not bind only to the OpenShell bridge`,
);
}
return hostPort;
return published[2];
};

const publishedRestPort = await publishedPort(8080, `port-fake-${options.kind}-api`);
Expand Down
32 changes: 23 additions & 9 deletions test/e2e/support/messaging-providers-runtime-proofs.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ import { parseInstalledWechatProof } from "../live/messaging-providers-wechat-ru
const FAKE_TELEGRAM_API = path.resolve(import.meta.dirname, "../lib/fake-telegram-api.cjs");
const FAKE_SLACK_API = path.resolve(import.meta.dirname, "../lib/fake-slack-api.cjs");
const FAKE_WECHAT_API = path.resolve(import.meta.dirname, "../lib/fake-wechat-api.mts");
const OPENSHELL_BRIDGE_ADDRESS = "172.18.0.1";
const OPENSHELL_NETWORK_INSPECT = JSON.stringify([
{
Driver: "bridge",
IPAM: { Config: [{ Subnet: "172.18.0.0/16", Gateway: OPENSHELL_BRIDGE_ADDRESS }] },
},
]);

async function waitFor(predicate: () => boolean, message: string): Promise<void> {
const deadline = Date.now() + 5_000;
Expand Down Expand Up @@ -56,7 +63,7 @@ function successfulCommand(stdout = "") {
};
}

function fakeDockerHost(publishedAddress = "127.0.0.1"): {
function fakeDockerHost(publishedAddress = OPENSHELL_BRIDGE_ADDRESS): {
calls: string[][];
host: HostCliClient;
} {
Expand All @@ -71,9 +78,11 @@ function fakeDockerHost(publishedAddress = "127.0.0.1"): {
const fixtureDir = fakeApiMount.slice(0, -":/tmp/fake".length);
fs.writeFileSync(path.join(fixtureDir, "port"), "8080");
});
return args[0] === "port"
? successfulCommand(`${publishedAddress}:${args[2] === "8081/tcp" ? "32101" : "32100"}\n`)
: successfulCommand();
return args[0] === "network" && args[1] === "inspect"
? successfulCommand(OPENSHELL_NETWORK_INSPECT)
: args[0] === "port"
? successfulCommand(`${publishedAddress}:${args[2] === "8081/tcp" ? "32101" : "32100"}\n`)
: successfulCommand();
},
} as unknown as HostCliClient;
return { calls, host };
Expand All @@ -85,10 +94,14 @@ async function runCleanup(actions: CleanupAction[]): Promise<void> {

describe("messaging provider installed-runtime proofs", () => {
it.each([
["discord-gateway", ["127.0.0.1::8080"], ["8080/tcp"]],
["slack", ["127.0.0.1::8080", "127.0.0.1::8081"], ["8080/tcp", "8081/tcp"]],
["discord-gateway", [`${OPENSHELL_BRIDGE_ADDRESS}::8080`], ["8080/tcp"]],
[
"slack",
[`${OPENSHELL_BRIDGE_ADDRESS}::8080`, `${OPENSHELL_BRIDGE_ADDRESS}::8081`],
["8080/tcp", "8081/tcp"],
],
] as const)(
"proxies the isolated fake %s API through loopback-only ephemeral ports",
"proxies the isolated fake %s API through OpenShell-bridge ephemeral ports",
async (kind, expectedPublications, expectedPortQueries) => {
const { calls, host } = fakeDockerHost();
const cleanup: CleanupAction[] = [];
Expand Down Expand Up @@ -118,6 +131,7 @@ describe("messaging provider installed-runtime proofs", () => {
argument === "-p" ? [proxyRun[index + 1]] : [],
);

expect(calls).toContainEqual(["network", "inspect", "openshell-docker"]);
expect(createdNetwork.slice(0, -1)).toEqual(["network", "create", "--internal"]);
expect(apiRun).toEqual(expect.arrayContaining(["--network", network]));
expect(apiRun).not.toContain("-p");
Expand All @@ -137,7 +151,7 @@ describe("messaging provider installed-runtime proofs", () => {
},
);

it("rejects a fake API proxy port that Docker publishes beyond loopback", async () => {
it("rejects a fake API proxy port that Docker publishes beyond the OpenShell bridge", async () => {
const { host } = fakeDockerHost("0.0.0.0");
const cleanup: CleanupAction[] = [];

Expand All @@ -154,7 +168,7 @@ describe("messaging provider installed-runtime proofs", () => {
redactionValues: [],
env: {},
}),
).rejects.toThrow(/did not bind only to 127\.0\.0\.1/u);
).rejects.toThrow(/did not bind only to the OpenShell bridge/u);
} finally {
await runCleanup(cleanup);
}
Expand Down
Loading