From 89f5e489adac69af2937fabc1a5ba283191d630a Mon Sep 17 00:00:00 2001 From: Ysopwnable <161784452+N0zoM1z0@users.noreply.github.com> Date: Mon, 12 Oct 2026 06:36:45 +0800 Subject: [PATCH] test(native): replay complete dylib-use provider output Replay the complete real Apple dylib-use output through the native provider boundary and retain rejection of an empty repeated options field. Align skill-install Result assertions and CDP initiator prerequisites with current contracts. The producing parser fix is already retained from main. Refs #1970 Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> Co-authored-by: Kaoru0822 <208281322+kaoru0822-kitauji@users.noreply.github.com> --- ...CdpCaptureEvents.redirectBodyShape.test.ts | 3 + .../qwenClientConfiguration.test.ts | 10 +- .../native/nativeMachoHeader.golden.test.ts | 39 +++ .../fixtures/native-macos/otool-dylib-use.md | 14 + .../fixtures/native-macos/otool-dylib-use.txt | 275 ++++++++++++++++++ 5 files changed, 339 insertions(+), 2 deletions(-) create mode 100644 tests/fixtures/native-macos/otool-dylib-use.md create mode 100644 tests/fixtures/native-macos/otool-dylib-use.txt diff --git a/src/browser/CdpCaptureEvents.redirectBodyShape.test.ts b/src/browser/CdpCaptureEvents.redirectBodyShape.test.ts index fb2da70a37..6faa983683 100644 --- a/src/browser/CdpCaptureEvents.redirectBodyShape.test.ts +++ b/src/browser/CdpCaptureEvents.redirectBodyShape.test.ts @@ -18,6 +18,7 @@ it("preserves an already captured response shape without marking it unavailable" method: "Network.requestWillBeSent", params: { requestId: "request-1", + initiator: { type: "other" }, request: { url: `${origin}/prior`, method: "POST", @@ -43,6 +44,7 @@ it("preserves an already captured response shape without marking it unavailable" base64Encoded: false, }); const capturedShape = events.network.get("request-1")?.body_shapes.response; + expect(capturedShape).toBeDefined(); expect(capturedShape).not.toBeNull(); events.ingest({ @@ -50,6 +52,7 @@ it("preserves an already captured response shape without marking it unavailable" params: { requestId: "request-1", request: { url: `${origin}/continuation`, method: "GET" }, + initiator: { type: "other" }, redirectResponse: null, timestamp: 2, }, diff --git a/tests/boundary/filesystem/qwenClientConfiguration.test.ts b/tests/boundary/filesystem/qwenClientConfiguration.test.ts index 55e8d0ab39..b915288fd3 100644 --- a/tests/boundary/filesystem/qwenClientConfiguration.test.ts +++ b/tests/boundary/filesystem/qwenClientConfiguration.test.ts @@ -150,7 +150,10 @@ describe("Qwen Code profile setup", () => { expect(await setup.configureClient(client, {}, command)).toEqual({ status: "configured", }); - expect(await setup.installSkill([client.name])).toBe("installed"); + expect(await setup.installSkill([client.name])).toEqual({ + ok: true, + value: "installed", + }); const skill = join(home, ".agents", "skills", PRODUCT_IDENTITY.skillName); await writeFile(join(skill, "user-notes.txt"), "user-authored"); expect(await readFile(join(skill, "SKILL.md"), "utf8")).toContain( @@ -158,7 +161,10 @@ describe("Qwen Code profile setup", () => { ); expect(await setup.clientNeedsConfigure(client, {}, command)).toBe(false); expect(await setup.skillNeedsInstall([client.name])).toBe(false); - expect(await setup.installSkill([client.name])).toBe("unchanged"); + expect(await setup.installSkill([client.name])).toEqual({ + ok: true, + value: "unchanged", + }); expect( ( await readClientRegistrationStatuses( diff --git a/tests/boundary/providers/native/nativeMachoHeader.golden.test.ts b/tests/boundary/providers/native/nativeMachoHeader.golden.test.ts index 49d80a601b..134db430bd 100644 --- a/tests/boundary/providers/native/nativeMachoHeader.golden.test.ts +++ b/tests/boundary/providers/native/nativeMachoHeader.golden.test.ts @@ -9,6 +9,45 @@ import { withOtoolMachHeader, } from "../../../fixtures/nativeCommands.js"; +it("retains the delayed dependency in the complete real framed otool output", async () => { + const output = await nativeFixture("otool-dylib-use.txt"); + const runner = new NativeFixtureRunner({ "otool:-h": output }); + const client = new NativeMacOSProvider({}, runner, "darwin").createClient( + nativeMachoTarget("/owned/fixture"), + ); + const result = await client.execute("inspect_macho", {}); + if (!result.ok) throw result.error; + expect(result.value.result).toMatchObject({ + load_commands: { + items: expect.arrayContaining([ + expect.objectContaining({ + index: 16, + kind: "LC_LOAD_DYLIB", + fields: expect.objectContaining({ options: "delay-init" }), + }), + ]), + }, + dependencies: { + items: expect.arrayContaining([ + expect.objectContaining({ + path: "@rpath/libdelay.dylib", + current_version: "0.0.0", + compatibility_version: "1.0.0", + }), + ]), + }, + }); + expect(parseOtoolLoadCommands(output).commands).toHaveLength(23); +}); + +it("rejects a repeated options field even when the duplicate has no value", async () => { + const output = (await nativeFixture("otool-dylib-use.txt")).replace( + " options delay-init ", + " options delay-init\n options", + ); + expect(() => parseOtoolLoadCommands(output)).toThrow(/otool/u); +}); + it("collects the actual Mach header alongside the native load commands", async () => { // The provider always invokes `otool -h -l`, which the runner resolves // via the "otool:-h" key; no bare `otool` override is needed. diff --git a/tests/fixtures/native-macos/otool-dylib-use.md b/tests/fixtures/native-macos/otool-dylib-use.md new file mode 100644 index 0000000000..750f044264 --- /dev/null +++ b/tests/fixtures/native-macos/otool-dylib-use.md @@ -0,0 +1,14 @@ +# Dylib-use otool capture + +`otool-dylib-use.txt` is the actual `otool -h -l` stdout retained by the +[Apple CLI/MCP verification job](https://github.com/morluto/rea/actions/runs/38176410166/job/114579755550). +Only its first filename line was replaced with `/owned/fixture:`. + +The source-built application comes from `scripts/verify/apple/macos-bundle.mjs`. +Its 23 load commands include a delayed dependency on `@rpath/libdelay.dylib`. +That dylib-use command has an `options delay-init` row instead of the legacy +`time stamp` row. The other three dylib commands retain the legacy form. + +The capture establishes actual producer text, command framing and dependency +fields. Linux replay tests do not establish real macOS provider execution; +the Apple CLI/MCP verification lane supplies that coverage. diff --git a/tests/fixtures/native-macos/otool-dylib-use.txt b/tests/fixtures/native-macos/otool-dylib-use.txt new file mode 100644 index 0000000000..28d40b4df5 --- /dev/null +++ b/tests/fixtures/native-macos/otool-dylib-use.txt @@ -0,0 +1,275 @@ +/owned/fixture: +Mach header + magic cputype cpusubtype caps filetype ncmds sizeofcmds flags + 0xfeedfacf 16777228 0 0x00 2 23 1632 0x00200085 +Load command 0 + cmd LC_SEGMENT_64 + cmdsize 72 + segname __PAGEZERO + vmaddr 0x0000000000000000 + vmsize 0x0000000100000000 + fileoff 0 + filesize 0 + maxprot 0x00000000 + initprot 0x00000000 + nsects 0 + flags 0x0 +Load command 1 + cmd LC_SEGMENT_64 + cmdsize 552 + segname __TEXT + vmaddr 0x0000000100000000 + vmsize 0x0000000000004000 + fileoff 0 + filesize 16384 + maxprot 0x00000005 + initprot 0x00000005 + nsects 6 + flags 0x0 +Section + sectname __text + segname __TEXT + addr 0x00000001000006b0 + size 0x0000000000000080 + offset 1712 + align 2^2 (4) + reloff 0 + nreloc 0 + flags 0x80000400 + reserved1 0 + reserved2 0 +Section + sectname __stubs + segname __TEXT + addr 0x0000000100000730 + size 0x0000000000000024 + offset 1840 + align 2^2 (4) + reloff 0 + nreloc 0 + flags 0x80000408 + reserved1 0 (index into indirect symbol table) + reserved2 12 (size of stubs) +Section + sectname __delay_stubs + segname __TEXT + addr 0x0000000100000754 + size 0x0000000000000028 + offset 1876 + align 2^2 (4) + reloff 0 + nreloc 0 + flags 0x80000400 + reserved1 0 + reserved2 0 +Section + sectname __delay_helper + segname __TEXT + addr 0x000000010000077c + size 0x00000000000000a0 + offset 1916 + align 2^2 (4) + reloff 0 + nreloc 0 + flags 0x80000400 + reserved1 0 + reserved2 0 +Section + sectname __cstring + segname __TEXT + addr 0x000000010000081c + size 0x0000000000000037 + offset 2076 + align 2^0 (1) + reloff 0 + nreloc 0 + flags 0x00000002 + reserved1 0 + reserved2 0 +Section + sectname __unwind_info + segname __TEXT + addr 0x0000000100000854 + size 0x0000000000000058 + offset 2132 + align 2^2 (4) + reloff 0 + nreloc 0 + flags 0x00000000 + reserved1 0 + reserved2 0 +Load command 2 + cmd LC_SEGMENT_64 + cmdsize 152 + segname __DATA_CONST + vmaddr 0x0000000100004000 + vmsize 0x0000000000004000 + fileoff 16384 + filesize 16384 + maxprot 0x00000003 + initprot 0x00000003 + nsects 1 + flags 0x10 +Section + sectname __got + segname __DATA_CONST + addr 0x0000000100004000 + size 0x0000000000000028 + offset 16384 + align 2^3 (8) + reloff 0 + nreloc 0 + flags 0x00000006 + reserved1 3 (index into indirect symbol table) + reserved2 0 +Load command 3 + cmd LC_SEGMENT_64 + cmdsize 152 + segname __DATA + vmaddr 0x0000000100008000 + vmsize 0x0000000000004000 + fileoff 32768 + filesize 16384 + maxprot 0x00000003 + initprot 0x00000003 + nsects 1 + flags 0x0 +Section + sectname __data + segname __DATA + addr 0x0000000100008000 + size 0x0000000000000004 + offset 32768 + align 2^2 (4) + reloff 0 + nreloc 0 + flags 0x00000000 + reserved1 0 + reserved2 0 +Load command 4 + cmd LC_SEGMENT_64 + cmdsize 72 + segname __LINKEDIT + vmaddr 0x000000010000c000 + vmsize 0x0000000000008000 + fileoff 49152 + filesize 19280 + maxprot 0x00000001 + initprot 0x00000001 + nsects 0 + flags 0x0 +Load command 5 + cmd LC_DYLD_CHAINED_FIXUPS + cmdsize 16 + dataoff 49152 + datasize 160 +Load command 6 + cmd LC_DYLD_EXPORTS_TRIE + cmdsize 16 + dataoff 49312 + datasize 48 +Load command 7 + cmd LC_SYMTAB + cmdsize 24 + symoff 49368 + nsyms 10 + stroff 49560 + strsize 176 +Load command 8 + cmd LC_DYSYMTAB + cmdsize 80 + ilocalsym 0 + nlocalsym 3 + iextdefsym 3 + nextdefsym 2 + iundefsym 5 + nundefsym 5 + tocoff 0 + ntoc 0 + modtaboff 0 + nmodtab 0 + extrefsymoff 0 + nextrefsyms 0 + indirectsymoff 49528 + nindirectsyms 8 + extreloff 0 + nextrel 0 + locreloff 0 + nlocrel 0 +Load command 9 + cmd LC_LOAD_DYLINKER + cmdsize 32 + name /usr/lib/dyld (offset 12) +Load command 10 + cmd LC_UUID + cmdsize 24 + uuid 2F026098-89DD-47C5-A6E4-7C567C2ACD30 +Load command 11 + cmd LC_BUILD_VERSION + cmdsize 32 + platform 1 + minos 15.0 + sdk 15.5 + ntools 1 + tool 3 + version 1167.5 +Load command 12 + cmd LC_SOURCE_VERSION + cmdsize 16 + version 0.0 +Load command 13 + cmd LC_MAIN + cmdsize 24 + entryoff 1712 + stacksize 0 +Load command 14 + cmd LC_LOAD_DYLIB + cmdsize 64 + name @rpath/Core.framework/Versions/A/Core (offset 24) + time stamp 2 Thu Jan 1 00:00:02 1970 + current version 0.0.0 +compatibility version 0.0.0 +Load command 15 + cmd LC_LOAD_WEAK_DYLIB + cmdsize 48 + name @rpath/libgone.dylib (offset 24) + time stamp 2 Thu Jan 1 00:00:02 1970 + current version 0.0.0 +compatibility version 0.0.0 +Load command 16 + cmd LC_LOAD_DYLIB + cmdsize 56 + name @rpath/libdelay.dylib (offset 28) + options delay-init + current version 0.0.0 +compatibility version 1.0.0 +Load command 17 + cmd LC_LOAD_DYLIB + cmdsize 56 + name /usr/lib/libSystem.B.dylib (offset 24) + time stamp 2 Thu Jan 1 00:00:02 1970 + current version 1351.0.0 +compatibility version 1.0.0 +Load command 18 + cmd LC_RPATH + cmdsize 48 + path @executable_path/../Overrides (offset 12) +Load command 19 + cmd LC_RPATH + cmdsize 48 + path @executable_path/../Frameworks (offset 12) +Load command 20 + cmd LC_FUNCTION_STARTS + cmdsize 16 + dataoff 49360 + datasize 8 +Load command 21 + cmd LC_DATA_IN_CODE + cmdsize 16 + dataoff 49368 + datasize 0 +Load command 22 + cmd LC_CODE_SIGNATURE + cmdsize 16 + dataoff 49744 + datasize 18688