mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 12:50:42 +00:00
test: stabilize gateway wake gating regression
This commit is contained in:
@@ -110,6 +110,7 @@ const { STARTUP_UNAVAILABLE_GATEWAY_METHODS } =
|
||||
await import("./server-startup-unavailable-methods.js");
|
||||
|
||||
type PostAttachParams = Parameters<typeof startGatewayPostAttachRuntime>[0];
|
||||
type PostAttachRuntimeDeps = NonNullable<Parameters<typeof startGatewayPostAttachRuntime>[1]>;
|
||||
|
||||
describe("startGatewayPostAttachRuntime", () => {
|
||||
beforeEach(() => {
|
||||
@@ -144,35 +145,54 @@ describe("startGatewayPostAttachRuntime", () => {
|
||||
});
|
||||
|
||||
it("keeps startup-gated methods unavailable while sidecars are still resuming", async () => {
|
||||
let resumeChannels!: () => void;
|
||||
const channelsReady = new Promise<void>((resolve) => {
|
||||
resumeChannels = resolve;
|
||||
let resumeSidecars!: () => void;
|
||||
const sidecarsReady = new Promise<{ pluginServices: null }>((resolve) => {
|
||||
resumeSidecars = () => resolve({ pluginServices: null });
|
||||
});
|
||||
const startChannels = vi.fn(async () => {
|
||||
await channelsReady;
|
||||
const startGatewaySidecars = vi.fn(async () => {
|
||||
return await sidecarsReady;
|
||||
});
|
||||
const unavailableGatewayMethods = new Set<string>(STARTUP_UNAVAILABLE_GATEWAY_METHODS);
|
||||
|
||||
const startup = startGatewayPostAttachRuntime({
|
||||
...createPostAttachParams({ startChannels }),
|
||||
unavailableGatewayMethods,
|
||||
});
|
||||
const startup = startGatewayPostAttachRuntime(
|
||||
{
|
||||
...createPostAttachParams(),
|
||||
unavailableGatewayMethods,
|
||||
},
|
||||
createPostAttachRuntimeDeps({ startGatewaySidecars }),
|
||||
);
|
||||
|
||||
await vi.waitFor(() => {
|
||||
expect(startChannels).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
await vi.waitFor(
|
||||
() => {
|
||||
expect(startGatewaySidecars).toHaveBeenCalledTimes(1);
|
||||
},
|
||||
{ timeout: 10_000 },
|
||||
);
|
||||
|
||||
expect([...unavailableGatewayMethods]).toEqual([...STARTUP_UNAVAILABLE_GATEWAY_METHODS]);
|
||||
expect(hoisted.startPluginServices).not.toHaveBeenCalled();
|
||||
|
||||
resumeChannels();
|
||||
resumeSidecars();
|
||||
await startup;
|
||||
|
||||
expect([...unavailableGatewayMethods]).toEqual([]);
|
||||
expect(hoisted.startPluginServices).toHaveBeenCalledTimes(1);
|
||||
expect(startGatewaySidecars).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
function createPostAttachRuntimeDeps(
|
||||
overrides: Partial<PostAttachRuntimeDeps> = {},
|
||||
): PostAttachRuntimeDeps {
|
||||
return {
|
||||
getGlobalHookRunner: vi.fn(() => null),
|
||||
logGatewayStartup: hoisted.logGatewayStartup,
|
||||
scheduleGatewayUpdateCheck: hoisted.scheduleGatewayUpdateCheck,
|
||||
startGatewaySidecars: vi.fn(async () => ({ pluginServices: null })),
|
||||
startGatewayTailscaleExposure: hoisted.startGatewayTailscaleExposure,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function createPostAttachParams(overrides: Partial<PostAttachParams> = {}): PostAttachParams {
|
||||
return {
|
||||
minimalTestGateway: false,
|
||||
|
||||
@@ -238,43 +238,62 @@ export async function startGatewaySidecars(params: {
|
||||
return { pluginServices };
|
||||
}
|
||||
|
||||
export async function startGatewayPostAttachRuntime(params: {
|
||||
minimalTestGateway: boolean;
|
||||
cfgAtStart: OpenClawConfig;
|
||||
bindHost: string;
|
||||
bindHosts: string[];
|
||||
port: number;
|
||||
tlsEnabled: boolean;
|
||||
log: {
|
||||
info: (msg: string) => void;
|
||||
warn: (msg: string) => void;
|
||||
};
|
||||
isNixMode: boolean;
|
||||
startupStartedAt?: number;
|
||||
broadcast: (event: string, payload: unknown, opts?: { dropIfSlow?: boolean }) => void;
|
||||
tailscaleMode: GatewayTailscaleMode;
|
||||
resetOnExit: boolean;
|
||||
controlUiBasePath: string;
|
||||
logTailscale: {
|
||||
info: (msg: string) => void;
|
||||
warn: (msg: string) => void;
|
||||
error: (msg: string) => void;
|
||||
debug?: (msg: string) => void;
|
||||
};
|
||||
gatewayPluginConfigAtStart: OpenClawConfig;
|
||||
pluginRegistry: ReturnType<typeof loadOpenClawPlugins>;
|
||||
defaultWorkspaceDir: string;
|
||||
deps: CliDeps;
|
||||
startChannels: () => Promise<void>;
|
||||
logHooks: {
|
||||
info: (msg: string) => void;
|
||||
warn: (msg: string) => void;
|
||||
error: (msg: string) => void;
|
||||
};
|
||||
logChannels: { info: (msg: string) => void; error: (msg: string) => void };
|
||||
unavailableGatewayMethods: Set<string>;
|
||||
}) {
|
||||
logGatewayStartup({
|
||||
type GatewayPostAttachRuntimeDeps = {
|
||||
getGlobalHookRunner: typeof getGlobalHookRunner;
|
||||
logGatewayStartup: typeof logGatewayStartup;
|
||||
scheduleGatewayUpdateCheck: typeof scheduleGatewayUpdateCheck;
|
||||
startGatewaySidecars: typeof startGatewaySidecars;
|
||||
startGatewayTailscaleExposure: typeof startGatewayTailscaleExposure;
|
||||
};
|
||||
|
||||
const defaultGatewayPostAttachRuntimeDeps: GatewayPostAttachRuntimeDeps = {
|
||||
getGlobalHookRunner,
|
||||
logGatewayStartup,
|
||||
scheduleGatewayUpdateCheck,
|
||||
startGatewaySidecars,
|
||||
startGatewayTailscaleExposure,
|
||||
};
|
||||
|
||||
export async function startGatewayPostAttachRuntime(
|
||||
params: {
|
||||
minimalTestGateway: boolean;
|
||||
cfgAtStart: OpenClawConfig;
|
||||
bindHost: string;
|
||||
bindHosts: string[];
|
||||
port: number;
|
||||
tlsEnabled: boolean;
|
||||
log: {
|
||||
info: (msg: string) => void;
|
||||
warn: (msg: string) => void;
|
||||
};
|
||||
isNixMode: boolean;
|
||||
startupStartedAt?: number;
|
||||
broadcast: (event: string, payload: unknown, opts?: { dropIfSlow?: boolean }) => void;
|
||||
tailscaleMode: GatewayTailscaleMode;
|
||||
resetOnExit: boolean;
|
||||
controlUiBasePath: string;
|
||||
logTailscale: {
|
||||
info: (msg: string) => void;
|
||||
warn: (msg: string) => void;
|
||||
error: (msg: string) => void;
|
||||
debug?: (msg: string) => void;
|
||||
};
|
||||
gatewayPluginConfigAtStart: OpenClawConfig;
|
||||
pluginRegistry: ReturnType<typeof loadOpenClawPlugins>;
|
||||
defaultWorkspaceDir: string;
|
||||
deps: CliDeps;
|
||||
startChannels: () => Promise<void>;
|
||||
logHooks: {
|
||||
info: (msg: string) => void;
|
||||
warn: (msg: string) => void;
|
||||
error: (msg: string) => void;
|
||||
};
|
||||
logChannels: { info: (msg: string) => void; error: (msg: string) => void };
|
||||
unavailableGatewayMethods: Set<string>;
|
||||
},
|
||||
runtimeDeps: GatewayPostAttachRuntimeDeps = defaultGatewayPostAttachRuntimeDeps,
|
||||
) {
|
||||
runtimeDeps.logGatewayStartup({
|
||||
cfg: params.cfgAtStart,
|
||||
bindHost: params.bindHost,
|
||||
bindHosts: params.bindHosts,
|
||||
@@ -290,7 +309,7 @@ export async function startGatewayPostAttachRuntime(params: {
|
||||
|
||||
const stopGatewayUpdateCheck = params.minimalTestGateway
|
||||
? () => {}
|
||||
: scheduleGatewayUpdateCheck({
|
||||
: runtimeDeps.scheduleGatewayUpdateCheck({
|
||||
cfg: params.cfgAtStart,
|
||||
log: params.log,
|
||||
isNixMode: params.isNixMode,
|
||||
@@ -302,7 +321,7 @@ export async function startGatewayPostAttachRuntime(params: {
|
||||
|
||||
const tailscaleCleanup = params.minimalTestGateway
|
||||
? null
|
||||
: await startGatewayTailscaleExposure({
|
||||
: await runtimeDeps.startGatewayTailscaleExposure({
|
||||
tailscaleMode: params.tailscaleMode,
|
||||
resetOnExit: params.resetOnExit,
|
||||
port: params.port,
|
||||
@@ -313,7 +332,7 @@ export async function startGatewayPostAttachRuntime(params: {
|
||||
let pluginServices: PluginServicesHandle | null = null;
|
||||
if (!params.minimalTestGateway) {
|
||||
params.log.info("starting channels and sidecars...");
|
||||
({ pluginServices } = await startGatewaySidecars({
|
||||
({ pluginServices } = await runtimeDeps.startGatewaySidecars({
|
||||
cfg: params.gatewayPluginConfigAtStart,
|
||||
pluginRegistry: params.pluginRegistry,
|
||||
defaultWorkspaceDir: params.defaultWorkspaceDir,
|
||||
@@ -329,7 +348,7 @@ export async function startGatewayPostAttachRuntime(params: {
|
||||
}
|
||||
|
||||
if (!params.minimalTestGateway) {
|
||||
const hookRunner = getGlobalHookRunner();
|
||||
const hookRunner = runtimeDeps.getGlobalHookRunner();
|
||||
if (hookRunner?.hasHooks("gateway_start")) {
|
||||
void hookRunner.runGatewayStart({ port: params.port }, { port: params.port }).catch((err) => {
|
||||
params.log.warn(`gateway_start hook failed: ${String(err)}`);
|
||||
|
||||
Reference in New Issue
Block a user