Skip to content

Commit

Permalink
fix: Tune simulator app architecture validation (#2492)
Browse files Browse the repository at this point in the history
  • Loading branch information
mykola-mokhnach authored Nov 11, 2024
1 parent 76de05c commit 0738ae9
Showing 1 changed file with 45 additions and 10 deletions.
55 changes: 45 additions & 10 deletions lib/app-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const MAX_ARCHIVE_SCAN_DEPTH = 1;
export const SUPPORTED_EXTENSIONS = [IPA_EXT, APP_EXT];
const MACOS_RESOURCE_FOLDER = '__MACOSX';
const SANITIZE_REPLACEMENT = '-';
const INTEL_ARCH = 'x86_64';

/**
* Verify whether the given application is compatible to the
Expand Down Expand Up @@ -56,27 +57,47 @@ export async function verifyApplicationPlatform() {
return;
}

const executablePath = path.resolve(this.opts.app, await this.appInfosCache.extractExecutableName(this.opts.app));
const executablePath = path.resolve(
this.opts.app,
await this.appInfosCache.extractExecutableName(this.opts.app)
);
const [resFile, resUname] = await B.all([
exec('lipo', ['-info', executablePath]),
exec('uname', ['-m']),
]);
const bundleExecutableInfo = _.trim(resFile.stdout);
this.log.debug(bundleExecutableInfo);
const arch = _.trim(resUname.stdout);
const isAppleSilicon = os.cpus()[0].model.includes('Apple');
const processArch = _.trim(resUname.stdout);
this.log.debug(`Current process architecture: ${processArch}`);
const isAppleSiliconCpu = isAppleSilicon();
this.log.debug(`Is Apple Silicon CPU: ${isAppleSiliconCpu}`);
if (isAppleSiliconCpu && processArch === INTEL_ARCH) {
this.log.warn(
`It looks like the Appium server process is running under Rosetta emulation. ` +
`This might lead to various performance/compatibility issues while running tests on Simulator. ` +
`Consider using binaries compiled natively for the ARM64 architecture to run Appium server ` +
`with this driver.`
);
}
if (_.includes(bundleExecutableInfo, processArch)) {
return;
}
const hasRosetta = isAppleSiliconCpu && await isRosettaInstalled();
const isIntelApp = _.includes(bundleExecutableInfo, INTEL_ARCH);
// We cannot run Simulator builds compiled for arm64 on Intel machines
// Rosetta allows only to run Intel ones on arm64
if (
!_.includes(bundleExecutableInfo, arch) &&
!(isAppleSilicon && _.includes(bundleExecutableInfo, 'x86_64'))
(isIntelApp && (!isAppleSiliconCpu || hasRosetta)) || (!isIntelApp && isAppleSiliconCpu)
) {
throw new Error(
`The ${this.opts.bundleId} application does not support the ${arch} Simulator ` +
`architecture:\n${bundleExecutableInfo}\n\n` +
`Please rebuild your application to support the ${arch} platform.`,
);
return;
}
const advice = isIntelApp && isAppleSiliconCpu && !hasRosetta
? `Please install Rosetta and try again.`
: `Please rebuild your application to support the ${processArch} platform.`;
throw new Error(
`The ${this.opts.bundleId} application does not support the ${processArch} Simulator ` +
`architecture:\n${bundleExecutableInfo}\n\n${advice}`
);
}

/**
Expand Down Expand Up @@ -666,6 +687,20 @@ export async function onPostConfigureApp({cachedAppInfo, isUrl, appPath}) {
};
}

/**
* @returns {Promise<boolean>}
*/
async function isRosettaInstalled() {
return await fs.exists('/Library/Apple/usr/share/rosetta/rosetta');
}

/**
* @returns {boolean}
*/
function isAppleSilicon() {
return os.cpus()[0].model.includes('Apple');
}

/**
* @typedef {import('./driver').XCUITestDriver} XCUITestDriver
*/

0 comments on commit 0738ae9

Please sign in to comment.