test(managed-agent): parse only complete rows in the wedge driver wire (#14496)

* test(managed-agent): parse only complete rows in the wedge driver wire

* test(managed-agent): pin the wire reader to complete rows

The blocked-wedge driver's wire reader had no executable coverage: the
driver cannot be imported (it parses argv and boots a daemon at load),
and the Java gates that spawn it are skipped on PR events. Extract the
parse into a side-effect-free helper so a unit test can exercise it, and
pin the mutants that matter with two complete rows plus an unterminated
tail.

---------

Co-authored-by: 易良 <1204183885@qq.com>
This commit is contained in:
Shaojin Wen 2026-10-18 10:50:10 +08:00 • committed by GitHub
parent b3c5d3ed1e
commit c6018c63b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 74 additions and 17 deletions

View file

@ -34,6 +34,7 @@ import { LISTENING_LINE_RE, stopDaemon } from './daemon-process.js';
import { HOSTED_HOME_PREFIX } from '../scratch-dir.js';
import { relayUpstream } from './hosted-relay-headers.js';
import { waitUntil } from './hosted-harness-process.js';
import { parseWireRows, type WireRow } from './wire-rows.js';
const config = JSON.parse(await readFile(process.argv[2], 'utf8')) as {
tenantId: string;
@ -544,25 +545,9 @@ const model = await startFakeOpenAIServer(({ body }) => {
const daemon = await new WedgeDaemon().start(model.baseUrl);
interface WireRow {
kind?: string;
requestId?: number;
at?: number;
method?: string;
url?: string;
operation?: string;
status?: number;
requestSnippet?: string;
responseSnippet?: string;
replied?: string;
}
async function readWire(): Promise<WireRow[]> {
try {
return (await readFile(config.wireFile, 'utf8'))
.split('\n')
.filter(Boolean)
.map((line) => JSON.parse(line) as WireRow);
return parseWireRows(await readFile(config.wireFile, 'utf8'));
} catch (cause) {
if ((cause as NodeJS.ErrnoException)?.code === 'ENOENT') return [];
throw cause;

View file

@ -0,0 +1,41 @@
/**
* @license
* Copyright 2026 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
import { describe, expect, it } from 'vitest';
import { parseWireRows } from './wire-rows.js';
describe('parseWireRows', () => {
it('returns no rows for an empty buffer', () => {
expect(parseWireRows('')).toEqual([]);
});
it('returns no rows when the only row has no trailing newline yet', () => {
expect(parseWireRows('{"kind":"a"}')).toEqual([]);
});
it('drops an unterminated tail and keeps the complete rows', () => {
// Two complete rows keep lastIndexOf -> indexOf observable; with a single
// complete row that mutant survives.
expect(parseWireRows('{"kind":"a"}\n{"kind":"b"}\n{"kind":"c"')).toEqual([
{ kind: 'a' },
{ kind: 'b' },
]);
});
it('returns one row for a single terminated row', () => {
expect(parseWireRows('{"kind":"a"}\n')).toEqual([{ kind: 'a' }]);
});
it('returns no rows for a buffer that is only a newline', () => {
expect(parseWireRows('\n')).toEqual([]);
});
it('still throws on a malformed complete row', () => {
expect(() => parseWireRows('{"kind":"a"}\n{"kind":\n')).toThrow(
SyntaxError,
);
});
});

View file

@ -0,0 +1,31 @@
/**
* @license
* Copyright 2026 Qwen Team
* SPDX-License-Identifier: Apache-2.0
*/
export interface WireRow {
kind?: string;
requestId?: number;
at?: number;
method?: string;
url?: string;
operation?: string;
status?: number;
requestSnippet?: string;
responseSnippet?: string;
replied?: string;
}
// The blocked-wedge driver appends each row with one appendFile of
// JSON.stringify(row) + '\n', and polls the same file from the same process,
// so a read can land mid-append. Parse only complete rows: an unterminated
// tail is the row still being written, and the next poll reads it whole. A
// complete-but-malformed row still reaches JSON.parse and throws.
export function parseWireRows(text: string): WireRow[] {
return text
.slice(0, text.lastIndexOf('\n') + 1)
.split('\n')
.filter(Boolean)
.map((line) => JSON.parse(line) as WireRow);
}