mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-12 03:47:59 +00:00
Update src/__tests__/task-history-retention.spec.ts
Co-authored-by: Seth Miller <sethmillerp@gmail.com>
This commit is contained in:
parent
06df1ca068
commit
64b08fb107
1 changed files with 124 additions and 0 deletions
|
|
@ -138,4 +138,128 @@ describe("utils/task-history-retention.ts purgeOldTasks()", () => {
|
|||
await fs.rm(base, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
it("deletes orphan checkpoint-only directories regardless of age", async () => {
|
||||
const base = await mkTempBase()
|
||||
try {
|
||||
const now = Date.now()
|
||||
const days = (n: number) => n * 24 * 60 * 60 * 1000
|
||||
|
||||
// Create a normal task that is recent (should be kept)
|
||||
const normalTask = await createTask(base, "task-normal", now - days(1))
|
||||
|
||||
// Create an orphan checkpoint-only directory (only has checkpoints/ subdirectory, no metadata)
|
||||
const orphanDir = path.join(base, "tasks", "task-orphan-checkpoints")
|
||||
await fs.mkdir(orphanDir, { recursive: true })
|
||||
const checkpointsDir = path.join(orphanDir, "checkpoints")
|
||||
await fs.mkdir(checkpointsDir, { recursive: true })
|
||||
// Add a dummy file inside checkpoints to make it realistic
|
||||
await fs.writeFile(path.join(checkpointsDir, "checkpoint-1.json"), "{}", "utf8")
|
||||
|
||||
// Create another orphan with just checkpoints (no other files)
|
||||
const orphanDir2 = path.join(base, "tasks", "task-orphan-empty")
|
||||
await fs.mkdir(orphanDir2, { recursive: true })
|
||||
const checkpointsDir2 = path.join(orphanDir2, "checkpoints")
|
||||
await fs.mkdir(checkpointsDir2, { recursive: true })
|
||||
|
||||
// Run purge with 7 day retention - orphans should be deleted regardless of age
|
||||
const { purgedCount } = await purgeOldTasks("7", base, () => {})
|
||||
|
||||
// Orphan directories should be deleted even though they're "recent"
|
||||
expect(await exists(orphanDir)).toBe(false)
|
||||
expect(await exists(orphanDir2)).toBe(false)
|
||||
// Normal task should still exist (it's recent)
|
||||
expect(await exists(normalTask)).toBe(true)
|
||||
// Should have deleted 2 orphan directories
|
||||
expect(purgedCount).toBe(2)
|
||||
} finally {
|
||||
await fs.rm(base, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
it("does not delete directories with checkpoints AND other content", async () => {
|
||||
const base = await mkTempBase()
|
||||
try {
|
||||
const now = Date.now()
|
||||
const days = (n: number) => n * 24 * 60 * 60 * 1000
|
||||
|
||||
// Create a task directory with both checkpoints and other files (but recent, so should be kept)
|
||||
const taskDir = path.join(base, "tasks", "task-with-content")
|
||||
await fs.mkdir(taskDir, { recursive: true })
|
||||
const checkpointsDir = path.join(taskDir, "checkpoints")
|
||||
await fs.mkdir(checkpointsDir, { recursive: true })
|
||||
await fs.writeFile(path.join(checkpointsDir, "checkpoint-1.json"), "{}", "utf8")
|
||||
// Add other files (not just checkpoints)
|
||||
await fs.writeFile(path.join(taskDir, "some-file.txt"), "content", "utf8")
|
||||
// Note: No metadata file, so it's technically invalid but has content
|
||||
|
||||
const { purgedCount } = await purgeOldTasks("7", base, () => {})
|
||||
|
||||
// Should NOT be deleted because it has content besides checkpoints
|
||||
expect(await exists(taskDir)).toBe(true)
|
||||
expect(purgedCount).toBe(0)
|
||||
} finally {
|
||||
await fs.rm(base, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
it("falls back to directory mtime for legacy tasks without metadata", async () => {
|
||||
const base = await mkTempBase()
|
||||
try {
|
||||
const now = Date.now()
|
||||
const days = (n: number) => n * 24 * 60 * 60 * 1000
|
||||
|
||||
// Create a legacy task directory without any metadata file
|
||||
const oldLegacyDir = path.join(base, "tasks", "task-legacy-old")
|
||||
await fs.mkdir(oldLegacyDir, { recursive: true })
|
||||
// Add some content file
|
||||
await fs.writeFile(path.join(oldLegacyDir, "content.txt"), "old task", "utf8")
|
||||
// Manually set mtime to 10 days ago by touching the directory
|
||||
const oldTime = new Date(now - days(10))
|
||||
await fs.utimes(oldLegacyDir, oldTime, oldTime)
|
||||
|
||||
// Create another legacy task that is recent
|
||||
const recentLegacyDir = path.join(base, "tasks", "task-legacy-recent")
|
||||
await fs.mkdir(recentLegacyDir, { recursive: true })
|
||||
await fs.writeFile(path.join(recentLegacyDir, "content.txt"), "recent task", "utf8")
|
||||
// This one has recent mtime (now)
|
||||
|
||||
// Run purge with 7 day retention
|
||||
const { purgedCount } = await purgeOldTasks("7", base, () => {})
|
||||
|
||||
// Old legacy task should be deleted based on mtime
|
||||
expect(await exists(oldLegacyDir)).toBe(false)
|
||||
// Recent legacy task should be kept
|
||||
expect(await exists(recentLegacyDir)).toBe(true)
|
||||
expect(purgedCount).toBe(1)
|
||||
} finally {
|
||||
await fs.rm(base, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
|
||||
it("prioritizes metadata timestamp over mtime when both exist", async () => {
|
||||
const base = await mkTempBase()
|
||||
try {
|
||||
const now = Date.now()
|
||||
const days = (n: number) => n * 24 * 60 * 60 * 1000
|
||||
|
||||
// Create task with old metadata ts but recent mtime
|
||||
const taskDir = path.join(base, "tasks", "task-priority-test")
|
||||
await fs.mkdir(taskDir, { recursive: true })
|
||||
const metadataPath = path.join(taskDir, GlobalFileNames.taskMetadata)
|
||||
// Metadata says it's 10 days old (should be deleted with 7 day retention)
|
||||
const metadata = JSON.stringify({ ts: now - days(10) }, null, 2)
|
||||
await fs.writeFile(metadataPath, metadata, "utf8")
|
||||
// But directory mtime is recent (could happen after editing)
|
||||
// (Directory mtime is automatically recent from mkdir/writeFile)
|
||||
|
||||
const { purgedCount } = await purgeOldTasks("7", base, () => {})
|
||||
|
||||
// Should be deleted based on metadata ts, not mtime
|
||||
expect(await exists(taskDir)).toBe(false)
|
||||
expect(purgedCount).toBe(1)
|
||||
} finally {
|
||||
await fs.rm(base, { recursive: true, force: true })
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue