Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

72 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { readFileSync, readdirSync } from "node:fs";
3import { DatabaseSync } from "node:sqlite";
4import { test } from "node:test";
5
6const source = readFileSync(new URL("../services/repos/src/public_storage.rs", import.meta.url), "utf8");
7const sql = name => source.match(new RegExp(`const ${name}: &str = "([\\s\\S]*?)";`))[1];
8function database() {
9 const db = new DatabaseSync(":memory:");
10 const dir = new URL("../services/repos/migrations/", import.meta.url);
11 for (const name of readdirSync(dir).filter(n => n.endsWith(".sql")).sort()) db.exec(readFileSync(new URL(name, dir), "utf8"));
12 return db;
13}
14function repo(db, id, bytes, workspace = "team", privateRepo = 0) {
15 db.prepare("INSERT INTO repos(id,namespace,name,owner_id,stored_bytes,is_private,created_at) VALUES (?,?,?,'owner',?,?,'2026-10-14T00:00:00Z')")
16 .run(id, workspace, id, bytes, privateRepo);
17}
18const reserve = (db, id, bytes, cap = 5_000_000_000) => db.prepare(sql("RESERVE")).get({ 1: id, 2: bytes, 3: cap });
19
20test("overlapping pushes cannot reserve the same final capacity", () => {
21 const db = database();
22 repo(db, "first", 4_900_000_000); repo(db, "second", 0);
23 assert.ok(reserve(db, "first", 80_000_000));
24 assert.equal(reserve(db, "second", 80_000_000), undefined);
25 assert.ok(reserve(db, "second", 20_000_000));
26 assert.equal(reserve(db, "first", 1), undefined);
27 assert.equal(db.prepare("SELECT SUM(stored_bytes + storage_reserved_bytes) n FROM repos").get().n, 5_000_000_000);
28 assert.equal(db.prepare("SELECT SUM(stored_bytes) n FROM repos").get().n, 4_900_000_000, "reservations are not measured storage billed to customers");
29 db.close();
30});
31
32test("deleted retained data and interrupted write reservations still consume capacity", () => {
33 const db = database();
34 repo(db, "retained", 4_950_000_000); repo(db, "active", 0);
35 db.exec("UPDATE repos SET deleted_at = '2026-10-14T00:00:00Z' WHERE id = 'retained'");
36 assert.ok(reserve(db, "active", 50_000_000));
37 assert.equal(reserve(db, "active", 1), undefined);
38 db.exec("DELETE FROM repos WHERE id = 'retained'");
39 assert.ok(reserve(db, "active", 1));
40 db.close();
41});
42
43test("concurrent visibility changes cannot bypass public capacity", () => {
44 const db = database();
45 repo(db, "public", 4_000_000_000); repo(db, "private_a", 750_000_000, "team", 1); repo(db, "private_b", 750_000_000, "team", 1);
46 assert.ok(db.prepare(sql("MAKE_PUBLIC")).get({ 1: "private_a", 2: 5_000_000_000 }));
47 assert.equal(db.prepare(sql("MAKE_PUBLIC")).get({ 1: "private_b", 2: 5_000_000_000 }), undefined);
48 assert.ok(reserve(db, "private_b", 100_000_000));
49 assert.equal(db.prepare("SELECT is_private FROM repos WHERE id='private_b'").get().is_private, 1);
50 db.close();
51});
52
53test("transfer admission uses destination capacity at the moment of mutation", () => {
54 const db = database();
55 repo(db, "existing", 4_500_000_000, "destination"); repo(db, "moving", 600_000_000);
56 assert.equal(db.prepare(sql("TRANSFER")).get({ 1: "moving", 2: "destination", 3: "team", 4: 5_000_000_000 }), undefined);
57 assert.equal(db.prepare("SELECT namespace FROM repos WHERE id='moving'").get().namespace, "team");
58 db.exec("DELETE FROM repos WHERE id='existing'");
59 assert.ok(db.prepare(sql("TRANSFER")).get({ 1: "moving", 2: "destination", 3: "team", 4: 5_000_000_000 }));
60 db.close();
61});
62
63test("native copy freezes new source writes until its storage snapshot is taken", () => {
64 const db = database();
65 repo(db, "source", 100); repo(db, "fork", 0);
66 db.exec("INSERT INTO storage_copy_locks VALUES ('source','fork','2026-10-14T00:00:00Z')");
67 assert.equal(reserve(db, "source", 20), undefined);
68 assert.ok(reserve(db, "fork", 100));
69 db.exec("DELETE FROM storage_copy_locks WHERE repo_id='source'");
70 assert.ok(reserve(db, "source", 20));
71 db.close();
72});