Skip to content

Commit

Permalink
Fix iOS remove devices from hub (#922)
Browse files Browse the repository at this point in the history
  • Loading branch information
saikrishna321 authored Dec 13, 2023
1 parent a2620a0 commit d35b6f0
Show file tree
Hide file tree
Showing 15 changed files with 47,080 additions and 18,042 deletions.
64,827 changes: 46,925 additions & 17,902 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "appium-device-farm",
"version": "8.4.2",
"version": "8.4.3",
"description": "An appium 2.0 plugin that manages and create driver session on available devices",
"main": "./lib/src/index.js",
"scripts": {
Expand Down
9 changes: 1 addition & 8 deletions server-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,7 @@
"device-farm": {
"platform": "android",
"skipChromeDownload": true,
"proxy": {
"host": "10.32.80.80",
"port": 800,
"auth": { "username": "username", "password": "password" }
},
"derivedDataPath": {
"simulator": "/Users/saikrishna/Library/Developer/Xcode/DerivedData/WebDriverAgent-Test"
}
"hub": "http://10.211.55.3:31337"
}
}
}
Expand Down
52 changes: 26 additions & 26 deletions src/data-service/device-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import { IDeviceFilterOptions } from '../interfaces/IDeviceFilterOptions';
import log from '../logger';
import { setUtilizationTime } from '../device-utils';

export function removeDevice(devices: { udid: string; host: string}[]) {
export function removeDevice(devices: { udid: string; host: string }[]) {
devices.forEach(function (device) {
log.info(`Removing device ${device.udid} from host ${device.host} from device list.`);
DeviceModel.chain()
.find({ udid: device.udid, host: { $contains: device.host } })
.remove();
})
});
}

