mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-21 04:10:47 +02:00
fix(gstack2): harden integrated runtime verification
This commit is contained in:
@@ -101,10 +101,15 @@ describe("capability readiness", () => {
|
||||
expect(exit).toBe(1);
|
||||
expect(stderr.value()).toBe("");
|
||||
expect(result).toMatchObject({
|
||||
ok: false,
|
||||
capability: "pdf",
|
||||
judgment: { status: "available" },
|
||||
readiness: { status: "unavailable" },
|
||||
schemaVersion: 1,
|
||||
status: "degraded",
|
||||
code: "CAPABILITY_UNAVAILABLE",
|
||||
data: {
|
||||
ok: false,
|
||||
capability: "pdf",
|
||||
judgment: { status: "available" },
|
||||
readiness: { status: "unavailable" },
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
await fs.rm(root, { recursive: true, force: true });
|
||||
|
||||
@@ -107,11 +107,33 @@ describe('gstack state external-effect CLI', () => {
|
||||
'state', 'effect', 'run_empty', 'silent.tool', '--', silent,
|
||||
], { cwd, env, stdout: out, stderr: err });
|
||||
expect(code).toBe(1);
|
||||
expect(err.value()).toContain('may have occurred');
|
||||
expect(JSON.parse(err.value())).toMatchObject({
|
||||
status: 'degraded',
|
||||
code: 'EXECUTION_EMPTY',
|
||||
evidence: ['exit code 0', 'stdout and stderr were empty'],
|
||||
});
|
||||
expect(out.value()).not.toContain('"status":"success"');
|
||||
const retryError = sink();
|
||||
expect(await main([
|
||||
'state', 'effect', 'run_empty', 'silent.tool', '--', silent,
|
||||
], { cwd, env, stdout: out, stderr: err })).toBe(1);
|
||||
expect(err.value()).toContain('was already claimed');
|
||||
], { cwd, env, stdout: out, stderr: retryError })).toBe(1);
|
||||
expect(retryError.value()).toContain('was already claimed');
|
||||
});
|
||||
|
||||
test('a nonzero command returns a structured failed result', async () => {
|
||||
const { cwd, env } = await fixture();
|
||||
const out = sink();
|
||||
const err = sink();
|
||||
await main(['state', 'begin', 'ship', '--run-id', 'run_failed'], { cwd, env, stdout: out, stderr: err });
|
||||
const code = await main([
|
||||
'state', 'effect', 'run_failed', 'failed.tool', '--', process.execPath, '-e', 'process.exit(7)',
|
||||
], { cwd, env, stdout: out, stderr: err });
|
||||
expect(code).toBe(1);
|
||||
expect(JSON.parse(err.value())).toMatchObject({
|
||||
status: 'failed',
|
||||
code: 'EXECUTION_FAILED',
|
||||
evidence: ['exit code 7'],
|
||||
data: { exitCode: 7 },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -376,6 +376,9 @@ describe("GStack 2 managed runtime installer", () => {
|
||||
"node_modules/sharp",
|
||||
"node_modules/detect-libc",
|
||||
"node_modules/semver",
|
||||
"node_modules/standardwebhooks",
|
||||
"node_modules/@stablelib/base64",
|
||||
"node_modules/fast-sha256",
|
||||
...runtimeNativePackagePaths(),
|
||||
]) expect(bundlePaths.has(dependency)).toBe(true);
|
||||
expect(bundlePaths.has("node_modules/@img")).toBe(false);
|
||||
|
||||
@@ -45,7 +45,9 @@ describe('GStack 2 generated runtime payload prerequisites', () => {
|
||||
expect(result.built).toBe(true);
|
||||
expect(calls).toHaveLength(1);
|
||||
expect(calls[0].map((entry) => entry.path)).toEqual(REQUIRED_RUNTIME_PAYLOADS.map((entry) => entry.path));
|
||||
expect(new Set(calls[0].map((entry) => entry.build))).toEqual(new Set(['core']));
|
||||
expect(new Set(calls[0].map((entry) => entry.build))).toEqual(
|
||||
new Set(process.platform === 'darwin' ? ['core', 'ios'] : ['core']),
|
||||
);
|
||||
});
|
||||
|
||||
test('does not rebuild payloads that already exist', async () => {
|
||||
|
||||
@@ -18,7 +18,7 @@ describe('GStack 2 semantic parity', () => {
|
||||
expect(result.sections).toBe(16);
|
||||
expect(result.policyUnits).toBe(AUTHORITY_POLICY_CASES.length);
|
||||
expect(result.checks).toBeGreaterThan(250);
|
||||
});
|
||||
}, 15_000);
|
||||
|
||||
test('authority-policy units cover evidence, trust, and routing controls', () => {
|
||||
expect(AUTHORITY_POLICY_CASES.length).toBeGreaterThanOrEqual(9);
|
||||
|
||||
@@ -72,7 +72,8 @@ describe("release and CI hardening", () => {
|
||||
expect(workflow).toContain("versions/current.json");
|
||||
expect(workflow).not.toContain('active="$GSTACK_HOME/versions/2.0.0"');
|
||||
expect(workflow).toContain(".gstack-runtime-browsers");
|
||||
expect(workflow).toContain('chromium.launch({ headless: true, channel: "chromium" })');
|
||||
expect(workflow).toContain('for (const options of [{ headless: true }, { headless: true, channel: "chromium" }])');
|
||||
expect(workflow).toContain("chromium.launch(options)");
|
||||
expect(workflow).not.toContain("--with-deps");
|
||||
expect(workflow).toContain(".gstack-runtime-tools/bun");
|
||||
expect(workflow).toContain('"$GSTACK_HOME/bin/bun" --version');
|
||||
@@ -99,7 +100,9 @@ describe("release and CI hardening", () => {
|
||||
expect(installer).toContain('entry(managedBunRelativePath(), "managed-bun", true)');
|
||||
const browser = read("browse/src/cli.ts");
|
||||
expect(browser).toContain("Every installed/compiled client must use the adjacent Node-compatible daemon");
|
||||
expect(browser).toContain("if (IS_COMPILED && !NODE_SERVER_SCRIPT)");
|
||||
expect(browser).toContain("if (isCompiled)");
|
||||
expect(browser).toContain("if (!nodeServerScript)");
|
||||
expect(browser).toContain("return { isCompiled, nodeServerScript, sourceServerScript: null }");
|
||||
});
|
||||
|
||||
test("Windows setup lane installs, doctors, and uninstalls rather than only building", () => {
|
||||
|
||||
@@ -5,6 +5,7 @@ import * as os from 'os';
|
||||
import {
|
||||
DEFAULT_MAX_FILES_PER_SHARD,
|
||||
FREE_TEST_ROOTS,
|
||||
buildShardArgs,
|
||||
isFreeTestFile,
|
||||
collectFreeTestFiles,
|
||||
containsScheduledProcessExitZero,
|
||||
@@ -138,6 +139,16 @@ describe('test-free-shards: sharding', () => {
|
||||
expect(() => assignFilesToShards(['a.test.ts'], -1)).toThrow();
|
||||
});
|
||||
|
||||
test('buildShardArgs accepts a suite-specific timeout without enabling file concurrency', () => {
|
||||
expect(buildShardArgs(['test/gstack2-skills.test.ts'], 30_000)).toEqual([
|
||||
'test',
|
||||
'test/gstack2-skills.test.ts',
|
||||
'--max-concurrency=1',
|
||||
'--timeout=30000',
|
||||
]);
|
||||
expect(() => buildShardArgs(['test/example.test.ts'], 0)).toThrow();
|
||||
});
|
||||
|
||||
test('shards are stable across runs (same files always land in same shard)', () => {
|
||||
const files = ['x.test.ts', 'y.test.ts', 'z.test.ts'];
|
||||
const a = assignFilesToShards(files, 5);
|
||||
|
||||
Reference in New Issue
Block a user