Skip to content
File

Blob: test/packed-object-store.delta.worker.test.ts

typescript95 lines
1import { describe, expect, it } from "vitest";
2import { env } from "cloudflare:workers";
3import { concatChunks, encodeGitObject } from "@/worker/git/core";
4import { readObject } from "@/worker/git/object-store";
5import {
6 buildAppendOnlyDelta,
7 buildPack,
8 callStubWithRetry,
9 seedLegacyPackedRepo,
10 uniqueRepoId,
11} from "./util/test-helpers";
12 
13describe("packed object store deltas", () => {
14 it("resolves OFS_DELTA blobs from pack-only storage", async () => {
15 const repoId = `o/${uniqueRepoId("pack-ofs-delta")}`;
16 const basePayload = new TextEncoder().encode("delta base\n");
17 const suffix = new TextEncoder().encode("plus ofs delta\n");
18 const resultPayload = concatChunks([basePayload, suffix]);
19 const baseBlob = await encodeGitObject("blob", basePayload);
20 const deltaBlob = await encodeGitObject("blob", resultPayload);
21 const id = env.REPO_DO.idFromName(repoId);
22 const getStub = () => env.REPO_DO.get(id);
23 
24 const packBytes = await buildPack([
25 { type: "blob", payload: basePayload },
26 {
27 type: "ofs-delta",
28 baseIndex: 0,
29 delta: buildAppendOnlyDelta(basePayload, suffix),
30 },
31 ]);
32 
33 const { getStub: seededStub } = await seedLegacyPackedRepo({
34 env,
35 repoId,
36 getStub,
37 packs: [{ name: "pack-ofs-delta.pack", packBytes }],
38 });
39 
40 const catalog = await callStubWithRetry(seededStub, (stub) => stub.getActivePackCatalog());
41 expect(catalog).toHaveLength(1);
42 
43 const loadedBase = await readObject(env, repoId, baseBlob.oid);
44 const loadedDelta = await readObject(env, repoId, deltaBlob.oid);
45 expect(loadedBase?.type).toBe("blob");
46 expect(loadedBase?.payload).toEqual(basePayload);
47 expect(loadedDelta?.type).toBe("blob");
48 expect(loadedDelta?.payload).toEqual(resultPayload);
49 });
50 
51 it("resolves REF_DELTA blobs across active catalog packs", async () => {
52 const repoId = `o/${uniqueRepoId("pack-ref-delta")}`;
53 const basePayload = new TextEncoder().encode("older pack blob\n");
54 const suffix = new TextEncoder().encode("newer ref delta\n");
55 const resultPayload = concatChunks([basePayload, suffix]);
56 const baseBlob = await encodeGitObject("blob", basePayload);
57 const deltaBlob = await encodeGitObject("blob", resultPayload);
58 const id = env.REPO_DO.idFromName(repoId);
59 const getStub = () => env.REPO_DO.get(id);
60 
61 const basePackBytes = await buildPack([{ type: "blob", payload: basePayload }]);
62 const refPackBytes = await buildPack([
63 {
64 type: "ref-delta",
65 baseOid: baseBlob.oid,
66 delta: buildAppendOnlyDelta(basePayload, suffix),
67 },
68 ]);
69 
70 // Pass packs newest-first to match production catalog chronology. The
71 // helper indexes them oldest-to-newest so the base pack is still visible
72 // when the newer REF_DELTA pack is indexed.
73 const { getStub: seededStub, packKeys } = await seedLegacyPackedRepo({
74 env,
75 repoId,
76 getStub,
77 packs: [
78 { name: "pack-ref-delta.pack", packBytes: refPackBytes },
79 { name: "pack-base.pack", packBytes: basePackBytes },
80 ],
81 looseObjects: [baseBlob],
82 });
83 
84 const catalog = await callStubWithRetry(seededStub, (stub) => stub.getActivePackCatalog());
85 expect(catalog.map((row) => row.packKey)).toEqual(packKeys);
86 
87 const loadedBase = await readObject(env, repoId, baseBlob.oid);
88 const loadedDelta = await readObject(env, repoId, deltaBlob.oid);
89 expect(loadedBase?.type).toBe("blob");
90 expect(loadedBase?.payload).toEqual(basePayload);
91 expect(loadedDelta?.type).toBe("blob");
92 expect(loadedDelta?.payload).toEqual(resultPayload);
93 });
94});