Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions src/eslint-suppressions.json
Original file line number Diff line number Diff line change
Expand Up @@ -1499,11 +1499,6 @@
"count": 3
}
},
"services/code-index/semble/semble-downloader.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
}
},
"services/code-index/shared/__tests__/validation-helpers.spec.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ vi.mock("fs/promises", () => ({
readdir: vi.fn().mockResolvedValue([]),
}))

vi.mock("proper-lockfile", () => ({
lock: vi.fn().mockResolvedValue(vi.fn().mockResolvedValue(undefined)),
}))

// Mock fs (createWriteStream and createReadStream for checksum verification)
const mockWriteStream = {
on: vi.fn(),
Expand Down Expand Up @@ -263,12 +267,14 @@ describe("semble-downloader", () => {
)
// Version file should be written
expect(fs.writeFile).toHaveBeenCalledWith(
path.join("/storage", "semble", ".semble-version"),
path.join("/storage", "semble.new", ".semble-version"),
"v0.4.1",
"utf-8",
)
// Archive should be cleaned up (version-prefixed local cache path)
expect(fs.unlink).toHaveBeenCalledWith(path.join("/storage", "v0.4.1-semble-linux-x64-fast.tar.gz"))
expect(fs.rm).toHaveBeenCalledWith(path.join("/storage", "v0.4.1-semble-linux-x64-fast.tar.gz"), {
force: true,
})
} finally {
if (originalPlatform) Object.defineProperty(process, "platform", originalPlatform)
if (originalArch) Object.defineProperty(process, "arch", originalArch)
Expand Down Expand Up @@ -325,7 +331,9 @@ describe("semble-downloader", () => {

try {
await expect(downloadSemble("/storage")).rejects.toThrow("Failed to download semble")
expect(fs.unlink).toHaveBeenCalledWith(path.join("/storage", "v0.4.1-semble-linux-arm64-fast.tar.gz"))
expect(fs.rm).toHaveBeenCalledWith(path.join("/storage", "v0.4.1-semble-linux-arm64-fast.tar.gz"), {
force: true,
})
// Should clean up staging directory, not the original
expect(fs.rm).toHaveBeenCalledWith(path.join("/storage", "semble.new"), {
recursive: true,
Expand Down Expand Up @@ -589,7 +597,7 @@ describe("semble-downloader", () => {
})

// Archive cleanup fails but should not throw (only archive removal after extraction)
;(fs.unlink as any).mockRejectedValue(new Error("unlink cleanup failed"))
;(fs.rm as any).mockRejectedValueOnce(new Error("archive cleanup failed"))

try {
const result = await downloadSemble("/storage")
Expand Down Expand Up @@ -641,7 +649,7 @@ describe("semble-downloader", () => {
expect(https.get).toHaveBeenCalledWith(expect.stringContaining("v0.4.1"), expect.any(Function))
// Should write the new version file
expect(fs.writeFile).toHaveBeenCalledWith(
path.join("/storage", "semble", ".semble-version"),
path.join("/storage", "semble.new", ".semble-version"),
"v0.4.1",
"utf-8",
)
Expand Down Expand Up @@ -700,19 +708,23 @@ describe("semble-downloader", () => {
)
// The stale archive is removed before the fresh download to guarantee
// a clean package is verified against the new checksum.
expect(fs.unlink).toHaveBeenCalledWith(versionedArchive)
expect(fs.rm).toHaveBeenCalledWith(versionedArchive, { force: true })
// The prior-version archive (v0.4.0-*) is swept by cleanupStaleArchives
// after a successful install, so a version upgrade doesn't accumulate
// orphaned packages on disk.
expect(fs.unlink).toHaveBeenCalledWith(path.join("/storage", "v0.4.0-semble-linux-x64-fast.tar.gz"))
expect(fs.rm).toHaveBeenCalledWith(path.join("/storage", "v0.4.0-semble-linux-x64-fast.tar.gz"), {
force: true,
})
// The legacy unversioned archive (pre-v0.4.0 cache layout) is also
// swept, covering the v0.3.1 → v0.4.1 upgrade path.
expect(fs.unlink).toHaveBeenCalledWith(path.join("/storage", "semble-linux-x64-fast.tar.gz"))
expect(fs.rm).toHaveBeenCalledWith(path.join("/storage", "semble-linux-x64-fast.tar.gz"), {
force: true,
})
// Unrelated files in the storage dir must not be touched.
expect(fs.unlink).not.toHaveBeenCalledWith(path.join("/storage", "unrelated-file.txt"))
expect(fs.rm).not.toHaveBeenCalledWith(path.join("/storage", "unrelated-file.txt"), expect.anything())
// The new version file is recorded
expect(fs.writeFile).toHaveBeenCalledWith(
path.join("/storage", "semble", ".semble-version"),
path.join("/storage", "semble.new", ".semble-version"),
Comment thread
coderabbitai[bot] marked this conversation as resolved.
"v0.4.1",
"utf-8",
)
Expand Down Expand Up @@ -789,7 +801,7 @@ describe("semble-downloader", () => {
)
// Should write version file again
expect(fs.writeFile).toHaveBeenCalledWith(
path.join("/storage", "semble", ".semble-version"),
path.join("/storage", "semble.new", ".semble-version"),
"v0.4.1",
"utf-8",
)
Expand Down Expand Up @@ -831,7 +843,7 @@ describe("semble-downloader", () => {
)
// Should write version file
expect(fs.writeFile).toHaveBeenCalledWith(
path.join("/storage", "semble", ".semble-version"),
path.join("/storage", "semble.new", ".semble-version"),
"v0.4.1",
"utf-8",
)
Expand Down Expand Up @@ -903,8 +915,12 @@ describe("semble-downloader", () => {

const currentArchive = path.join("/storage", "v0.4.1-semble-linux-x64-fast.tar.gz")
// Stale versioned + legacy unversioned archives are swept
expect(fs.unlink).toHaveBeenCalledWith(path.join("/storage", "v0.4.0-semble-linux-x64-fast.tar.gz"))
expect(fs.unlink).toHaveBeenCalledWith(path.join("/storage", "semble-linux-x64-fast.tar.gz"))
expect(fs.rm).toHaveBeenCalledWith(path.join("/storage", "v0.4.0-semble-linux-x64-fast.tar.gz"), {
force: true,
})
expect(fs.rm).toHaveBeenCalledWith(path.join("/storage", "semble-linux-x64-fast.tar.gz"), {
force: true,
})
// The current archive is never swept by cleanupStaleArchives (it is
// excluded by the currentArchivePath guard). It is unlinked only by
// the pre-download partial-archive cleanup and the post-install
Expand All @@ -913,8 +929,8 @@ describe("semble-downloader", () => {
// Sanity: the current archive path is never passed to the stale sweep.
// It is unlinked exactly twice (pre-download cleanup + post-install
// archive cleanup), never via cleanupStaleArchives.
const currentUnlinks = (fs.unlink as any).mock.calls.filter((c: any[]) => c[0] === currentArchive)
expect(currentUnlinks.length).toBe(2)
const currentRemovals = (fs.rm as any).mock.calls.filter((c: any[]) => c[0] === currentArchive)
expect(currentRemovals.length).toBe(2)
} finally {
if (originalPlatform) Object.defineProperty(process, "platform", originalPlatform)
if (originalArch) Object.defineProperty(process, "arch", originalArch)
Expand Down
Loading
Loading