process.test.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import { describe, expect, test } from "bun:test"
  2. import { Process } from "../../src/util/process"
  3. import { tmpdir } from "../fixture/fixture"
  4. function node(script: string) {
  5. return [process.execPath, "-e", script]
  6. }
  7. describe("util.process", () => {
  8. test("captures stdout and stderr", async () => {
  9. const out = await Process.run(node('process.stdout.write("out");process.stderr.write("err")'))
  10. expect(out.code).toBe(0)
  11. expect(out.stdout.toString()).toBe("out")
  12. expect(out.stderr.toString()).toBe("err")
  13. })
  14. test("returns code when nothrow is enabled", async () => {
  15. const out = await Process.run(node("process.exit(7)"), { nothrow: true })
  16. expect(out.code).toBe(7)
  17. })
  18. test("throws RunFailedError on non-zero exit", async () => {
  19. const err = await Process.run(node('process.stderr.write("bad");process.exit(3)')).catch((error) => error)
  20. expect(err).toBeInstanceOf(Process.RunFailedError)
  21. if (!(err instanceof Process.RunFailedError)) throw err
  22. expect(err.code).toBe(3)
  23. expect(err.stderr.toString()).toBe("bad")
  24. })
  25. test("aborts a running process", async () => {
  26. const abort = new AbortController()
  27. const started = Date.now()
  28. setTimeout(() => abort.abort(), 25)
  29. const out = await Process.run(node("setInterval(() => {}, 1000)"), {
  30. abort: abort.signal,
  31. nothrow: true,
  32. })
  33. expect(out.code).not.toBe(0)
  34. expect(Date.now() - started).toBeLessThan(1000)
  35. }, 3000)
  36. test("kills after timeout when process ignores terminate signal", async () => {
  37. if (process.platform === "win32") return
  38. const abort = new AbortController()
  39. const started = Date.now()
  40. setTimeout(() => abort.abort(), 25)
  41. const out = await Process.run(node('process.on("SIGTERM", () => {}); setInterval(() => {}, 1000)'), {
  42. abort: abort.signal,
  43. nothrow: true,
  44. timeout: 25,
  45. })
  46. expect(out.code).not.toBe(0)
  47. expect(Date.now() - started).toBeLessThan(1000)
  48. }, 3000)
  49. test("uses cwd when spawning commands", async () => {
  50. await using tmp = await tmpdir()
  51. const out = await Process.run(node("process.stdout.write(process.cwd())"), {
  52. cwd: tmp.path,
  53. })
  54. expect(out.stdout.toString()).toBe(tmp.path)
  55. })
  56. test("merges environment overrides", async () => {
  57. const out = await Process.run(node('process.stdout.write(process.env.OPENCODE_TEST ?? "")'), {
  58. env: {
  59. OPENCODE_TEST: "set",
  60. },
  61. })
  62. expect(out.stdout.toString()).toBe("set")
  63. })
  64. })