File
Blob: test/upload-pack-acks.test.ts
| 1 | import { assert, test } from "vitest"; |
| 2 | import type { PktItem } from "@/worker/git/core"; |
| 3 | import { concatChunks, decodePktLines, flushPkt } from "@/worker/git"; |
| 4 | import { buildAckSection } from "@/worker/git/operations/fetch/protocol"; |
| 5 | import { createSidebandPacketChunks } from "@/worker/git/operations/fetch/sideband"; |
| 6 | |
| 7 | function findLine(items: PktItem[], text: string): number { |
| 8 | return items.findIndex((item) => item.type === "line" && item.text === text); |
| 9 | } |
| 10 | |
| 11 | function expectLine(item: PktItem | undefined) { |
| 12 | if (!item || item.type !== "line") { |
| 13 | throw new Error("expected pkt line"); |
| 14 | } |
| 15 | return item; |
| 16 | } |
| 17 | |
| 18 | function buildPacketizedResponse( |
| 19 | packfile: Uint8Array, |
| 20 | done: boolean, |
| 21 | ackOids: string[] |
| 22 | ): Uint8Array { |
| 23 | return concatChunks([ |
| 24 | ...buildAckSection(ackOids, done), |
| 25 | ...createSidebandPacketChunks(1, packfile), |
| 26 | flushPkt(), |
| 27 | ]); |
| 28 | } |
| 29 | |
| 30 | test("packetized response emits NAK when no common haves and done=false", () => { |
| 31 | const items = decodePktLines( |
| 32 | buildPacketizedResponse(new Uint8Array([0x50, 0x41, 0x43, 0x4b]), false, []) |
| 33 | ); |
| 34 | |
| 35 | const ackIndex = findLine(items, "acknowledgments\n"); |
| 36 | assert.isTrue(ackIndex >= 0); |
| 37 | assert.strictEqual(expectLine(items[ackIndex + 1]).text, "NAK\n"); |
| 38 | assert.strictEqual(items[ackIndex + 2]?.type, "delim"); |
| 39 | assert.strictEqual(expectLine(items[ackIndex + 3]).text, "packfile\n"); |
| 40 | const bandLine = expectLine(items[ackIndex + 4]); |
| 41 | assert.isTrue((bandLine.raw?.length || 0) >= 1); |
| 42 | assert.strictEqual(bandLine.raw?.[0], 0x01); |
| 43 | }); |
| 44 | |
| 45 | test("packetized response emits ACK common lines and the final ready line", () => { |
| 46 | const firstOid = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; |
| 47 | const secondOid = "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"; |
| 48 | const items = decodePktLines( |
| 49 | buildPacketizedResponse(new Uint8Array([0xaa]), false, [firstOid, secondOid]) |
| 50 | ); |
| 51 | |
| 52 | const ackIndex = findLine(items, "acknowledgments\n"); |
| 53 | assert.isTrue(ackIndex >= 0); |
| 54 | assert.strictEqual(expectLine(items[ackIndex + 1]).text, `ACK ${firstOid} common\n`); |
| 55 | assert.strictEqual(expectLine(items[ackIndex + 2]).text, `ACK ${secondOid} ready\n`); |
| 56 | assert.strictEqual(items[ackIndex + 3]?.type, "delim"); |
| 57 | }); |
| 58 | |
| 59 | test("packetized response omits acknowledgments when done=true", () => { |
| 60 | const items = decodePktLines(buildPacketizedResponse(new Uint8Array([0xff, 0x00]), true, [])); |
| 61 | assert.isTrue(findLine(items, "packfile\n") >= 0); |
| 62 | assert.strictEqual(findLine(items, "acknowledgments\n"), -1); |
| 63 | }); |