export function addNewDevice(devices: IDevice[]) {
Expand Down Expand Up @@ -171,31 +171,31 @@ export function updateCmdExecutedTime(sessionId: string) {
export async function unblockDevice(filter: object) {
const devices = DeviceModel.chain().find(filter).data();
if (devices !== undefined) {
console.log(
`Found ${devices.length} devices to unblock with filter ${JSON.stringify(filter)}`,
console.log(`Found ${devices.length} devices to unblock with filter ${JSON.stringify(filter)}`);

await Promise.all(
devices.map(async (device) => {
const sessionStart = device.sessionStartTime;
const currentTime = new Date().getTime();
let utilization = currentTime - sessionStart;
// no session time recorded means device was never used
if (sessionStart === 0) {
utilization = 0;
}
const totalUtilization = device.totalUtilizationTimeMilliSec + utilization;
await setUtilizationTime(device.udid, totalUtilization);
DeviceModel.chain()
.find(filter)
.update(function (device: IDevice) {
device.session_id = undefined;
device.busy = false;
device.lastCmdExecutedAt = undefined;
device.sessionStartTime = 0;
device.totalUtilizationTimeMilliSec = totalUtilization;
device.newCommandTimeout = undefined;
});
}),
);

await Promise.all(devices.map(async (device) => {
const sessionStart = device.sessionStartTime;
const currentTime = new Date().getTime();
let utilization = currentTime - sessionStart;
// no session time recorded means device was never used
if (sessionStart === 0) {
utilization = 0;
}
const totalUtilization = device.totalUtilizationTimeMilliSec + utilization;
await setUtilizationTime(device.udid, totalUtilization);
DeviceModel.chain()
.find(filter)
.update(function (device: IDevice) {
device.session_id = undefined;
device.busy = false;
device.lastCmdExecutedAt = undefined;
device.sessionStartTime = 0;
device.totalUtilizationTimeMilliSec = totalUtilization;
device.newCommandTimeout = undefined;
});
}));
} else {
console.log(`Not able to find device to unblock with filter ${JSON.stringify(filter)}`);
}
Expand Down
39 changes: 25 additions & 14 deletions src/device-managers/AndroidDeviceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ export default class AndroidDeviceManager implements IDeviceManager {
private adbAvailable = true;
private abortControl: Map<string, AbortController> = new Map();

constructor(private pluginArgs: IPluginArgs, private hostPort: number) {

}
constructor(
private pluginArgs: IPluginArgs,
private hostPort: number,
) {}

private initiateAbortControl(deviceUdid: string) {
const control = new AbortController();
Expand All @@ -45,7 +46,7 @@ export default class AndroidDeviceManager implements IDeviceManager {

async getDevices(
deviceTypes: { androidDeviceType: DeviceTypeToInclude },
existingDeviceDetails: Array<IDevice>
existingDeviceDetails: Array<IDevice>,
): Promise<any> {
if (!this.adbAvailable) {
return [];
Expand Down Expand Up @@ -107,7 +108,12 @@ export default class AndroidDeviceManager implements IDeviceManager {
// device may have changed the status since the last time we queried
// we want to avoid device with offline or unauthorized status
if (device.state === 'device') {
const deviceInfo = await this.deviceInfo(device, adbInstance, this.pluginArgs, this.hostPort);
const deviceInfo = await this.deviceInfo(
device,
adbInstance,
this.pluginArgs,
this.hostPort,
);
if (!deviceInfo) {
log.info(`Cannot get device info for ${device.udid}. Skipping`);
} else {
Expand Down Expand Up @@ -244,11 +250,7 @@ export default class AndroidDeviceManager implements IDeviceManager {
host: adbHost,
port: adbPort,
});
const remoteAdbTracking = this.createRemoteAdbTracker(
remoteAdb,
originalADB,
adbHost
);
const remoteAdbTracking = this.createRemoteAdbTracker(remoteAdb, originalADB, adbHost);
remoteAdbTracking();
});
}
Expand All @@ -275,7 +277,12 @@ export default class AndroidDeviceManager implements IDeviceManager {
}

this.cancelAbort(newDevice.udid);
const trackedDevice = await this.deviceInfo(newDevice, originalADB, this.pluginArgs, this.hostPort);
const trackedDevice = await this.deviceInfo(
newDevice,
originalADB,
this.pluginArgs,
this.hostPort,
);

if (!trackedDevice) {
log.info(`Cannot get device info for ${newDevice.udid}. Skipping`);
Expand Down Expand Up @@ -310,7 +317,7 @@ export default class AndroidDeviceManager implements IDeviceManager {
} else {
this.onDeviceAdded(originalADB, device);
}
})
});
tracker.on('end', () => log.info('Tracking stopped'));
} catch (err: any) {
log.error('Something went wrong:', err.stack);
Expand All @@ -321,7 +328,11 @@ export default class AndroidDeviceManager implements IDeviceManager {
}

private async onDeviceRemoved(device: DeviceWithPath, pluginArgs: IPluginArgs) {
const clonedDevice: DeviceUpdate = { udid: device['id'], host: ip.address(), state: device.type };
const clonedDevice: DeviceUpdate = {
udid: device['id'],
host: ip.address(),
state: device.type,
};
if (pluginArgs.hub != undefined) {
const nodeDevices = new NodeDevices(pluginArgs.hub);
await nodeDevices.postDevicesToHub([clonedDevice], 'remove');
Expand Down Expand Up @@ -349,7 +360,7 @@ export default class AndroidDeviceManager implements IDeviceManager {
} else {
this.onDeviceAdded(originalADB, device);
}
})
});
tracker.on('end', () => console.log('Tracking stopped'));
} catch (err: any) {
console.error('Something went wrong:', err.stack);
Expand Down
39 changes: 29 additions & 10 deletions src/device-managers/IOSDeviceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,25 @@ import { DeviceTypeToInclude, IDerivedDataPath, IPluginArgs } from '../interface
import e from 'express';

export default class IOSDeviceManager implements IDeviceManager {
constructor(private pluginArgs: IPluginArgs, private hostPort: number) {}
constructor(
private pluginArgs: IPluginArgs,
private hostPort: number,
) {}
/**
* Method to get all ios devices and simulators
*
* @returns {Promise<Array<IDevice>>}
*/
async getDevices(
deviceTypes: { iosDeviceType: DeviceTypeToInclude },
existingDeviceDetails: Array<IDevice>
existingDeviceDetails: Array<IDevice>,
): Promise<IDevice[]> {
if (deviceTypes.iosDeviceType === 'real') {
return flatten(await Promise.all([this.getRealDevices(existingDeviceDetails, this.pluginArgs, this.hostPort)]));
return flatten(
await Promise.all([
this.getRealDevices(existingDeviceDetails, this.pluginArgs, this.hostPort),
]),
);
} else if (deviceTypes.iosDeviceType === 'simulated') {
return flatten(await Promise.all([this.getSimulators()]));
} else {
Expand Down Expand Up @@ -74,7 +81,7 @@ export default class IOSDeviceManager implements IDeviceManager {
private async getRealDevices(
existingDeviceDetails: Array<IDevice>,
pluginArgs: IPluginArgs,
hostPort: number
hostPort: number,
): Promise<Array<IDevice>> {
const deviceState: Array<IDevice> = [];
if (this.pluginArgs.cloud !== undefined) {
Expand All @@ -84,10 +91,14 @@ export default class IOSDeviceManager implements IDeviceManager {
await this.fetchLocalIOSDevices(existingDeviceDetails, deviceState, pluginArgs, hostPort);
}
const returnDevices = deviceState.filter((device) => device.realDevice === true);
return returnDevices
return returnDevices;
}

private prepareDerivedDataPath(derivedDataPath: IDerivedDataPath | undefined, udid: string, realDevice: boolean): string {
private prepareDerivedDataPath(
derivedDataPath: IDerivedDataPath | undefined,
udid: string,
realDevice: boolean,
): string {
function derivedPathExtracted(tmpPath: string, theDerivedDataPath?: string) {
if (theDerivedDataPath !== undefined) {
fs.copySync(theDerivedDataPath, tmpPath);
Expand Down Expand Up @@ -124,7 +135,7 @@ export default class IOSDeviceManager implements IDeviceManager {
existingDeviceDetails: IDevice[],
deviceState: IDevice[],
pluginArgs: IPluginArgs,
hostPort: number
hostPort: number,
) {
const devices = await this.getConnectedDevices();
await asyncForEach(devices, async (udid: string) => {
Expand Down Expand Up @@ -159,7 +170,7 @@ export default class IOSDeviceManager implements IDeviceManager {
}
});
goIosTracker.on('device-removed', async (message) => {
const deviceRemoved: any = { udid: message.id, host: ip.address() };
const deviceRemoved: any = [{ udid: message.id, host: ip.address() }];
if (pluginArgs.hub !== undefined) {
log.info(`iOS device with udid ${message.id} unplugged! updating hub device list...`);
const nodeDevices = new NodeDevices(pluginArgs.hub);
Expand All @@ -171,7 +182,11 @@ export default class IOSDeviceManager implements IDeviceManager {
});
}

private async getDeviceInfo(udid: string, pluginArgs: IPluginArgs, hostPort: number): Promise<IDevice> {
private async getDeviceInfo(
udid: string,
pluginArgs: IPluginArgs,
hostPort: number,
): Promise<IDevice> {
let host;
if (pluginArgs.remoteMachineProxyIP) {
host = pluginArgs.remoteMachineProxyIP;
Expand Down Expand Up @@ -244,7 +259,11 @@ export default class IOSDeviceManager implements IDeviceManager {
host: `http://${ip.address()}:${this.hostPort}`,
totalUtilizationTimeMilliSec: totalUtilizationTimeMilliSec,
sessionStartTime: 0,
derivedDataPath: this.prepareDerivedDataPath(this.pluginArgs.derivedDataPath, device.udid, false),
derivedDataPath: this.prepareDerivedDataPath(
this.pluginArgs.derivedDataPath,
device.udid,
false,
),
}),
);
});
Expand Down
12 changes: 4 additions & 8 deletions src/device-managers/NodeDevices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,11 @@ export default class NodeDevices {
log.info(`Unblocking device ${this.host}/device-farm/api/unblock`);
try {
const status = (
await axios.post(
`${this.host}/device-farm/api/unblock`,
filter,
{
params: {
type: 'unblock',
},
await axios.post(`${this.host}/device-farm/api/unblock`, filter, {
params: {
type: 'unblock',
},
)
})
).status;
if (status === 200) {
log.info(`Unblocked device with filter: ${filter}`);
Expand Down
14 changes: 7 additions & 7 deletions src/device-managers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ export class DeviceFarmManager {

constructor(
platform: Platform | 'both',
private deviceTypes: { androidDeviceType: DeviceTypeToInclude; iosDeviceType: DeviceTypeToInclude },
private deviceTypes: {
androidDeviceType: DeviceTypeToInclude;
iosDeviceType: DeviceTypeToInclude;
},
hostPort: number,
private pluginArgs: IPluginArgs)
{
private pluginArgs: IPluginArgs,
) {
this.deviceTypes = deviceTypes;
if (platform.toLowerCase() === 'both') {
this.deviceManagers.push(new AndroidDeviceManager(pluginArgs, hostPort));
Expand All @@ -29,10 +32,7 @@ export class DeviceFarmManager {
const devices: IDevice[] = [];
for (const deviceManager of this.deviceManagers) {
devices.push(
...(await deviceManager.getDevices(
this.deviceTypes,
existingDeviceDetails || []
)),
...(await deviceManager.getDevices(this.deviceTypes, existingDeviceDetails || [])),
);
}
return devices;
Expand Down
Loading

0 comments on commit d35b6f0

Please sign in to comment.