log.test.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { afterEach, expect, test } from "bun:test"
  2. import fs from "fs/promises"
  3. import path from "path"
  4. import { Global } from "../../src/global"
  5. import { Log } from "../../src/util"
  6. import * as Process from "../../src/util/process" // kilocode_change
  7. import { tmpdir } from "../fixture/fixture"
  8. const log = Global.Path.log
  9. afterEach(() => {
  10. Global.Path.log = log
  11. })
  12. async function files(dir: string) {
  13. let last = ""
  14. let same = 0
  15. for (let i = 0; i < 50; i++) {
  16. const list = (await fs.readdir(dir)).sort()
  17. const next = JSON.stringify(list)
  18. same = next === last ? same + 1 : 0
  19. if (same >= 2 && list.length === 11) return list
  20. last = next
  21. await Bun.sleep(10)
  22. }
  23. return (await fs.readdir(dir)).sort()
  24. }
  25. test("init cleanup keeps the newest timestamped logs", async () => {
  26. await using tmp = await tmpdir()
  27. Global.Path.log = tmp.path
  28. const list = Array.from({ length: 12 }, (_, i) => `2000-01-${String(i + 1).padStart(2, "0")}T000000.log`)
  29. await Promise.all(list.map((file) => fs.writeFile(path.join(tmp.path, file), file)))
  30. await Log.init({ print: false, dev: false })
  31. const next = await files(tmp.path)
  32. expect(next).not.toContain(list[0]!)
  33. expect(next).toContain(list.at(-1)!)
  34. })
  35. // kilocode_change start
  36. const root = path.join(import.meta.dir, "../..")
  37. const worker = path.join(import.meta.dir, "../fixture/log-init-worker.ts")
  38. test("uses single log directory for rotation history", async () => {
  39. await using tmp = await tmpdir()
  40. const out = await Process.run([process.execPath, "--conditions=browser", worker, tmp.path], {
  41. cwd: root,
  42. nothrow: true,
  43. })
  44. const dir = path.join(tmp.path, "share", "kilo", "log")
  45. const history = path.join(dir, ".log-history")
  46. expect(out.code).toBe(0)
  47. expect(out.stderr.toString()).not.toContain("log stream error:")
  48. expect(out.stdout.toString()).toBe(path.join(dir, "dev.log"))
  49. const stat = await fs.stat(history)
  50. expect(stat.isFile()).toBe(true)
  51. })
  52. test("skips rotation rename when active log file is missing", async () => {
  53. await using tmp = await tmpdir()
  54. const out = await Process.run([process.execPath, "--conditions=browser", worker, tmp.path, "missing"], {
  55. cwd: root,
  56. nothrow: true,
  57. })
  58. const dir = path.join(tmp.path, "share", "kilo", "log")
  59. const list = (await fs.readdir(dir)).sort()
  60. const next = list.filter((file) => /^\d{8}-\d{4}-\d{2}-dev\.log$/.test(file))
  61. const stat = await fs.stat(path.join(dir, next[0]!))
  62. expect(out.code).toBe(0)
  63. expect(out.stderr.toString()).not.toContain("log stream error:")
  64. expect(list).toContain("dev.log")
  65. expect(next).toHaveLength(1)
  66. expect(stat.size).toBe(0)
  67. })
  68. // kilocode_change end