-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Expand file tree
/
Copy pathrpc_server_remote_control.e2e.test.ts
More file actions
130 lines (111 loc) · 4.5 KB
/
Copy pathrpc_server_remote_control.e2e.test.ts
File metadata and controls
130 lines (111 loc) · 4.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
*--------------------------------------------------------------------------------------------*/
import { randomUUID } from "node:crypto";
import { describe, expect, it } from "vitest";
import { CopilotClient, RuntimeConnection } from "../../src/index.js";
import { createSdkTestContext, DEFAULT_GITHUB_TOKEN } from "./harness/sdkTestContext.js";
import { formatError } from "./harness/sdkTestHelper.js";
describe("Server-scoped remote-control RPC", async () => {
const { env, workDir } = await createSdkTestContext();
function createDedicatedClient(): CopilotClient {
return new CopilotClient({
workingDirectory: workDir,
env,
logLevel: "error",
connection: RuntimeConnection.forStdio({ path: process.env.COPILOT_CLI_PATH }),
gitHubToken: DEFAULT_GITHUB_TOKEN,
});
}
async function forceStop(client: CopilotClient): Promise<void> {
try {
await client.forceStop();
} catch {
// Runtime may already be gone.
}
}
function uniqueSessionId(prefix: string): string {
return `${prefix}-${randomUUID().replace(/-/g, "")}`;
}
it("should report remote control status as off", { timeout: 120_000 }, async () => {
const client = createDedicatedClient();
try {
await client.start();
const result = await client.rpc.sessions.getRemoteControlStatus();
expect(result.status.state).toBe("off");
} finally {
await forceStop(client);
}
});
it("should treat set steering as no op when off", { timeout: 120_000 }, async () => {
const client = createDedicatedClient();
try {
await client.start();
const result = await client.rpc.sessions.setRemoteControlSteering({ enabled: false });
expect(result.status.state).toBe("off");
} finally {
await forceStop(client);
}
});
it("should report not stopped when remote control is off", { timeout: 120_000 }, async () => {
const client = createDedicatedClient();
try {
await client.start();
const result = await client.rpc.sessions.stopRemoteControl({});
expect(result.stopped).toBe(false);
expect(result.status.state).toBe("off");
} finally {
await forceStop(client);
}
});
it("should reject transfer when off with compare and swap", { timeout: 120_000 }, async () => {
const client = createDedicatedClient();
try {
await client.start();
const result = await client.rpc.sessions.transferRemoteControl({
toSessionId: uniqueSessionId("rc-to"),
expectedFromSessionId: uniqueSessionId("rc-from"),
});
expect(result.transferred).toBe(false);
expect(result.status.state).toBe("off");
} finally {
await forceStop(client);
}
});
it(
"should reach runtime when starting remote control for unknown session",
{ timeout: 120_000 },
async () => {
const client = createDedicatedClient();
try {
await client.start();
await expect(
client.rpc.sessions.startRemoteControl({
sessionId: uniqueSessionId("missing-session"),
config: {
remote: false,
explicit: false,
silent: true,
steerable: false,
},
})
).rejects.toSatisfy((error: unknown) => {
const message = formatError(error);
expect(message.toLowerCase()).not.toContain("unhandled method");
expect(
message.toLowerCase().includes("session") ||
message.toLowerCase().includes("remote")
).toBe(true);
return true;
});
} finally {
try {
await client.rpc.sessions.stopRemoteControl({ force: true });
} catch {
// Best-effort reset.
}
await forceStop(client);
}
}
);
});