|
1 | 1 | // Plugin Lifecycle Measure tests cover plugin lifecycle measure script behavior. |
2 | 2 | import { spawn, spawnSync, type ChildProcess } from "node:child_process"; |
3 | | -import { existsSync, mkdtempSync, readFileSync, rmSync } from "node:fs"; |
| 3 | +import { |
| 4 | +chmodSync, |
| 5 | +existsSync, |
| 6 | +mkdirSync, |
| 7 | +mkdtempSync, |
| 8 | +readFileSync, |
| 9 | +rmSync, |
| 10 | +writeFileSync, |
| 11 | +} from "node:fs"; |
4 | 12 | import { tmpdir } from "node:os"; |
5 | 13 | import path from "node:path"; |
6 | 14 | import { afterEach, describe, expect, it } from "vitest"; |
@@ -17,6 +25,15 @@ function makeTempDir(): string {
|
17 | 25 | return dir; |
18 | 26 | } |
19 | 27 | |
| 28 | +function writeFakeGetconf(dir: string, body: string): string { |
| 29 | +const binDir = path.join(dir, "bin"); |
| 30 | +mkdirSync(binDir); |
| 31 | +const getconfPath = path.join(binDir, "getconf"); |
| 32 | +writeFileSync(getconfPath, `#!/bin/sh\n${body}\n`, "utf8"); |
| 33 | +chmodSync(getconfPath, 0o755); |
| 34 | +return binDir; |
| 35 | +} |
| 36 | + |
20 | 37 | function pidExists(pid: number): boolean { |
21 | 38 | try { |
22 | 39 | process.kill(pid, 0); |
@@ -75,6 +92,40 @@ afterEach(() => {
|
75 | 92 | }); |
76 | 93 | |
77 | 94 | describe("plugin lifecycle resource sampler", () => { |
| 95 | +it.runIf(process.platform === "linux")( |
| 96 | +"derives proc units from getconf when overrides are absent", |
| 97 | +() => { |
| 98 | +const dir = makeTempDir(); |
| 99 | +const summary = path.join(dir, "summary.tsv"); |
| 100 | +const logPath = path.join(dir, "getconf.log"); |
| 101 | +const binDir = writeFakeGetconf( |
| 102 | +dir, |
| 103 | +'printf "%s\\n" "$1" >>"$GETCONF_LOG"\ncase "$1" in PAGESIZE) echo 16384 ;; CLK_TCK) echo 250 ;; esac', |
| 104 | +); |
| 105 | +const env = { |
| 106 | + ...process.env, |
| 107 | +GETCONF_LOG: logPath, |
| 108 | +PATH: `${binDir}:${process.env.PATH ?? ""}`, |
| 109 | +}; |
| 110 | +delete env.OPENCLAW_PROC_PAGE_SIZE; |
| 111 | +delete env.OPENCLAW_PROC_CLK_TCK; |
| 112 | + |
| 113 | +const result = spawnSync( |
| 114 | +process.execPath, |
| 115 | +[scriptPath, summary, "getconf-units", "--", process.execPath, "-e", ""], |
| 116 | +{ |
| 117 | +cwd: process.cwd(), |
| 118 | +encoding: "utf8", |
| 119 | + env, |
| 120 | +timeout: 5000, |
| 121 | +}, |
| 122 | +); |
| 123 | + |
| 124 | +expect(readFileSync(logPath, "utf8")).toBe("PAGESIZE\nCLK_TCK\n"); |
| 125 | +expect(result.stderr).not.toContain("failed to derive OPENCLAW_PROC"); |
| 126 | +}, |
| 127 | +); |
| 128 | + |
78 | 129 | it("rejects loose numeric env values instead of parsing prefixes", () => { |
79 | 130 | const dir = makeTempDir(); |
80 | 131 | const summary = path.join(dir, "summary.tsv"); |
|