mirror of
https://github.com/stablyai/orca.git
synced 2026-10-31 00:57:45 +00:00
fix(emulator): wait for the requested AVD during Android boot (#35536)
* fix(emulator): match the requested AVD while waiting for boot * test(emulator): trim AVD boot identity test to the regression case --------- Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { describe, expect, it, vi } from 'vitest'
|
||||
import { bootAndroidDevice } from './android-avd-boot'
|
||||
import type { AndroidSdkPaths } from './android-sdk-discovery'
|
||||
|
||||
vi.mock('node:child_process', () => ({
|
||||
spawn: () => ({ on: vi.fn(), unref: vi.fn() })
|
||||
}))
|
||||
|
||||
const sdk: AndroidSdkPaths = {
|
||||
sdkRoot: 'sdk',
|
||||
adb: 'adb',
|
||||
emulator: 'emulator',
|
||||
avdmanager: 'avdmanager'
|
||||
}
|
||||
type Device = { serial: string; name: string; booted: boolean }
|
||||
const other: Device = { serial: 'emulator-5556', name: 'Other', booted: true }
|
||||
const target: Device = {
|
||||
serial: 'emulator-5558',
|
||||
name: 'Wanted',
|
||||
booted: true
|
||||
}
|
||||
|
||||
function bootWithInventory(snapshots: Device[][]) {
|
||||
let reads = 0
|
||||
let current: Device[] = []
|
||||
const runner = vi.fn(async (binary: string, args: readonly string[]) => {
|
||||
let stdout = ''
|
||||
if (binary === sdk.emulator && args[0] === '-list-avds') {
|
||||
stdout = 'Wanted\nOther\n'
|
||||
} else if (args[0] === 'devices') {
|
||||
current = snapshots[Math.min(reads++, snapshots.length - 1)]
|
||||
stdout = `List of devices attached\n${current.map((d) => `${d.serial}\tdevice`).join('\n')}`
|
||||
} else {
|
||||
const device = current.find((d) => d.serial === args[1])
|
||||
stdout = args[2] === 'emu' ? `${device?.name ?? ''}\nOK\n` : device?.booted ? '1' : '0'
|
||||
}
|
||||
return { code: 0, stdout, stderr: '' }
|
||||
})
|
||||
return bootAndroidDevice(runner, sdk, 'Wanted', {
|
||||
bootTimeoutMs: 30,
|
||||
pollIntervalMs: 10,
|
||||
sleep: async () => {}
|
||||
})
|
||||
}
|
||||
|
||||
describe('Android AVD boot identity', () => {
|
||||
it('waits for the requested AVD when another emulator boots first', async () => {
|
||||
await expect(
|
||||
bootWithInventory([[], [other], [other, { ...target, booted: false }], [other, target]])
|
||||
).resolves.toBe(target.serial)
|
||||
await expect(bootWithInventory([[], [other]])).rejects.toThrow(
|
||||
'AVD "Wanted" did not finish booting in time.'
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -64,10 +64,11 @@ async function waitForNewBootedSerial(
|
||||
const fresh = (await listRunningAdbDevices(runner, sdk)).filter(
|
||||
(device) => device.isEmulator && !known.has(device.serial)
|
||||
)
|
||||
for (const device of fresh) {
|
||||
const booted = await runner(sdk.adb, bootCompletedArgs(device.serial))
|
||||
const serial = await findRunningAvdSerial(runner, sdk, avdName, fresh)
|
||||
if (serial) {
|
||||
const booted = await runner(sdk.adb, bootCompletedArgs(serial))
|
||||
if (isBootCompleted(booted.stdout)) {
|
||||
return device.serial
|
||||
return serial
|
||||
}
|
||||
}
|
||||
await options.sleep(options.pollIntervalMs)
|
||||
|
||||
@@ -235,6 +235,9 @@ describe('AndroidEmulatorBackend', () => {
|
||||
if (binary === SDK.adb && a === '-s emulator-5556 shell getprop sys.boot_completed') {
|
||||
return ok('1')
|
||||
}
|
||||
if (binary === SDK.adb && a === '-s emulator-5556 emu avd name') {
|
||||
return ok('Pixel_Tablet\nOK\n')
|
||||
}
|
||||
if (binary === SDK.emulator && a === '-list-avds') {
|
||||
return ok('Pixel_Tablet')
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user