ci: enable arm64 macOS tests (#24832)

* ci: enable arm64 macOS tests
This commit is contained in:
John Kleinschmidt 2021-01-21 18:36:52 -05:00 committed by GitHub
parent 4f930b6e42
commit 034a792df1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 138 additions and 108 deletions

View file

@ -97,6 +97,10 @@ machine-mac-large-arm: &machine-mac-large-arm
macos:
xcode: "12.2.0"
machine-mac-arm64: &machine-mac-arm64
resource_class: electronjs/macos-arm64
machine: true
# Build configurations options.
env-testing-build: &env-testing-build
GN_CONFIG: //electron/build/args/testing.gn
@ -141,6 +145,7 @@ env-apple-silicon: &env-apple-silicon
GN_EXTRA_ARGS: 'target_cpu = "arm64" use_prebuilt_v8_context_snapshot = true'
TARGET_ARCH: arm64
USE_PREBUILT_V8_CONTEXT_SNAPSHOT: 1
npm_config_arch: arm64
env-arm64: &env-arm64
GN_EXTRA_ARGS: 'target_cpu = "arm64" fatal_linker_warnings = false enable_linux_installer = false'
@ -457,7 +462,7 @@ step-install-signing-cert-on-mac: &step-install-signing-cert-on-mac
run:
name: Import and trust self-signed codesigning cert on MacOS
command: |
if [ "`uname`" == "Darwin" ]; then
if [ "$TARGET_ARCH" != "arm64" ] && [ "`uname`" == "Darwin" ]; then
cd src/electron
./script/codesign/generate-identity.sh
fi
@ -670,6 +675,7 @@ step-persist-data-for-tests: &step-persist-data-for-tests
- src/electron
- src/third_party/electron_node
- src/third_party/nan
- src/cross-arch-snapshots
step-electron-dist-unzip: &step-electron-dist-unzip
run:
@ -732,7 +738,11 @@ step-verify-mksnapshot: &step-verify-mksnapshot
name: Verify mksnapshot
command: |
cd src
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
if [ "$TARGET_ARCH" == "arm64" ] &&[ "`uname`" == "Darwin" ]; then
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default --snapshot-files-dir $PWD/cross-arch-snapshots
else
python electron/script/verify-mksnapshot.py --source-root "$PWD" --build-dir out/Default
fi
step-verify-chromedriver: &step-verify-chromedriver
run:
@ -835,7 +845,7 @@ step-maybe-cross-arch-snapshot: &step-maybe-cross-arch-snapshot
run:
name: Generate cross arch snapshot (arm/arm64)
command: |
if [ "$TRIGGER_ARM_TEST" == "true" ] && [ -z "$CIRCLE_PR_NUMBER" ]; then
if [ "$GENERATE_CROSS_ARCH_SNAPSHOT" == "true" ] && [ -z "$CIRCLE_PR_NUMBER" ]; then
cd src
if [ "$TARGET_ARCH" == "arm" ]; then
export MKSNAPSHOT_PATH="clang_x86_v8_arm"
@ -868,8 +878,13 @@ step-maybe-trigger-arm-test: &step-maybe-trigger-arm-test
if [ "$TRIGGER_ARM_TEST" == "true" ] && [ -z "$CIRCLE_PR_NUMBER" ]; then
#Trigger VSTS job, passing along CircleCI job number and branch to build
if [ "`uname`" == "Darwin" ]; then
echo "Triggering electron-arm2-testing build on Azure DevOps"
node electron/script/release/ci-release-build.js --job=electron-arm2-testing --ci=DevOps --armTest --circleBuildNum=$CIRCLE_BUILD_NUM $CIRCLE_BRANCH
if [ x"$MAS_BUILD" == x"true" ]; then
export DEVOPS_BUILD="electron-mas-arm64-testing"
else
export DEVOPS_BUILD="electron-osx-arm64-testing"
fi
echo "Triggering $DEVOPS_BUILD build on Azure DevOps"
node electron/script/release/ci-release-build.js --job=$DEVOPS_BUILD --ci=DevOps --armTest --circleBuildNum=$CIRCLE_BUILD_NUM $CIRCLE_BRANCH
else
echo "Triggering electron-$TARGET_ARCH-testing build on VSTS"
node electron/script/release/ci-release-build.js --job=electron-$TARGET_ARCH-testing --ci=VSTS --armTest --circleBuildNum=$CIRCLE_BUILD_NUM $CIRCLE_BRANCH
@ -1290,8 +1305,14 @@ steps-tests: &steps-tests
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
command: |
cd src
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec-main/*-spec.ts | circleci tests split))
(cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.js | circleci tests split))
if [ "$TARGET_ARCH" == "arm64" ] &&[ "`uname`" == "Darwin" ]; then
export ELECTRON_SKIP_NATIVE_MODULE_TESTS=true
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging)
(cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging)
else
(cd electron && node script/yarn test --runners=main --trace-uncaught --enable-logging --files $(circleci tests glob spec-main/*-spec.ts | circleci tests split))
(cd electron && node script/yarn test --runners=remote --trace-uncaught --enable-logging --files $(circleci tests glob spec/*-spec.js | circleci tests split))
fi
- run:
name: Check test results existence
command: |
@ -1889,6 +1910,7 @@ jobs:
<<: *env-testing-build
<<: *env-ninja-status
TRIGGER_ARM_TEST: true
GENERATE_CROSS_ARCH_SNAPSHOT: true
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
@ -1947,6 +1969,7 @@ jobs:
<<: *env-testing-build
<<: *env-ninja-status
TRIGGER_ARM_TEST: true
GENERATE_CROSS_ARCH_SNAPSHOT: true
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_arm=True --custom-var=checkout_arm64=True'
steps:
- electron-build:
@ -2098,6 +2121,7 @@ jobs:
<<: *env-macos-build
<<: *env-apple-silicon
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
GENERATE_CROSS_ARCH_SNAPSHOT: true
steps:
- electron-build:
persist: true
@ -2204,6 +2228,7 @@ jobs:
<<: *env-macos-build
<<: *env-mas-apple-silicon
GCLIENT_EXTRA_ARGS: '--custom-var=checkout_mac=True --custom-var=host_os=mac'
GENERATE_CROSS_ARCH_SNAPSHOT: true
steps:
- electron-build:
persist: true
@ -2357,6 +2382,14 @@ jobs:
<<: *env-send-slack-notifications
<<: *steps-verify-ffmpeg
osx-testing-arm64-tests:
<<: *machine-mac-arm64
environment:
<<: *env-mac-large
<<: *env-stack-dumping
<<: *env-apple-silicon
<<: *steps-tests
mas-testing-x64-tests:
<<: *machine-mac-large
environment:
@ -2380,6 +2413,14 @@ jobs:
<<: *env-send-slack-notifications
<<: *steps-verify-ffmpeg
mas-testing-arm64-tests:
<<: *machine-mac-arm64
environment:
<<: *env-mac-large
<<: *env-stack-dumping
<<: *env-apple-silicon
<<: *steps-tests
# Layer 4: Summary.
linux-x64-release-summary:
<<: *machine-linux-medium
@ -2591,6 +2632,14 @@ workflows:
requires:
- mac-checkout-and-save-cache
- osx-testing-arm64-tests:
filters:
branches:
# Do not run this on forked pull requests
ignore: /pull\/[0-9]+/
requires:
- osx-testing-arm64
- mas-testing-x64:
requires:
- mac-checkout-and-save-cache
@ -2607,6 +2656,14 @@ workflows:
requires:
- mac-checkout-and-save-cache
- mas-testing-arm64-tests:
filters:
branches:
# Do not run this on forked pull requests
ignore: /pull\/[0-9]+/
requires:
- mas-testing-arm64
nightly-linux-release-test:
triggers:
- schedule:

View file

@ -17,6 +17,7 @@ steps:
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=dist.zip --dest=$ZIP_DEST
cd $ZIP_DEST
unzip -o dist.zip
xattr -cr Electron.app
displayName: 'Download and unzip dist files for test'
env:
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
@ -48,38 +49,44 @@ steps:
mkdir -p $CROSS_ARCH_SNAPSHOTS
cd src/electron
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/snapshot_blob.bin --dest=$CROSS_ARCH_SNAPSHOTS
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/v8_context_snapshot.bin --dest=$CROSS_ARCH_SNAPSHOTS
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=cross-arch-snapshots/v8_context_snapshot.arm64.bin --dest=$CROSS_ARCH_SNAPSHOTS
displayName: 'Download cross arch snapshot files'
env:
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
- bash: |
export NATIVE_UNITTESTS_DEST=$PWD/src/out/Default
cd src/electron
node script/download-circleci-artifacts.js --buildNum=$CIRCLE_BUILD_NUM --name=shell_browser_ui_unittests --dest=$NATIVE_UNITTESTS_DEST
chmod +x $NATIVE_UNITTESTS_DEST/shell_browser_ui_unittests
displayName: 'Download native unittest executables'
env:
CIRCLE_TOKEN: $(CIRCLECI_TOKEN)
- bash: |
cd src
export ELECTRON_OUT_DIR=Default
set npm_config_arch=arm64
(cd electron && node script/yarn test -- --enable-logging)
displayName: 'Run Electron tests'
export npm_config_arch=arm64
(cd electron && node script/yarn test --enable-logging --runners main)
displayName: 'Run Electron main tests'
timeoutInMinutes: 20
env:
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
IGNORE_YARN_INSTALL_ERROR: 1
ELECTRON_TEST_RESULTS_DIR: junit
- bash: |
cd src
export ELECTRON_OUT_DIR=Default
export npm_config_arch=arm64
(cd electron && node script/yarn test --enable-logging --runners remote)
displayName: 'Run Electron remote tests'
timeoutInMinutes: 20
condition: succeededOrFailed()
env:
ELECTRON_DISABLE_SECURITY_WARNINGS: 1
IGNORE_YARN_INSTALL_ERROR: 1
ELECTRON_TEST_RESULTS_DIR: junit
- bash: |
cd src
python electron/script/verify-ffmpeg.py --source-root "$PWD" --build-dir out/Default --ffmpeg-path out/ffmpeg
displayName: Verify non proprietary ffmpeg
timeoutInMinutes: 5
condition: succeededOrFailed()
env:
TARGET_ARCH: arm64
- bash: |
cd src
@ -98,6 +105,16 @@ steps:
condition: succeededOrFailed()
- bash: killall Electron || echo "No Electron processes left running"
displayName: 'Kill processes left running from last test run'
condition: always()
- bash: |
rm -rf ~/Library/Application\ Support/Electron*
rm -rf ~/Library/Application\ Support/electron*
displayName: 'Delete user app data directories'
condition: always()
- task: mspremier.PostBuildCleanup.PostBuildCleanup-task.PostBuildCleanup@3
displayName: 'Clean Agent Directories'

View file

@ -7,5 +7,4 @@ workaround_an_undefined_symbol_error.patch
do_not_export_private_v8_symbols_on_windows.patch
revert_cleanup_switch_offset_of_to_offsetof_where_possible.patch
fix_build_deprecated_attirbute_for_older_msvc_versions.patch
fix_use_proper_page_size_for_mac_arm64.patch
chore_disallow_copying_cppheapcreateparams.patch

View file

@ -1,43 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: John Kleinschmidt <jkleinsc@github.com>
Date: Wed, 8 Jul 2020 10:46:13 -0400
Subject: fix: use proper page size for mac arm64
This fix temporarily sets page size to 16k for mac arm64 so that mksnapshot can run on x64
and generate a mac arm64 snapshot
diff --git a/src/base/platform/platform-posix.cc b/src/base/platform/platform-posix.cc
index ab0d7839a453d87a8404ca791c1022871e8fd606..821a3925e91c229873f75ac024c1b388b4d0c06e 100644
--- a/src/base/platform/platform-posix.cc
+++ b/src/base/platform/platform-posix.cc
@@ -165,9 +165,19 @@ void* Allocate(void* hint, size_t size, OS::MemoryPermission access,
PageType page_type) {
int prot = GetProtectionFromMemoryPermission(access);
int flags = GetFlagsForMemoryPermission(access, page_type);
+#if defined(__APPLE__) && V8_TARGET_ARCH_ARM64 && defined(__x86_64__)
+ // XXX: This logic is simple and leaky as it is only used for mksnapshot.
+ size_t alignment = 16384;
+ void* result = mmap(hint, size + alignment, prot, flags, kMmapFd,
+ kMmapFdOffset);
+ if (result == MAP_FAILED) return nullptr;
+ return reinterpret_cast<void*>(
+ RoundUp(reinterpret_cast<uintptr_t>(result), alignment));
+#else
void* result = mmap(hint, size, prot, flags, kMmapFd, kMmapFdOffset);
if (result == MAP_FAILED) return nullptr;
return result;
+#endif
}
#endif // !V8_OS_FUCHSIA
@@ -224,7 +234,9 @@ void OS::Initialize(bool hard_abort, const char* const gc_fake_mmap) {
}
int OS::ActivationFrameAlignment() {
-#if V8_TARGET_ARCH_ARM
+#if defined(__APPLE__) && V8_TARGET_ARCH_ARM
+ return 4;
+#elif V8_TARGET_ARCH_ARM
// On EABI ARM targets this is required for fp correctness in the
// runtime system.
return 8;

View file

@ -33,7 +33,8 @@ const circleCIJobs = circleCIPublishWorkflows.concat([
const vstsArmJobs = [
'electron-arm-testing',
'electron-arm2-testing',
'electron-osx-arm64-testing',
'electron-mas-arm64-testing',
'electron-arm64-testing',
'electron-woa-testing'
];

View file

@ -48,7 +48,7 @@ def main():
# FIXME: Enable after ELECTRON_ENABLE_LOGGING works again
# env['ELECTRON_ENABLE_LOGGING'] = 'true'
testargs = [electron, test_path]
if sys.platform == 'win32' and platform.machine() == 'ARM64':
if sys.platform != 'linux' and (platform.machine() == 'ARM64' or os.environ.get('TARGET_ARCH') == 'arm64'):
testargs.append('--disable-accelerated-video-decode')
subprocess.check_call(testargs, env=env)
except subprocess.CalledProcessError as e:

View file

@ -32,7 +32,10 @@ def main():
print('ok mksnapshot successfully created snapshot_blob.bin.')
context_snapshot = 'v8_context_snapshot.bin'
if platform.system() == 'Darwin':
context_snapshot = 'v8_context_snapshot.x86_64.bin'
if os.environ.get('TARGET_ARCH') == 'arm64':
context_snapshot = 'v8_context_snapshot.arm64.bin'
else:
context_snapshot = 'v8_context_snapshot.x86_64.bin'
context_snapshot_path = os.path.join(app_path, context_snapshot)
gen_binary = get_binary_path('v8_context_snapshot_generator', \
app_path)

View file

@ -594,7 +594,7 @@ describe('app module', () => {
});
});
describe('app.get/setLoginItemSettings API', function () {
ifdescribe(process.platform !== 'linux' && !process.mas)('app.get/setLoginItemSettings API', function () {
const updateExe = path.resolve(path.dirname(process.execPath), '..', 'Update.exe');
const processStartArgs = [
'--processStart', `"${path.basename(process.execPath)}"`,
@ -611,10 +611,6 @@ describe('app module', () => {
'/d'
];
before(function () {
if (process.platform === 'linux' || process.mas) this.skip();
});
beforeEach(() => {
app.setLoginItemSettings({ openAtLogin: false });
app.setLoginItemSettings({ openAtLogin: false, path: updateExe, args: processStartArgs });

View file

@ -54,7 +54,7 @@ ifdescribe(!process.mas)('autoUpdater module', function () {
});
});
ifdescribe(process.platform === 'darwin')('on Mac', function () {
ifdescribe(process.platform === 'darwin' && process.arch !== 'arm64')('on Mac', function () {
it('emits an error when the application is unsigned', async () => {
const errorEvent = emittedOnce(autoUpdater, 'error');
autoUpdater.setFeedURL({ url: '' });

View file

@ -6,15 +6,14 @@ import * as fs from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
import { AddressInfo } from 'net';
import { ifdescribe } from './spec-helpers';
const features = process._linkedBinding('electron_common_features');
const fixturesPath = path.resolve(__dirname, 'fixtures');
// We can only test the auto updater on darwin non-component builds
const describeFn = (process.platform === 'darwin' && !process.mas && !features.isComponentBuild() ? describe : describe.skip);
describeFn('autoUpdater behavior', function () {
ifdescribe(process.platform === 'darwin' && process.arch !== 'arm64' && !process.mas && !features.isComponentBuild())('autoUpdater behavior', function () {
this.timeout(120000);
let identity = '';

View file

@ -5,7 +5,7 @@ import * as path from 'path';
import { ifdescribe, delay } from './spec-helpers';
// FIXME: The tests are skipped on arm/arm64.
ifdescribe(!(process.platform !== 'win32' && ['arm', 'arm64'].includes(process.arch)))('contentTracing', () => {
ifdescribe(!(['arm', 'arm64'].includes(process.arch)))('contentTracing', () => {
const record = async (options: TraceConfig | TraceCategoriesAndOptions, outputFilePath: string | undefined, recordTimeInMilliseconds = 1e1) => {
await app.whenReady();

View file

@ -1483,7 +1483,7 @@ describe('net module', () => {
const urlRequest = net.request(serverUrl);
urlRequest.end(randomBuffer(kOneMegaByte));
const [error] = await emittedOnce(urlRequest, 'error');
expect(error.message).to.be.oneOf(['net::ERR_CONNECTION_RESET', 'net::ERR_CONNECTION_ABORTED']);
expect(error.message).to.be.oneOf(['net::ERR_FAILED', 'net::ERR_CONNECTION_RESET', 'net::ERR_CONNECTION_ABORTED']);
});
it('should not emit any event after close', async () => {

View file

@ -1738,28 +1738,6 @@ describe('webContents module', () => {
expect(data).to.be.an.instanceof(Buffer).that.is.not.empty();
});
it('respects custom settings', async () => {
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf.html'));
const data = await w.webContents.printToPDF({
pageRanges: {
from: 0,
to: 2
},
landscape: true
});
const doc = await pdfjs.getDocument(data).promise;
// Check that correct # of pages are rendered.
expect(doc.numPages).to.equal(3);
// Check that PDF is generated in landscape mode.
const firstPage = await doc.getPage(1);
const { width, height } = firstPage.getViewport({ scale: 100 });
expect(width).to.be.greaterThan(height);
});
it('does not crash when called multiple times in parallel', async () => {
const promises = [];
for (let i = 0; i < 3; i++) {
@ -1783,6 +1761,35 @@ describe('webContents module', () => {
expect(data).to.be.an.instanceof(Buffer).that.is.not.empty();
}
});
describe('using a large document', () => {
beforeEach(async () => {
w = new BrowserWindow({ show: false, webPreferences: { sandbox: true } });
await w.loadFile(path.join(__dirname, 'fixtures', 'api', 'print-to-pdf.html'));
});
afterEach(closeAllWindows);
it('respects custom settings', async () => {
const data = await w.webContents.printToPDF({
pageRanges: {
from: 0,
to: 2
},
landscape: true
});
const doc = await pdfjs.getDocument(data).promise;
// Check that correct # of pages are rendered.
expect(doc.numPages).to.equal(3);
// Check that PDF is generated in landscape mode.
const firstPage = await doc.getPage(1);
const { width, height } = firstPage.getViewport({ scale: 100 });
expect(width).to.be.greaterThan(height);
});
});
});
describe('PictureInPicture video', () => {

View file

@ -5,7 +5,7 @@ const path = require('path');
const temp = require('temp').track();
const util = require('util');
const { emittedOnce } = require('./events-helpers');
const { ifit } = require('./spec-helpers');
const { ifit, ifdescribe } = require('./spec-helpers');
const nativeImage = require('electron').nativeImage;
const features = process._linkedBinding('electron_common_features');
@ -1385,17 +1385,11 @@ describe('asar package', function () {
});
});
describe('child_process.execFile', function () {
ifdescribe(process.platform === 'darwin' && process.arch !== 'arm64')('child_process.execFile', function () {
const execFile = ChildProcess.execFile;
const execFileSync = ChildProcess.execFileSync;
const echo = path.join(asarDir, 'echo.asar', 'echo');
before(function () {
if (process.platform !== 'darwin') {
this.skip();
}
});
it('executes binaries', function (done) {
execFile(echo, ['test'], function (error, stdout) {
try {