@mycadet/cli 0.12.6-dev.202610082233.54244ee → 0.12.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/eslint.config.mjs +7 -0
- package/node_modules/@mycadet/local-mode/src/__tests__/environment.test.ts +1 -4
- package/node_modules/@mycadet/local-mode/src/config.ts +14 -19
- package/node_modules/@mycadet/local-mode/src/index.ts +5 -0
- package/node_modules/@mycadet/local-mode/src/local-signing-key.ts +73 -0
- package/node_modules/@mycadet/local-mode/src/lockfile.ts +18 -3
- package/package.json +4 -3
- package/src/__tests__/assistant-config.test.ts +30 -28
- package/src/__tests__/debug.test.ts +8 -8
- package/src/__tests__/default-main-screen-formatting.test.ts +5 -4
- package/src/__tests__/flags.test.ts +2 -2
- package/src/__tests__/hatch-provider-secrets.test.ts +3 -3
- package/src/__tests__/ingress-config.test.ts +2 -2
- package/src/__tests__/login-loopback.test.ts +1 -1
- package/src/__tests__/nginx-ingress.test.ts +68 -76
- package/src/__tests__/pair.test.ts +135 -121
- package/src/__tests__/platform-client.test.ts +2 -2
- package/src/__tests__/recover.test.ts +96 -3
- package/src/__tests__/retire.test.ts +5 -3
- package/src/__tests__/signing-key-continuity.test.ts +261 -0
- package/src/__tests__/sleep.test.ts +189 -6
- package/src/__tests__/tailscale-tunnel.test.ts +1 -1
- package/src/__tests__/uninstall.test.ts +171 -0
- package/src/__tests__/upgrade-local.test.ts +16 -3
- package/src/__tests__/use.test.ts +2 -2
- package/src/__tests__/wake-error.test.ts +76 -0
- package/src/__tests__/wake.test.ts +309 -36
- package/src/commands/backup.ts +6 -2
- package/src/commands/clean.ts +6 -2
- package/src/commands/client.ts +91 -41
- package/src/commands/confirm.ts +6 -2
- package/src/commands/connect.ts +6 -2
- package/src/commands/debug.ts +6 -2
- package/src/commands/devices.ts +6 -2
- package/src/commands/events.ts +6 -2
- package/src/commands/exec.ts +50 -12
- package/src/commands/flags.ts +6 -2
- package/src/commands/gateway.ts +6 -2
- package/src/commands/hatch.ts +6 -2
- package/src/commands/login.ts +26 -356
- package/src/commands/logs.ts +6 -2
- package/src/commands/message.ts +6 -2
- package/src/commands/pair.ts +6 -2
- package/src/commands/ps.ts +7 -2
- package/src/commands/recover.ts +21 -16
- package/src/commands/restore.ts +6 -2
- package/src/commands/retire.ts +6 -2
- package/src/commands/roadmap.ts +6 -2
- package/src/commands/rollback.ts +6 -2
- package/src/commands/setup.ts +76 -9
- package/src/commands/sleep.ts +131 -31
- package/src/commands/ssh.ts +6 -2
- package/src/commands/teleport.ts +6 -2
- package/src/commands/terminal.ts +6 -2
- package/src/commands/tunnel.ts +6 -2
- package/src/commands/uninstall.ts +228 -0
- package/src/commands/unpair.ts +6 -2
- package/src/commands/upgrade.ts +13 -8
- package/src/commands/use.ts +6 -2
- package/src/commands/voice.ts +6 -2
- package/src/commands/wake.ts +69 -37
- package/src/commands/workflows.ts +6 -2
- package/src/components/DefaultMainScreen.tsx +250 -36
- package/src/index.ts +23 -55
- package/src/lib/assistant-config.ts +27 -13
- package/src/lib/backup-ops.ts +3 -4
- package/src/lib/cli-error.ts +5 -0
- package/src/lib/client-identity.ts +8 -10
- package/src/lib/cloud-login.ts +422 -0
- package/src/lib/color.ts +16 -0
- package/src/lib/default-main-screen-formatting.ts +32 -8
- package/src/lib/environments/__tests__/paths.test.ts +9 -11
- package/src/lib/environments/paths.ts +2 -20
- package/src/lib/guardian-token.ts +72 -18
- package/src/lib/hatch-local.ts +52 -1
- package/src/lib/health-check.ts +24 -15
- package/src/lib/lifecycle-reporter.ts +9 -1
- package/src/lib/local-hatch-lock.ts +19 -27
- package/src/lib/local-runtime-client.ts +25 -14
- package/src/lib/local.ts +17 -43
- package/src/lib/ngrok.ts +48 -16
- package/src/lib/platform-client.ts +141 -72
- package/src/lib/retire-archive.ts +4 -4
- package/src/lib/retire-local.ts +2 -25
- package/src/lib/teleport-backup.ts +23 -9
- package/src/lib/terminal-client.ts +21 -9
- package/src/lib/tunnel-edge.ts +11 -13
- package/src/lib/upgrade-lifecycle.ts +16 -4
- package/src/lib/workos-pkce.ts +52 -21
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as childProcess from "node:child_process";
|
|
2
|
-
import type { ChildProcess } from "node:child_process";
|
|
3
2
|
import { createHash } from "node:crypto";
|
|
4
3
|
import * as fsModule from "node:fs";
|
|
5
4
|
import {
|
|
@@ -23,6 +22,8 @@ import {
|
|
|
23
22
|
test,
|
|
24
23
|
} from "bun:test";
|
|
25
24
|
|
|
25
|
+
import { z } from "zod";
|
|
26
|
+
|
|
26
27
|
import * as httpClient from "../lib/http-client.js";
|
|
27
28
|
import type { AssistantEntry } from "../lib/assistant-config.js";
|
|
28
29
|
|
|
@@ -91,7 +92,7 @@ const workspaces: string[] = [];
|
|
|
91
92
|
const fakePids = new Map<number, { alive: boolean; unkillable?: boolean }>();
|
|
92
93
|
|
|
93
94
|
function installKillMock(): void {
|
|
94
|
-
process.kill = mock((targetPid: number, signal?: string | number) => {
|
|
95
|
+
process.kill = mock((targetPid: number, signal?: string | number): true => {
|
|
95
96
|
const entry = fakePids.get(targetPid);
|
|
96
97
|
if (!entry) {
|
|
97
98
|
return originalKill(targetPid, signal);
|
|
@@ -107,7 +108,7 @@ function installKillMock(): void {
|
|
|
107
108
|
}
|
|
108
109
|
entry.alive = false;
|
|
109
110
|
return true;
|
|
110
|
-
})
|
|
111
|
+
});
|
|
111
112
|
}
|
|
112
113
|
|
|
113
114
|
afterEach(() => {
|
|
@@ -135,10 +136,18 @@ function makeWorkspace(): string {
|
|
|
135
136
|
return dir;
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
139
|
+
const IngressTestConfigSchema = z.object({
|
|
140
|
+
ingress: z
|
|
141
|
+
.object({
|
|
142
|
+
nginx: z.record(z.string(), z.unknown()).optional(),
|
|
143
|
+
})
|
|
144
|
+
.optional(),
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
function readConfig(workspaceDir: string) {
|
|
148
|
+
return IngressTestConfigSchema.parse(
|
|
149
|
+
JSON.parse(readFileSync(join(workspaceDir, "config.json"), "utf-8")),
|
|
150
|
+
);
|
|
142
151
|
}
|
|
143
152
|
|
|
144
153
|
describe("buildIngressNginxConfig", () => {
|
|
@@ -571,7 +580,7 @@ describe("nginx ingress process state", () => {
|
|
|
571
580
|
writeIngressState(ws, 7841);
|
|
572
581
|
writePidFile(ws, pid);
|
|
573
582
|
execFileSyncMock.mockReturnValue(nginxCommand(ws));
|
|
574
|
-
process.kill = mock((targetPid: number, signal?: string | number) => {
|
|
583
|
+
process.kill = mock((targetPid: number, signal?: string | number): true => {
|
|
575
584
|
if (targetPid !== pid) return originalKill(targetPid, signal);
|
|
576
585
|
if (signal === 0) {
|
|
577
586
|
if (!alive) throw new Error("dead");
|
|
@@ -582,12 +591,12 @@ describe("nginx ingress process state", () => {
|
|
|
582
591
|
return true;
|
|
583
592
|
}
|
|
584
593
|
return true;
|
|
585
|
-
})
|
|
594
|
+
});
|
|
586
595
|
|
|
587
596
|
await expect(stopIngressNginx(ws)).resolves.toBe(true);
|
|
588
597
|
|
|
589
598
|
const config = readConfig(ws);
|
|
590
|
-
expect(
|
|
599
|
+
expect(config.ingress?.nginx).toBeUndefined();
|
|
591
600
|
expect(existsSync(pidPath(ws))).toBe(false);
|
|
592
601
|
});
|
|
593
602
|
|
|
@@ -597,16 +606,16 @@ describe("nginx ingress process state", () => {
|
|
|
597
606
|
writeIngressState(ws, 7841);
|
|
598
607
|
writePidFile(ws, pid);
|
|
599
608
|
execFileSyncMock.mockReturnValue(nginxCommand(ws));
|
|
600
|
-
process.kill = mock((targetPid: number, signal?: string | number) => {
|
|
609
|
+
process.kill = mock((targetPid: number, signal?: string | number): true => {
|
|
601
610
|
if (targetPid !== pid) return originalKill(targetPid, signal);
|
|
602
611
|
if (signal === 0) return true;
|
|
603
612
|
throw new Error("operation not permitted");
|
|
604
|
-
})
|
|
613
|
+
});
|
|
605
614
|
|
|
606
615
|
await expect(stopIngressNginx(ws)).resolves.toBe(false);
|
|
607
616
|
|
|
608
617
|
const config = readConfig(ws);
|
|
609
|
-
expect(
|
|
618
|
+
expect(config.ingress?.nginx).toEqual({
|
|
610
619
|
listenPort: 7841,
|
|
611
620
|
});
|
|
612
621
|
expect(existsSync(pidPath(ws))).toBe(true);
|
|
@@ -619,7 +628,7 @@ describe("nginx ingress process state", () => {
|
|
|
619
628
|
writeIngressState(ws, 7841);
|
|
620
629
|
writePidFile(ws, pid);
|
|
621
630
|
execFileSyncMock.mockReturnValue(nginxCommand(ws));
|
|
622
|
-
process.kill = mock((targetPid: number, signal?: string | number) => {
|
|
631
|
+
process.kill = mock((targetPid: number, signal?: string | number): true => {
|
|
623
632
|
if (targetPid !== pid) return originalKill(targetPid, signal);
|
|
624
633
|
if (signal === 0) {
|
|
625
634
|
aliveChecks++;
|
|
@@ -627,12 +636,12 @@ describe("nginx ingress process state", () => {
|
|
|
627
636
|
throw new Error("dead");
|
|
628
637
|
}
|
|
629
638
|
throw new Error("no such process");
|
|
630
|
-
})
|
|
639
|
+
});
|
|
631
640
|
|
|
632
641
|
await expect(stopIngressNginx(ws)).resolves.toBe(true);
|
|
633
642
|
|
|
634
643
|
const config = readConfig(ws);
|
|
635
|
-
expect(
|
|
644
|
+
expect(config.ingress?.nginx).toBeUndefined();
|
|
636
645
|
expect(existsSync(pidPath(ws))).toBe(false);
|
|
637
646
|
});
|
|
638
647
|
|
|
@@ -644,16 +653,16 @@ describe("nginx ingress process state", () => {
|
|
|
644
653
|
execFileSyncMock.mockReturnValue(
|
|
645
654
|
"nginx: master process nginx -p /tmp/other-ingress -c /tmp/other-ingress/nginx.conf",
|
|
646
655
|
);
|
|
647
|
-
process.kill = mock((targetPid: number, signal?: string | number) => {
|
|
656
|
+
process.kill = mock((targetPid: number, signal?: string | number): true => {
|
|
648
657
|
if (targetPid !== pid) return originalKill(targetPid, signal);
|
|
649
658
|
if (signal === 0) return true;
|
|
650
659
|
throw new Error("should not kill another nginx instance");
|
|
651
|
-
})
|
|
660
|
+
});
|
|
652
661
|
|
|
653
662
|
await expect(stopIngressNginx(ws)).resolves.toBe(false);
|
|
654
663
|
|
|
655
664
|
const config = readConfig(ws);
|
|
656
|
-
expect(
|
|
665
|
+
expect(config.ingress?.nginx).toBeUndefined();
|
|
657
666
|
expect(existsSync(pidPath(ws))).toBe(false);
|
|
658
667
|
});
|
|
659
668
|
});
|
|
@@ -708,25 +717,20 @@ function mockNginxSpawn(): void {
|
|
|
708
717
|
psArgs?.includes(String(SPAWNED_NGINX_PID))
|
|
709
718
|
? `nginx: master process nginx -p ${dir} -c ${join(dir, "nginx.conf")} -g daemon off;`
|
|
710
719
|
: "") as typeof childProcess.execFileSync);
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
exitCode: null,
|
|
715
|
-
pid: SPAWNED_NGINX_PID,
|
|
716
|
-
} as unknown as ChildProcess;
|
|
720
|
+
const child = new childProcess.ChildProcess();
|
|
721
|
+
Object.assign(child, { pid: SPAWNED_NGINX_PID });
|
|
722
|
+
return child;
|
|
717
723
|
}) as unknown as typeof childProcess.spawn);
|
|
718
724
|
}
|
|
719
725
|
|
|
720
726
|
/** Spawned nginx that exits on startup, as when the listen port is already bound. */
|
|
721
727
|
function mockNginxSpawnExitsOnStartup(): void {
|
|
722
|
-
spawnMock.mockReturnValue(
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
},
|
|
727
|
-
|
|
728
|
-
pid: SPAWNED_NGINX_PID,
|
|
729
|
-
} as unknown as ChildProcess);
|
|
728
|
+
spawnMock.mockReturnValue(
|
|
729
|
+
Object.assign(new childProcess.ChildProcess(), {
|
|
730
|
+
pid: SPAWNED_NGINX_PID,
|
|
731
|
+
exitCode: 1,
|
|
732
|
+
}),
|
|
733
|
+
);
|
|
730
734
|
}
|
|
731
735
|
|
|
732
736
|
/**
|
|
@@ -735,20 +739,13 @@ function mockNginxSpawnExitsOnStartup(): void {
|
|
|
735
739
|
*/
|
|
736
740
|
function mockNginxSpawnExitsAfterProbe(): void {
|
|
737
741
|
spawnMock.mockImplementation((() => {
|
|
738
|
-
const child =
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
child.exitCode = 1;
|
|
746
|
-
listener();
|
|
747
|
-
}, 150);
|
|
748
|
-
}
|
|
749
|
-
},
|
|
750
|
-
};
|
|
751
|
-
return child as unknown as ChildProcess;
|
|
742
|
+
const child = new childProcess.ChildProcess();
|
|
743
|
+
Object.assign(child, { pid: SPAWNED_NGINX_PID });
|
|
744
|
+
setTimeout(() => {
|
|
745
|
+
Object.assign(child, { exitCode: 1 });
|
|
746
|
+
child.emit("exit", 1);
|
|
747
|
+
}, 150);
|
|
748
|
+
return child;
|
|
752
749
|
}) as unknown as typeof childProcess.spawn);
|
|
753
750
|
}
|
|
754
751
|
|
|
@@ -944,7 +941,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
944
941
|
expect(conf).not.toContain("__remote-index.html");
|
|
945
942
|
expect(conf).not.toContain("location ^~ /assistant/assets/");
|
|
946
943
|
expect(conf).not.toContain("alias ");
|
|
947
|
-
expect(
|
|
944
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
948
945
|
listenPort: 7845,
|
|
949
946
|
includeWebApp: false,
|
|
950
947
|
gatewayPort: 7830,
|
|
@@ -995,7 +992,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
995
992
|
expect(indexHtml).toContain(`"hubUrl":"${PRODUCTION_HUB_URL}"`);
|
|
996
993
|
// No assistant name was provided, so the served config omits the label.
|
|
997
994
|
expect(indexHtml).not.toContain("assistantName");
|
|
998
|
-
expect(
|
|
995
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
999
996
|
listenPort: 7845,
|
|
1000
997
|
includeWebApp: true,
|
|
1001
998
|
gatewayPort: 7830,
|
|
@@ -1206,7 +1203,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1206
1203
|
}),
|
|
1207
1204
|
);
|
|
1208
1205
|
expect(conf).toContain("proxy_pass http://127.0.0.1:7830;");
|
|
1209
|
-
expect(
|
|
1206
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
1210
1207
|
listenPort: 7845,
|
|
1211
1208
|
includeWebApp: false,
|
|
1212
1209
|
gatewayPort: 7830,
|
|
@@ -1243,7 +1240,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1243
1240
|
ipv6Loopback: hasIpv6Loopback(),
|
|
1244
1241
|
}),
|
|
1245
1242
|
);
|
|
1246
|
-
expect(
|
|
1243
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
1247
1244
|
listenPort: 7845,
|
|
1248
1245
|
includeWebApp: false,
|
|
1249
1246
|
gatewayPort: 7900,
|
|
@@ -1335,7 +1332,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1335
1332
|
"utf-8",
|
|
1336
1333
|
);
|
|
1337
1334
|
expect(indexHtml).toContain('"assistantName":"New Name"');
|
|
1338
|
-
expect(
|
|
1335
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
1339
1336
|
listenPort: 7845,
|
|
1340
1337
|
includeWebApp: true,
|
|
1341
1338
|
gatewayPort: 7830,
|
|
@@ -1382,7 +1379,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1382
1379
|
expect(edge.killed()).toBe(true);
|
|
1383
1380
|
const conf = realFs.readFileSync(ingressConfPath(ws), "utf-8");
|
|
1384
1381
|
expect(conf).toContain("location = /readyz {");
|
|
1385
|
-
expect(
|
|
1382
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
1386
1383
|
listenPort: 7845,
|
|
1387
1384
|
includeWebApp: true,
|
|
1388
1385
|
gatewayPort: 7830,
|
|
@@ -1410,7 +1407,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1410
1407
|
|
|
1411
1408
|
expect(result.status).toBe("started");
|
|
1412
1409
|
expect(edge.killed()).toBe(true);
|
|
1413
|
-
expect(
|
|
1410
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
1414
1411
|
listenPort: 7845,
|
|
1415
1412
|
includeWebApp: true,
|
|
1416
1413
|
gatewayPort: 7830,
|
|
@@ -1479,7 +1476,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1479
1476
|
ipv6Loopback: hasIpv6Loopback(),
|
|
1480
1477
|
}),
|
|
1481
1478
|
);
|
|
1482
|
-
expect(
|
|
1479
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
1483
1480
|
listenPort: 7845,
|
|
1484
1481
|
includeWebApp: false,
|
|
1485
1482
|
gatewayPort: 7830,
|
|
@@ -1495,11 +1492,11 @@ describe("startRemoteWebIngress", () => {
|
|
|
1495
1492
|
// Alive for the initial running check, dead by the time the stop helper
|
|
1496
1493
|
// probes it: the race where the old edge exits on its own mid-switch.
|
|
1497
1494
|
let liveChecks = 0;
|
|
1498
|
-
process.kill = mock((targetPid: number, signal?: string | number) => {
|
|
1495
|
+
process.kill = mock((targetPid: number, signal?: string | number): true => {
|
|
1499
1496
|
if (targetPid !== pid) return originalKill(targetPid, signal);
|
|
1500
1497
|
if (signal === 0 && ++liveChecks === 1) return true;
|
|
1501
1498
|
throw new Error("dead");
|
|
1502
|
-
})
|
|
1499
|
+
});
|
|
1503
1500
|
|
|
1504
1501
|
const result = await startRemoteWebIngress({
|
|
1505
1502
|
workspaceDir: ws,
|
|
@@ -1523,7 +1520,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1523
1520
|
ipv6Loopback: hasIpv6Loopback(),
|
|
1524
1521
|
}),
|
|
1525
1522
|
);
|
|
1526
|
-
expect(
|
|
1523
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
1527
1524
|
listenPort: 7845,
|
|
1528
1525
|
includeWebApp: false,
|
|
1529
1526
|
gatewayPort: 7830,
|
|
@@ -1552,7 +1549,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1552
1549
|
expect(spawnMock).toHaveBeenCalledTimes(1);
|
|
1553
1550
|
const conf = realFs.readFileSync(ingressConfPath(ws), "utf-8");
|
|
1554
1551
|
expect(conf).toContain("location ^~ /assistant/ {");
|
|
1555
|
-
expect(
|
|
1552
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
1556
1553
|
listenPort: 7845,
|
|
1557
1554
|
includeWebApp: true,
|
|
1558
1555
|
gatewayPort: 7830,
|
|
@@ -1577,7 +1574,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1577
1574
|
expect(result).toEqual({ status: "web-dist-missing" });
|
|
1578
1575
|
expect(edge.killed()).toBe(false);
|
|
1579
1576
|
expect(spawnMock).not.toHaveBeenCalled();
|
|
1580
|
-
expect(
|
|
1577
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
1581
1578
|
listenPort: 7845,
|
|
1582
1579
|
includeWebApp: false,
|
|
1583
1580
|
});
|
|
@@ -1606,9 +1603,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1606
1603
|
logPath: join(ws, "data", "logs", "nginx-ingress.log"),
|
|
1607
1604
|
});
|
|
1608
1605
|
expect(spawnMock).toHaveBeenCalledTimes(1);
|
|
1609
|
-
const ingress = readConfig(ws).ingress
|
|
1610
|
-
| Record<string, unknown>
|
|
1611
|
-
| undefined;
|
|
1606
|
+
const ingress = readConfig(ws).ingress;
|
|
1612
1607
|
expect(ingress?.nginx).toBeUndefined();
|
|
1613
1608
|
});
|
|
1614
1609
|
|
|
@@ -1635,9 +1630,7 @@ describe("startRemoteWebIngress", () => {
|
|
|
1635
1630
|
logPath: join(ws, "data", "logs", "nginx-ingress.log"),
|
|
1636
1631
|
});
|
|
1637
1632
|
expect(spawnMock).toHaveBeenCalledTimes(1);
|
|
1638
|
-
const ingress = readConfig(ws).ingress
|
|
1639
|
-
| Record<string, unknown>
|
|
1640
|
-
| undefined;
|
|
1633
|
+
const ingress = readConfig(ws).ingress;
|
|
1641
1634
|
expect(ingress?.nginx).toBeUndefined();
|
|
1642
1635
|
});
|
|
1643
1636
|
|
|
@@ -1698,16 +1691,15 @@ describe("startRemoteWebIngress", () => {
|
|
|
1698
1691
|
// Alive for the whole settle window (nginx retrying its bind), never
|
|
1699
1692
|
// writes a pid file; an orphan left running could win the bind later.
|
|
1700
1693
|
spawnMock.mockImplementation((() => {
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
exitCode: null,
|
|
1694
|
+
const child = new childProcess.ChildProcess();
|
|
1695
|
+
Object.assign(child, {
|
|
1704
1696
|
pid: SPAWNED_NGINX_PID,
|
|
1705
|
-
once: () => {},
|
|
1706
1697
|
kill: (signal: string) => {
|
|
1707
1698
|
kills.push(signal);
|
|
1708
1699
|
return true;
|
|
1709
1700
|
},
|
|
1710
|
-
}
|
|
1701
|
+
});
|
|
1702
|
+
return child;
|
|
1711
1703
|
}) as unknown as typeof childProcess.spawn);
|
|
1712
1704
|
|
|
1713
1705
|
const result = await startRemoteWebIngress({
|
|
@@ -1758,7 +1750,7 @@ describe("ensureTunnelEdge", () => {
|
|
|
1758
1750
|
mockNginxSpawn();
|
|
1759
1751
|
mockWebDistPresent();
|
|
1760
1752
|
writeFileSync(
|
|
1761
|
-
join(lockfileDir, ".
|
|
1753
|
+
join(lockfileDir, "lockfile.json"),
|
|
1762
1754
|
JSON.stringify({
|
|
1763
1755
|
assistants: [
|
|
1764
1756
|
{
|
|
@@ -1845,7 +1837,7 @@ describe("ensureTunnelEdge", () => {
|
|
|
1845
1837
|
mockWebDistPresent();
|
|
1846
1838
|
const writeLockfile = (name: string) =>
|
|
1847
1839
|
writeFileSync(
|
|
1848
|
-
join(lockfileDir, ".
|
|
1840
|
+
join(lockfileDir, "lockfile.json"),
|
|
1849
1841
|
JSON.stringify({
|
|
1850
1842
|
assistants: [
|
|
1851
1843
|
{
|
|
@@ -2036,7 +2028,7 @@ describe("ensureTunnelEdge", () => {
|
|
|
2036
2028
|
const conf = realFs.readFileSync(ingressConfPath(ws), "utf-8");
|
|
2037
2029
|
expect(conf).toContain("location ^~ /assistant/ {");
|
|
2038
2030
|
expect(conf).toContain("location ^~ /webhooks/ {");
|
|
2039
|
-
expect(
|
|
2031
|
+
expect(readConfig(ws).ingress?.nginx).toEqual({
|
|
2040
2032
|
listenPort: REQUESTED_PORT,
|
|
2041
2033
|
includeWebApp: true,
|
|
2042
2034
|
gatewayPort: 7830,
|
|
@@ -2180,7 +2172,7 @@ describe("stopContainerTunnelEdge", () => {
|
|
|
2180
2172
|
assistantId: "docker-1",
|
|
2181
2173
|
runtimeUrl: `http://localhost:${port}`,
|
|
2182
2174
|
cloud: "docker",
|
|
2183
|
-
}
|
|
2175
|
+
};
|
|
2184
2176
|
}
|
|
2185
2177
|
|
|
2186
2178
|
test("stops the default-workspace edge fronting this assistant", async () => {
|
|
@@ -2224,7 +2216,7 @@ describe("stopContainerTunnelEdge", () => {
|
|
|
2224
2216
|
assistantId: "docker-1",
|
|
2225
2217
|
runtimeUrl: "https://runtime.example.com/docker-1",
|
|
2226
2218
|
cloud: "docker",
|
|
2227
|
-
}
|
|
2219
|
+
}),
|
|
2228
2220
|
).toBe(false);
|
|
2229
2221
|
expect(killed()).toBe(false);
|
|
2230
2222
|
});
|