@@ -2922,6 +2922,56 @@ describe("update-cli", () => {
|
2922 | 2922 | expect(updateCall?.beforeGitMutation).toEqual(expect.any(Function)); |
2923 | 2923 | }); |
2924 | 2924 | |
| 2925 | +it("stops a managed gateway rooted at the package install when switching package installs to dev", async () => { |
| 2926 | +const packageRoot = await createTrackedTempDir("openclaw-update-package-service-root-"); |
| 2927 | +const packageEntrypoint = path.join(packageRoot, "dist", "index.js"); |
| 2928 | +const gitRoot = await createTrackedTempDir("openclaw-update-git-service-root-"); |
| 2929 | +await fs.mkdir(path.join(gitRoot, ".git"), { recursive: true }); |
| 2930 | +await fs.mkdir(path.dirname(packageEntrypoint), { recursive: true }); |
| 2931 | +await fs.writeFile( |
| 2932 | +path.join(gitRoot, "package.json"), |
| 2933 | +JSON.stringify({ name: "openclaw", version: "2026.4.21" }), |
| 2934 | +"utf-8", |
| 2935 | +); |
| 2936 | +await fs.writeFile( |
| 2937 | +path.join(packageRoot, "package.json"), |
| 2938 | +JSON.stringify({ name: "openclaw", version: "2026.4.20" }), |
| 2939 | +"utf-8", |
| 2940 | +); |
| 2941 | +await fs.writeFile(packageEntrypoint, "export {};\n", "utf-8"); |
| 2942 | +mockPackageInstallStatus(packageRoot); |
| 2943 | +pathExists.mockImplementation(async (candidate: string) => candidate === gitRoot); |
| 2944 | +serviceReadCommand.mockResolvedValue({ |
| 2945 | +programArguments: ["node", packageEntrypoint, "gateway", "run"], |
| 2946 | +environment: { |
| 2947 | +OPENCLAW_SERVICE_MARKER: "openclaw", |
| 2948 | +OPENCLAW_SERVICE_KIND: "gateway", |
| 2949 | +}, |
| 2950 | +}); |
| 2951 | +serviceLoaded.mockResolvedValue(true); |
| 2952 | +serviceReadRuntime.mockResolvedValue({ |
| 2953 | +status: "running", |
| 2954 | +pid: 4242, |
| 2955 | +state: "running", |
| 2956 | +}); |
| 2957 | +mockGitUpdateAfterMutation( |
| 2958 | +makeOkUpdateResult({ |
| 2959 | +mode: "git", |
| 2960 | +root: gitRoot, |
| 2961 | +}), |
| 2962 | +); |
| 2963 | + |
| 2964 | +await withEnvAsync({ OPENCLAW_GIT_DIR: gitRoot }, async () => { |
| 2965 | +await updateCommand({ channel: "dev", yes: true }); |
| 2966 | +}); |
| 2967 | + |
| 2968 | +expect(serviceStop).toHaveBeenCalledTimes(1); |
| 2969 | +expect(runGatewayUpdate).toHaveBeenCalledTimes(1); |
| 2970 | +const updateCall = vi.mocked(runGatewayUpdate).mock.calls[0]?.[0]; |
| 2971 | +expect(updateCall?.cwd).toBe(gitRoot); |
| 2972 | +expect(updateCall?.beforeGitMutation).toEqual(expect.any(Function)); |
| 2973 | +}); |
| 2974 | + |
2925 | 2975 | it("does not stop or restart a managed gateway owned by another git checkout", async () => { |
2926 | 2976 | const otherRoot = await createTrackedTempDir("openclaw-update-other-service-root-"); |
2927 | 2977 | const otherEntrypoint = path.join(otherRoot, "dist", "index.js"); |
|