From a0be6a068cbc10798f724b855cb41046609d51f0 Mon Sep 17 00:00:00 2001 From: HampusM Date: Sat, 24 Jul 2021 23:06:39 +0200 Subject: Improved the git http unit test --- test/unit/git-http.unit.test.ts | 107 ++++++++++++++++++++++++++++++---------- 1 file changed, 82 insertions(+), 25 deletions(-) (limited to 'test/unit/git-http.unit.test.ts') diff --git a/test/unit/git-http.unit.test.ts b/test/unit/git-http.unit.test.ts index 944ba7d..de281fb 100644 --- a/test/unit/git-http.unit.test.ts +++ b/test/unit/git-http.unit.test.ts @@ -1,25 +1,32 @@ import { FastifyInstance } from "fastify"; import buildApp from "server/src/app"; import { EnvironmentVariables } from "../util"; -import { readFile } from "fs/promises"; -import { Readable } from "stream"; +import { readFile } from "fs-extra"; +import { exec, ExecException } from "child_process"; const env = process.env as EnvironmentVariables; +const host = "localhost"; +const port = 8080; + describe("Git HTTP backend", () => { let app: FastifyInstance; beforeAll(() => { app = buildApp({ - host: "localhost", - port: 1337, - dev_port: 8080, - title: "lmao", - about: "lmao", - base_dir: "/tmp/githermit_test", + host: host, + port: port, + dev_port: 0, // Doesn't matter + title: "", + about: "", + base_dir: env.BASE_DIR, production: false }, ""); }); + + afterAll(async () => { + await app.close(); + }) describe("info/refs", () => { it("Should make a valid response when the service is git-upload-pack", async () => { @@ -58,26 +65,76 @@ describe("Git HTTP backend", () => { describe("git-upload-pack", () => { it("Should make a valid response", async () => { - expect.assertions(6); + await app.listen(port); + + const head = /^[a-f0-9]+/.exec((await readFile(`${env.BASE_DIR}/${env.AVAIL_REPO}/FETCH_HEAD`)).toString())[0]; + const data = `0098want ${head} multi_ack_detailed no-done side-band-64k thin-pack ofs-delta deepen-since deepen-not agent=git/2.32.0\n00000009done`; + + // I did it this way because i just couldn't get chunked responses + // to work with LightMyRequest or Supertest + const res = new Promise((resolve: (value: Record) => void, reject: (value: ExecException) => void) => { + const curl_params = [ + "-X POST", + "-s", + "-H \"Content-Type: application/x-git-upload-pack-request\"", + "-T -" + ].join(" "); + const command = `echo "${data}" | curl ${curl_params} http://${host}:${port}/${env.AVAIL_REPO}/git-upload-pack`; + + exec(command, { maxBuffer: 5368709120, encoding: "buffer" }, (err, stdout, stderr) => { + if(err) { + reject(err); + return; + } + resolve({ stdout, stderr }); + }); + }); - const head = /^[a-f0-9]+/.exec((await readFile(env.BASE_DIR + "/" + env.AVAIL_REPO + "/FETCH_HEAD")).toString()); + const { stdout, stderr } = await res; - const res = await app.inject({ - method: "POST", - url: `${env.AVAIL_REPO}/git-upload-pack`, - payload: Readable.from([`0098want ${head} multi_ack_detailed no-done side-band-64k thin-pack ofs-delta deepen-since deepen-not agent=git/2.32.0\n\ -00000009done`]), - headers: { - "content-type": "application/x-git-upload-pack-request" - } - }); + expect(stderr).toBeInstanceOf(Buffer); + expect(stderr.length).toEqual(0); - expect(res).toBeDefined(); - expect(res).toHaveProperty("statusCode"); - expect(res.statusCode).toEqual(200); - expect(res).toHaveProperty("rawPayload"); - expect(res.rawPayload).toBeDefined(); - expect(res.rawPayload).toBeInstanceOf(Buffer); + expect(stdout).toBeInstanceOf(Buffer); + expect(stdout.length).toBeGreaterThan(1); + + const readable_stdout = stdout.toString().split("\n"); + + expect(readable_stdout.length).toBeGreaterThan(5); + + readable_stdout[2] = readable_stdout[2] + .replace(/[\x0D]/g, "###") + .replace(/[0-9a-f]{4}[\x02]/g, ""); + + readable_stdout[3] = readable_stdout[3] + .replace(/[\x0D]/g, "###") + .replace(/[0-9a-f]{4}[\x02]/g, ""); + + readable_stdout[readable_stdout.length - 1] = readable_stdout[readable_stdout.length - 1].replace(/.*[\x01]/, ""); + + expect(readable_stdout[0]).toEqual("0008NAK"); + expect(readable_stdout[1]).toMatch(/Enumerating\ objects:\ \d+,\ done\.$/); + + // Make sure the progress output for counting objects is fine and dandy + const counting_objects = readable_stdout[2].split("###"); + + for(const progress of counting_objects.slice(0, -1)) { + expect(progress).toMatch(/^Counting\ objects:\s+\d+%\s\(\d+\/\d+\)$/); + } + + expect(counting_objects[counting_objects.length - 1]).toMatch(/^Counting\ objects:\s+\d+%\s\(\d+\/\d+\),\sdone\.$/); + + // Make sure the progress output for compressing objects is fine and dandy + const compressing_objects = readable_stdout[3].split("###"); + + for(const progress of compressing_objects.slice(0, -1)) { + expect(progress).toMatch(/^Compressing\ objects:\s+\d+%\s\(\d+\/\d+\)$/); + } + + expect(compressing_objects[counting_objects.length - 1]).toMatch(/^Compressing\ objects:\s+\d+%\s\(\d+\/\d+\),\sdone\.$/); + + //Just to be sure + expect(readable_stdout[readable_stdout.length - 1]).toMatch(/^A?0{4}/); }); }); -- cgit v1.2.3-18-g5258