File
Blob: test/packed-object-store.reads.worker.test.ts
| 1 | import { describe, expect, it } from "vitest"; |
| 2 | import { env, exports as workerExports } from "cloudflare:workers"; |
| 3 | import { objKey } from "@/worker/do/repo/repoState"; |
| 4 | import { readLooseObjectRaw } from "@/worker/git/operations/read/objects"; |
| 5 | import { readObject } from "@/worker/git/object-store"; |
| 6 | import { runDOWithRetry, seedPackedRepo, uniqueRepoId } from "./util/test-helpers"; |
| 7 | import { setupRepoForTests } from "./util/repoSeed"; |
| 8 | |
| 9 | describe("packed object store reads", () => { |
| 10 | it("matches legacy reads and still works after loose objects are deleted", async () => { |
| 11 | const repoId = `o/${uniqueRepoId("pack-object-store")}`; |
| 12 | const id = env.REPO_DO.idFromName(repoId); |
| 13 | const getStub = () => env.REPO_DO.get(id); |
| 14 | const { |
| 15 | getStub: seededStub, |
| 16 | blob, |
| 17 | tree, |
| 18 | commit, |
| 19 | tag, |
| 20 | objectOids, |
| 21 | } = await seedPackedRepo({ |
| 22 | env, |
| 23 | repoId, |
| 24 | getStub, |
| 25 | }); |
| 26 | |
| 27 | for (const obj of [blob, tree, commit, tag]) { |
| 28 | const legacy = await readLooseObjectRaw(env, repoId, obj.oid); |
| 29 | const packed = await readObject(env, repoId, obj.oid); |
| 30 | expect(legacy?.type).toBe(packed?.type); |
| 31 | expect(legacy?.payload).toEqual(packed?.payload); |
| 32 | } |
| 33 | |
| 34 | await runDOWithRetry(seededStub, async (_instance, state) => { |
| 35 | for (const oid of objectOids) await state.storage.delete(objKey(oid)); |
| 36 | }); |
| 37 | |
| 38 | for (const obj of [blob, tree, commit, tag]) { |
| 39 | const packed = await readObject(env, repoId, obj.oid); |
| 40 | expect(packed?.type).toBe( |
| 41 | obj === blob ? "blob" : obj === tree ? "tree" : obj === commit ? "commit" : "tag" |
| 42 | ); |
| 43 | expect(packed?.payload).toEqual(obj.raw.subarray(obj.raw.indexOf(0) + 1)); |
| 44 | } |
| 45 | }); |
| 46 | |
| 47 | it("preserves raw responses in streaming mode", async () => { |
| 48 | const owner = "o"; |
| 49 | const repo = uniqueRepoId("pack-streaming-raw"); |
| 50 | await setupRepoForTests(env, owner, repo); |
| 51 | const repoId = `${owner}/${repo}`; |
| 52 | const id = env.REPO_DO.idFromName(repoId); |
| 53 | const getStub = () => env.REPO_DO.get(id); |
| 54 | const { blob } = await seedPackedRepo({ env, repoId, getStub }); |
| 55 | |
| 56 | const res = await workerExports.default.fetch( |
| 57 | `https://example.com/${owner}/${repo}/raw?oid=${encodeURIComponent(blob.oid)}&name=hello.txt` |
| 58 | ); |
| 59 | expect(res.status).toBe(200); |
| 60 | expect(res.headers.get("content-type")).toContain("text/plain"); |
| 61 | expect(await res.text()).toBe("hello from packed storage\n"); |
| 62 | |
| 63 | const packed = await readObject(env, repoId, blob.oid); |
| 64 | expect(packed?.type).toBe("blob"); |
| 65 | expect(packed?.payload).toEqual(blob.raw.subarray(blob.raw.indexOf(0) + 1)); |
| 66 | }); |
| 67 | }); |