mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-09 22:48:57 +02:00
spawnSync/execSync/Bun.spawnSync BLOCK the main thread, so bun's in-process per-test timeout can never fire while one waits — a hung child (stdin read, network probe, dead daemon) wedges the whole shard until the runner's external wall-clock SIGKILL. This exact class reached main: free-tests run 33262077256, test/gstack-memory-ingest.test.ts (normally 2.3s) held shard 2 at the 360s wall while its five siblings finished in ~65s. Mechanical sweep in two waves (12 + 4 fan-out agents, every edit verified against its call site): default timeout: 30_000 (matches the free runner's per-test budget), 120_000 for genuinely slow ops (installs, builds, playwright, provider CLIs), helper wrappers fixed ONCE where call sites route through them. Sites that only LOOK like calls (string fixtures, grep needles, comments) were skipped with reasons — the enforcement commit that follows marks them exempt. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
106 lines
4.0 KiB
TypeScript
106 lines
4.0 KiB
TypeScript
/**
|
|
* gstack-artifacts-url — URL canonicalization helper.
|
|
*
|
|
* Centralizes HTTPS↔SSH conversion so callers don't each string-mangle. Per
|
|
* codex Finding #10: store one canonical form (HTTPS) and derive all others.
|
|
*/
|
|
|
|
import { describe, test, expect } from 'bun:test';
|
|
import * as path from 'path';
|
|
import { spawnSync } from 'child_process';
|
|
|
|
const ROOT = path.resolve(import.meta.dir, '..');
|
|
const URL_BIN = path.join(ROOT, 'bin', 'gstack-artifacts-url');
|
|
|
|
function run(args: string[]): { code: number; stdout: string; stderr: string } {
|
|
const r = spawnSync(URL_BIN, args, { encoding: 'utf-8', timeout: 30_000 });
|
|
return {
|
|
code: r.status ?? -1,
|
|
stdout: (r.stdout || '').trim(),
|
|
stderr: (r.stderr || '').trim(),
|
|
};
|
|
}
|
|
|
|
describe('gstack-artifacts-url', () => {
|
|
test('--to ssh from canonical https', () => {
|
|
const r = run(['--to', 'ssh', 'https://github.com/garrytan/gstack-artifacts-garrytan']);
|
|
expect(r.code).toBe(0);
|
|
expect(r.stdout).toBe('git@github.com:garrytan/gstack-artifacts-garrytan.git');
|
|
});
|
|
|
|
test('--to ssh from https-with-.git', () => {
|
|
const r = run(['--to', 'ssh', 'https://github.com/garrytan/gstack-artifacts-garrytan.git']);
|
|
expect(r.stdout).toBe('git@github.com:garrytan/gstack-artifacts-garrytan.git');
|
|
});
|
|
|
|
test('--to https is idempotent on https input', () => {
|
|
const r = run(['--to', 'https', 'https://github.com/garrytan/gstack-artifacts-garrytan']);
|
|
expect(r.stdout).toBe('https://github.com/garrytan/gstack-artifacts-garrytan');
|
|
});
|
|
|
|
test('--to https from git@host:owner/repo.git', () => {
|
|
const r = run(['--to', 'https', 'git@github.com:garrytan/gstack-artifacts-garrytan.git']);
|
|
expect(r.stdout).toBe('https://github.com/garrytan/gstack-artifacts-garrytan');
|
|
});
|
|
|
|
test('--to https from ssh:// scheme (gitlab self-hosted style)', () => {
|
|
const r = run(['--to', 'https', 'ssh://git@gitlab.example.org/team/gstack-artifacts-team.git']);
|
|
expect(r.stdout).toBe('https://gitlab.example.org/team/gstack-artifacts-team');
|
|
});
|
|
|
|
test('--host extracts hostname from any form', () => {
|
|
expect(run(['--host', 'https://github.com/x/y']).stdout).toBe('github.com');
|
|
expect(run(['--host', 'git@gitlab.com:x/y.git']).stdout).toBe('gitlab.com');
|
|
expect(run(['--host', 'ssh://git@gitlab.example.org/x/y.git']).stdout).toBe('gitlab.example.org');
|
|
});
|
|
|
|
test('--owner-repo extracts the path segment', () => {
|
|
expect(run(['--owner-repo', 'https://github.com/garrytan/gstack-artifacts-garrytan']).stdout)
|
|
.toBe('garrytan/gstack-artifacts-garrytan');
|
|
expect(run(['--owner-repo', 'git@github.com:team/gstack-artifacts-team.git']).stdout)
|
|
.toBe('team/gstack-artifacts-team');
|
|
});
|
|
|
|
test('rejects unrecognized URL form with exit 3', () => {
|
|
const r = run(['--to', 'ssh', 'not a url']);
|
|
expect(r.code).toBe(3);
|
|
expect(r.stderr).toContain('unrecognized URL form');
|
|
});
|
|
|
|
test('rejects remotes without both owner and repo path segments', () => {
|
|
const malformed = [
|
|
'https://github.com',
|
|
'https://github.com/owner',
|
|
'https://github.com/owner/',
|
|
'https://github.com/owner//repo',
|
|
'git@github.com:owner',
|
|
'ssh://git@github.com',
|
|
'ssh://git@github.com/owner',
|
|
];
|
|
|
|
for (const url of malformed) {
|
|
const r = run(['--to', 'ssh', url]);
|
|
expect(r.code, url).toBe(3);
|
|
expect(r.stderr, url).toContain('failed to parse host/owner');
|
|
}
|
|
});
|
|
|
|
test('rejects missing args with exit 2', () => {
|
|
expect(run([]).code).toBe(2);
|
|
expect(run(['--to']).code).toBe(2);
|
|
expect(run(['--to', 'ssh']).code).toBe(2);
|
|
});
|
|
|
|
test('rejects unknown --to target', () => {
|
|
const r = run(['--to', 'svn', 'https://github.com/x/y']);
|
|
expect(r.code).toBe(2);
|
|
});
|
|
|
|
test('round-trip: https → ssh → https is identity', () => {
|
|
const original = 'https://github.com/garrytan/gstack-artifacts-garrytan';
|
|
const ssh = run(['--to', 'ssh', original]).stdout;
|
|
const back = run(['--to', 'https', ssh]).stdout;
|
|
expect(back).toBe(original);
|
|
});
|
|
});
|