From a7bdcfc2f7439c7a4b7208a44bf23474c204ac71 Mon Sep 17 00:00:00 2001 From: Yury Zialionka Date: Thu, 13 Aug 2026 18:05:47 -0600 Subject: [PATCH] perf(test): start heavy batches first; make artifact upload non-fatal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The worker queue sorted by raw file weight, which is 0 for batch pseudo-files (not real paths) — batches started last, leaving one worker running a full batch after the rest of the shard drained. Sorting by shard weight starts the heaviest items first and shortens the tail. The batch-safety guard now reads member sources in parallel, and the diagnostics-only artifact upload no longer fails a green job on a runner-side network blip (seen as ECONNREFUSED on Blacksmith). --- .github/workflows/test.yml | 3 +++ packages/opencode/script/test-runner.ts | 20 ++++++++++++-------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e252eb78f5..a67718ec17 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -203,6 +203,9 @@ jobs: - name: Upload unit artifacts if: always() && matrix.settings.run + # kilocode_change - diagnostics only: a runner-side network blip here must not + # fail a job whose tests already passed (seen as ECONNREFUSED on Blacksmith). + continue-on-error: true uses: actions/upload-artifact@v7 with: name: unit-${{ matrix.settings.os }}-${{ matrix.settings.index }}-${{ github.run_attempt }} diff --git a/packages/opencode/script/test-runner.ts b/packages/opencode/script/test-runner.ts index 713502a709..591af2b128 100644 --- a/packages/opencode/script/test-runner.ts +++ b/packages/opencode/script/test-runner.ts @@ -388,13 +388,14 @@ if (patterns.length === 0 && !profile) { // later: bun's mock.module is process-wide and permanent, AppRuntime.dispose() kills the // shared runtime, and global-fetch spies observe batch-mates' traffic. const unsafe = [/\bmock\.module\s*\(/, /\bAppRuntime\.dispose\s*\(/, /\bspyOn\s*\(\s*globalThis\b/] - const violations: string[] = [] - for (const members of batches.values()) { - for (const member of members) { - const source = await Bun.file(path.join(root, "test", member)).text() - if (unsafe.some((pattern) => pattern.test(source))) violations.push(member) - } - } + const violations = ( + await Promise.all( + [...batches.values()].flat().map(async (member) => { + const source = await Bun.file(path.join(root, "test", member)).text() + return unsafe.some((pattern) => pattern.test(source)) ? member : undefined + }), + ) + ).filter((member): member is string => member !== undefined) if (violations.length > 0) { console.error( [ @@ -696,7 +697,10 @@ console.log() const start = performance.now() const results: Result[] = [] -const queue = TestShard.order(files, weight) +// Order by shardWeight, not weight: batch pseudo-files are not real paths, so weight() +// gives them 0 and they would start LAST — leaving one worker running a whole batch +// after everything else finished. Heaviest-first keeps the tail short. kilocode_change +const queue = TestShard.order(files, shardWeight) const workers = Array.from({ length: Math.min(concurrency, files.length) }, async () => { while (queue.length > 0 && !stopped.value) {