Skip to content

Commit 798f32e

Browse files
authored
perf(test): memoize the shared GitHub App test keypair and cap rag-index's fixture size (#8550)
19 test files each generated a fresh RSA-2048 GitHub App keypair per call (~774 sites) for JWTs no fetch stub ever verifies -- any single valid key works for every fixture. test/helpers/github-app-key.ts memoizes one keypair per worker process on globalThis (not module scope -- vitest's per-file module isolation would rebuild it once per file otherwise, the same lesson test/helpers/d1.ts's template memo already learned). github-app.test.ts's key-rotation tests genuinely need distinct keys and keep their own local generator. rag-index.test.ts's cap tests built up to 4000 real chunk rows to prove MAX_CHUNKS_PER_REPO-capping BEHAVIOR, not to validate the number itself. rag.ts gains maxChunksPerRepo()/setMaxChunksPerRepoForTest() (the same ...ForTest override convention as clearInstallationTokenCacheForTest); the test file runs under a 24-row cap. rag-index.test.ts: 46s -> 1.6s (28x).
1 parent 61f6ec6 commit 798f32e

22 files changed

Lines changed: 85 additions & 260 deletions

src/review/rag-index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
filePriority,
3939
getStoredChunkMeta,
4040
isIndexablePath,
41-
MAX_CHUNKS_PER_REPO,
41+
maxChunksPerRepo,
4242
MAX_FILE_BYTES,
4343
ragNamespace,
4444
type RagChunk,
@@ -209,8 +209,8 @@ async function upsertChunksCapped(env: Env, project: string, repo: string, chunk
209209
const infra = createReviewAdapters(env);
210210
let stored = alreadyStored;
211211
let upserted = 0;
212-
for (let i = 0; i < chunks.length && stored < MAX_CHUNKS_PER_REPO; i += UPSERT_BATCH) {
213-
const remaining = MAX_CHUNKS_PER_REPO - stored;
212+
for (let i = 0; i < chunks.length && stored < maxChunksPerRepo(); i += UPSERT_BATCH) {
213+
const remaining = maxChunksPerRepo() - stored;
214214
const batch = chunks.slice(i, i + Math.min(UPSERT_BATCH, remaining));
215215
if (batch.length === 0) break;
216216
const n = await upsertChunks(infra, project, repo, batch, blobSha);
@@ -324,7 +324,7 @@ export async function indexRepo(
324324
skipped += 1;
325325
continue; // unchanged since the last full index — skip the fetch/chunk/embed entirely
326326
}
327-
if (stored >= MAX_CHUNKS_PER_REPO && (!known || known.count <= 0)) {
327+
if (stored >= maxChunksPerRepo() && (!known || known.count <= 0)) {
328328
capped = true;
329329
break;
330330
}
@@ -395,7 +395,7 @@ export async function reindexChangedPaths(
395395
let filesIndexed = 0;
396396
let capped = false;
397397
for (const path of indexable) {
398-
if (stored >= MAX_CHUNKS_PER_REPO) {
398+
if (stored >= maxChunksPerRepo()) {
399399
capped = true;
400400
break;
401401
}

src/review/rag.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,18 @@ const CHUNK_OVERLAP = 1500;
113113
* recurring one per cron cycle (#4365's blob-SHA skip-cache). Self-host only: this is not a Cloudflare
114114
* free-tier constraint on this deployment, but the name/comment history predates self-host. */
115115
export const MAX_CHUNKS_PER_REPO = 4000;
116+
// Test-only override (#test-hotspots): the cap tests exist to pin capping BEHAVIOR, not the number
117+
// 4000 — building 4,000 real chunk rows per cap test made rag-index.test.ts one of the suite's
118+
// slowest files (~7s per cap test). Same `...ForTest` hook convention as
119+
// clearInstallationTokenCacheForTest / clearGitHubResponseCacheForTest; production call sites read
120+
// maxChunksPerRepo() and never touch the override.
121+
let maxChunksPerRepoOverride: number | null = null;
122+
export function maxChunksPerRepo(): number {
123+
return maxChunksPerRepoOverride ?? MAX_CHUNKS_PER_REPO;
124+
}
125+
export function setMaxChunksPerRepoForTest(value: number | null): void {
126+
maxChunksPerRepoOverride = value;
127+
}
116128
const EMBED_BATCH = 96; // Workers AI caps embedding input at 100 items/call; kept as a conservative general
117129
// bound — other embed providers (Ollama/vLLM/etc via the self-host adapter) may not share this exact cap.
118130
const MAX_CONTEXT_CHARS = 14000; // bound the injected block (mirrors diff/knowledge budgets)

test/helpers/github-app-key.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// One throwaway RSA-2048 GitHub App private key per worker process (#test-hotspots): the suite
2+
// re-generated a fresh WebCrypto keypair on every call — ~770 call sites × ~20-100ms of prime
3+
// search — for JWTs whose signatures the fetch stubs never verify. Any single valid key is as good
4+
// as any other for these fixtures, so one per process is memoized on globalThis (NOT module scope:
5+
// vitest's per-file module isolation re-evaluates this module constantly, the same lesson
6+
// test/helpers/d1.ts's template memo learned). github-app.test.ts's key-rotation tests need
7+
// genuinely DISTINCT keys per call and keep their own local, non-memoized generator instead.
8+
const PEM_HEADER = "-----BEGIN PRIVATE KEY-----";
9+
const PEM_FOOTER = "-----END PRIVATE KEY-----";
10+
11+
async function freshPrivateKeyPem(): Promise<string> {
12+
const key = (await crypto.subtle.generateKey(
13+
{
14+
name: "RSASSA-PKCS1-v1_5",
15+
modulusLength: 2048,
16+
publicExponent: new Uint8Array([1, 0, 1]),
17+
hash: "SHA-256",
18+
},
19+
true,
20+
["sign", "verify"],
21+
)) as CryptoKeyPair;
22+
const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey);
23+
const base64 = Buffer.from(exported as ArrayBuffer)
24+
.toString("base64")
25+
.replace(/(.{64})/g, "$1\n");
26+
return `${PEM_HEADER}\n${base64}\n${PEM_FOOTER}`;
27+
}
28+
29+
export function generatePrivateKeyPem(): Promise<string> {
30+
const holder = globalThis as { __loopoverTestAppKeyPem?: Promise<string> };
31+
return (holder.__loopoverTestAppKeyPem ??= freshPrivateKeyPem());
32+
}

test/integration/api.test.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import { persistRegistrySnapshot } from "../../src/registry/sync";
4646
import { recordOverrideAudit, writeLiveOverride, writeShadowOverride, type StorageEnv } from "../../src/review/auto-apply";
4747
import { asCloudEnv, createTestEnv } from "../helpers/d1";
4848
import type { JsonValue } from "../../src/types";
49+
import { generatePrivateKeyPem } from "../helpers/github-app-key";
4950

5051
vi.mock("../../src/github/app", async (importOriginal) => ({
5152
...(await importOriginal<typeof import("../../src/github/app")>()),
@@ -7139,22 +7140,6 @@ function apiHeaders(env: Env): Record<string, string> {
71397140
};
71407141
}
71417142

7142-
async function generatePrivateKeyPem(): Promise<string> {
7143-
const key = (await crypto.subtle.generateKey(
7144-
{
7145-
name: "RSASSA-PKCS1-v1_5",
7146-
modulusLength: 2048,
7147-
publicExponent: new Uint8Array([1, 0, 1]),
7148-
hash: "SHA-256",
7149-
},
7150-
true,
7151-
["sign", "verify"],
7152-
)) as CryptoKeyPair;
7153-
const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey);
7154-
const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n");
7155-
return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`;
7156-
}
7157-
71587143
function upstreamContractFetch() {
71597144
const files: Record<string, string> = {
71607145
"gittensor/constants.py": "SRC_TOK_SATURATION_SCALE = 58\nMAX_CODE_DENSITY_MULTIPLIER = 1.15\n",

test/unit/actions-fallback-webhook.test.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,10 @@ import { fallbackShotR2Key, FALLBACK_ARTIFACT_NAME, isFallbackDispatchInFlight,
1414
import { processJob } from "../../src/queue/processors";
1515
import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader";
1616
import { createTestEnv } from "../helpers/d1";
17+
import { generatePrivateKeyPem } from "../helpers/github-app-key";
1718

1819
// Mirrors test/unit/queue.test.ts's own generatePrivateKeyPem helper -- createInstallationToken mints a real
1920
// JWT, so the default createTestEnv placeholder key ("test-private-key") won't do for any test that reaches it.
20-
async function generatePrivateKeyPem(): Promise<string> {
21-
const key = (await crypto.subtle.generateKey(
22-
{ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" },
23-
true,
24-
["sign", "verify"],
25-
)) as CryptoKeyPair;
26-
const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey);
27-
const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n");
28-
return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`;
29-
}
3021

3122
function concatBytes(parts: Uint8Array[]): Uint8Array {
3223
const total = parts.reduce((sum, p) => sum + p.length, 0);

test/unit/backfill-2.test.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ import { normalizeRegistryPayload } from "../../src/registry/normalize";
6363
import { persistRegistrySnapshot } from "../../src/registry/sync";
6464
import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics";
6565
import { asCloudEnv, createTestEnv } from "../helpers/d1";
66+
import { generatePrivateKeyPem } from "../helpers/github-app-key";
6667

6768
// #4682 incident (2026-07-10): the stored-body cap used to be 4000 chars -- well under what a compliant
6869
// screenshot-evidence table (or any sufficiently detailed PR/issue) actually needs -- and every body-content
@@ -89,22 +90,6 @@ async function seedRegisteredRepo(env: Env) {
8990
);
9091
}
9192

92-
async function generatePrivateKeyPem(): Promise<string> {
93-
const key = (await crypto.subtle.generateKey(
94-
{
95-
name: "RSASSA-PKCS1-v1_5",
96-
modulusLength: 2048,
97-
publicExponent: new Uint8Array([1, 0, 1]),
98-
hash: "SHA-256",
99-
},
100-
true,
101-
["sign", "verify"],
102-
)) as CryptoKeyPair;
103-
const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey);
104-
const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n");
105-
return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`;
106-
}
107-
10893
async function persistTotalsSnapshot(
10994
env: Env,
11095
overrides: {

test/unit/backfill.test.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import { normalizeRegistryPayload } from "../../src/registry/normalize";
6666
import { persistRegistrySnapshot } from "../../src/registry/sync";
6767
import { renderMetrics, resetMetrics } from "../../src/selfhost/metrics";
6868
import { asCloudEnv, createTestEnv } from "../helpers/d1";
69+
import { generatePrivateKeyPem } from "../helpers/github-app-key";
6970

7071
// #4682 incident (2026-07-10): the stored-body cap used to be 4000 chars -- well under what a compliant
7172
// screenshot-evidence table (or any sufficiently detailed PR/issue) actually needs -- and every body-content
@@ -218,22 +219,6 @@ async function seedInstalledAndRegisteredRepo(env: Env) {
218219
await seedRegisteredRepo(env);
219220
}
220221

221-
async function generatePrivateKeyPem(): Promise<string> {
222-
const key = (await crypto.subtle.generateKey(
223-
{
224-
name: "RSASSA-PKCS1-v1_5",
225-
modulusLength: 2048,
226-
publicExponent: new Uint8Array([1, 0, 1]),
227-
hash: "SHA-256",
228-
},
229-
true,
230-
["sign", "verify"],
231-
)) as CryptoKeyPair;
232-
const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey);
233-
const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n");
234-
return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`;
235-
}
236-
237222
async function persistTotalsSnapshot(
238223
env: Env,
239224
overrides: {

test/unit/github-comments.test.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { afterEach, describe, expect, it, vi } from "vitest";
22
import { createOrUpdatePrIntelligenceComment, createOrUpdateVisualFollowupComment, PR_INTELLIGENCE_COMMENT_MARKER, VISUAL_FOLLOWUP_COMMENT_MARKER } from "../../src/github/comments";
33
import { createTestEnv } from "../helpers/d1";
4+
import { generatePrivateKeyPem } from "../helpers/github-app-key";
45

56
describe("GitHub PR intelligence comments", () => {
67
afterEach(() => {
@@ -504,22 +505,6 @@ describe("GitHub PR intelligence comments", () => {
504505
});
505506
});
506507

507-
async function generatePrivateKeyPem(): Promise<string> {
508-
const key = (await crypto.subtle.generateKey(
509-
{
510-
name: "RSASSA-PKCS1-v1_5",
511-
modulusLength: 2048,
512-
publicExponent: new Uint8Array([1, 0, 1]),
513-
hash: "SHA-256",
514-
},
515-
true,
516-
["sign", "verify"],
517-
)) as CryptoKeyPair;
518-
const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey);
519-
const base64 = Buffer.from(exported as ArrayBuffer).toString("base64").replace(/(.{64})/g, "$1\n");
520-
return `-----BEGIN PRIVATE KEY-----\n${base64}\n-----END PRIVATE KEY-----`;
521-
}
522-
523508
describe("createOrUpdateIssueCommentWithMarker repoFullName guard (#8311)", () => {
524509
// The existing segment-count guard now also rejects whitespace, matching pr-actions.ts/assignees.ts/
525510
// labels.ts (#6613). These malformed shapes reject before any GitHub call (no fetch stub needed) and

test/unit/linked-issue-label-propagation-fetch.test.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {
66
fetchLinkedIssueLabelsForPropagation,
77
type LinkedIssuePropagationLabels,
88
} from "../../src/review/linked-issue-label-propagation-fetch";
9+
import { generatePrivateKeyPem } from "../helpers/github-app-key";
910

1011
// `getRepositoryCollaboratorPermission` mints its own installation token internally with no fallback to
1112
// the public token, so a maintainer-authored-issue test that reaches it (i.e. isn't already short-circuited
@@ -18,19 +19,6 @@ import {
1819
const PEM_HEADER = ["-----BEGIN", "PRIVATE KEY-----"].join(" ");
1920
const PEM_FOOTER = ["-----END", "PRIVATE KEY-----"].join(" ");
2021

21-
async function generatePrivateKeyPem(): Promise<string> {
22-
const key = (await crypto.subtle.generateKey(
23-
{ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" },
24-
true,
25-
["sign", "verify"],
26-
)) as CryptoKeyPair;
27-
const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey);
28-
const base64 = Buffer.from(exported as ArrayBuffer)
29-
.toString("base64")
30-
.replace(/(.{64})/g, "$1\n");
31-
return `${PEM_HEADER}\n${base64}\n${PEM_FOOTER}`;
32-
}
33-
3422
// #regression-safe-propagation: `fetchLinkedIssueLabelsForPropagation` returns `{labels, inconclusive}`, not a
3523
// bare `string[]` -- `inconclusive` defaults false (a confirmed result) in every assertion below except the
3624
// one test that simulates a genuinely unverifiable pass (a collaborator-permission check that errors).

test/unit/linked-issue-satisfaction-run.test.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { persistRegistrySnapshot } from "../../src/registry/sync";
2121
import { upsertRepoFocusManifest } from "../../src/signals/focus-manifest-loader";
2222
import type { Advisory, PullRequestFileRecord, RepositorySettings } from "../../src/types";
2323
import { createTestEnv } from "../helpers/d1";
24+
import { generatePrivateKeyPem } from "../helpers/github-app-key";
2425

2526
// Split so the literal PEM marker text never appears contiguous in source -- the review-safety secrets
2627
// scanner's private_key_block pattern is a pure text match with no awareness that the bytes between these
@@ -29,19 +30,6 @@ import { createTestEnv } from "../helpers/d1";
2930
const PEM_HEADER = ["-----BEGIN", "PRIVATE KEY-----"].join(" ");
3031
const PEM_FOOTER = ["-----END", "PRIVATE KEY-----"].join(" ");
3132

32-
async function generatePrivateKeyPem(): Promise<string> {
33-
const key = (await crypto.subtle.generateKey(
34-
{ name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" },
35-
true,
36-
["sign", "verify"],
37-
)) as CryptoKeyPair;
38-
const exported = await crypto.subtle.exportKey("pkcs8", key.privateKey);
39-
const base64 = Buffer.from(exported as ArrayBuffer)
40-
.toString("base64")
41-
.replace(/(.{64})/g, "$1\n");
42-
return `${PEM_HEADER}\n${base64}\n${PEM_FOOTER}`;
43-
}
44-
4533
function satisfactionJson(over: Partial<{ status: string; rationale: string; confidence: number }> = {}): string {
4634
return JSON.stringify({
4735
status: over.status ?? "addressed",

0 commit comments

Comments
 (0)