From 8efe0ca2535c047f930888b03c7e31ebd136548c Mon Sep 17 00:00:00 2001 From: Tim Perry Date: Wed, 22 May 2024 18:24:29 +0200 Subject: [PATCH] Add support for auto-connection after initial failure This isn't relevant on most environments (where you either have usbmuxd or you don't) but on Linux the standard setup is that the server stops whenever no devices are connected, so if you start with nothing connected, requests will fail until there's a device present. --- src/index.ts | 1 + test/unit-tests.spec.ts | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/index.ts b/src/index.ts index c166dab..68d5042 100644 --- a/src/index.ts +++ b/src/index.ts @@ -104,6 +104,7 @@ export class UsbmuxClient { this.deviceData = {}; }); } catch (e: any) { + this.deviceMonitorConnection = undefined; connectionDeferred.reject(e); throw e; } diff --git a/test/unit-tests.spec.ts b/test/unit-tests.spec.ts index b6ab5d6..bb1536c 100644 --- a/test/unit-tests.spec.ts +++ b/test/unit-tests.spec.ts @@ -50,17 +50,19 @@ describe("Usbmux-client unit tests", () => { }) })); let mockServerPort: number | undefined; - - let client: UsbmuxClient | undefined; - - beforeEach(async () => { - mockServer.listen(0); + const startServer = async (port = 0) => { + mockServer.listen(port); await new Promise((resolve, reject) => { mockServer.once('listening', resolve); mockServer.once('error', reject); }); - mockServerPort = (mockServer.address() as net.AddressInfo).port; + } + + let client: UsbmuxClient | undefined; + + beforeEach(async () => { + await startServer(); }); afterEach(async () => { @@ -116,7 +118,28 @@ describe("Usbmux-client unit tests", () => { socket.write(Buffer.from(MESSAGES.OK_RESULT, 'base64')); socket.write(Buffer.from(MESSAGES.DEVICE_ATTACHED_EVENT, 'base64')); - await delay(10); + expect(Object.keys(await deviceQuery)).to.have.length(1); + }); + + it("should handle reconnecting to an initially unresponsive server", async () => { + const port = mockServerPort!; + await mockServer.destroy(); + + client = new UsbmuxClient({ port }); + + const deviceQueryResult = await client.getDevices().catch(e => e);; + expect(deviceQueryResult).to.be.instanceOf(Error); + expect(deviceQueryResult.message).to.contain("ECONNREFUSED"); + + await startServer(port); + + const deviceQuery = client.getDevices(); + + const socket = await waitForSocket(); + await expectMessage(socket, 'LISTEN_REQUEST'); + socket.write(Buffer.from(MESSAGES.OK_RESULT, 'base64')); + socket.write(Buffer.from(MESSAGES.DEVICE_ATTACHED_EVENT, 'base64')); + expect(Object.keys(await deviceQuery)).to.have.length(1); });