diff --git a/spec-main/api-app-spec.ts b/spec-main/api-app-spec.ts index cbbcee1895..ceae307529 100644 --- a/spec-main/api-app-spec.ts +++ b/spec-main/api-app-spec.ts @@ -143,7 +143,8 @@ describe('app module', () => { }); }); - describe('app.exit(exitCode)', () => { + // Running child app under ASan might receive SIGKILL because of OOM. + ifdescribe(!process.env.IS_ASAN)('app.exit(exitCode)', () => { let appProcess: cp.ChildProcess | null = null; afterEach(() => { @@ -209,7 +210,7 @@ describe('app module', () => { }); }); - // TODO(jeremy): figure out why these tests time out under ASan + // Running child app under ASan might receive SIGKILL because of OOM. ifdescribe(!process.env.IS_ASAN)('app.requestSingleInstanceLock', () => { it('prevents the second launch of app', async function () { this.timeout(120000); @@ -252,7 +253,8 @@ describe('app module', () => { }); }); - describe('app.relaunch', () => { + // Running child app under ASan might receive SIGKILL because of OOM. + ifdescribe(!process.env.IS_ASAN)('app.relaunch', () => { let server: net.Server | null = null; const socketPath = process.platform === 'win32' ? '\\\\.\\pipe\\electron-app-relaunch' : '/tmp/electron-app-relaunch'; @@ -852,7 +854,8 @@ describe('app module', () => { }); }); - describe('getAppPath', () => { + // Running child app under ASan might receive SIGKILL because of OOM. + ifdescribe(!process.env.IS_ASAN)('getAppPath', () => { it('works for directories with package.json', async () => { const { appPath } = await runTestApp('app-path'); expect(appPath).to.equal(path.resolve(fixturesPath, 'api/app-path')); @@ -1128,13 +1131,7 @@ describe('app module', () => { }); }); - describe('app launch through uri', () => { - before(function () { - if (process.platform !== 'win32') { - this.skip(); - } - }); - + ifdescribe(process.platform === 'win32')('app launch through uri', () => { it('does not launch for argument following a URL', async () => { const appPath = path.join(fixturesPath, 'api', 'quit-app'); // App should exit with non 123 code. @@ -1334,7 +1331,8 @@ describe('app module', () => { }); }); - describe('sandbox options', () => { + // Running child app under ASan might receive SIGKILL because of OOM. + ifdescribe(!process.env.IS_ASAN)('sandbox options', () => { let appProcess: cp.ChildProcess = null as any; let server: net.Server = null as any; const socketPath = process.platform === 'win32' ? '\\\\.\\pipe\\electron-mixed-sandbox' : '/tmp/electron-mixed-sandbox'; @@ -1375,8 +1373,7 @@ describe('app module', () => { }); describe('when app.enableSandbox() is called', () => { - // TODO(jeremy): figure out why this times out under ASan - ifit(!process.env.IS_ASAN)('adds --enable-sandbox to all renderer processes', done => { + it('adds --enable-sandbox to all renderer processes', done => { const appPath = path.join(fixturesPath, 'api', 'mixed-sandbox-app'); appProcess = cp.spawn(process.execPath, [appPath, '--app-enable-sandbox']); @@ -1401,8 +1398,7 @@ describe('app module', () => { }); describe('when the app is launched with --enable-sandbox', () => { - // TODO(jeremy): figure out why this times out under ASan - ifit(!process.env.IS_ASAN)('adds --enable-sandbox to all renderer processes', done => { + it('adds --enable-sandbox to all renderer processes', done => { const appPath = path.join(fixturesPath, 'api', 'mixed-sandbox-app'); appProcess = cp.spawn(process.execPath, [appPath, '--enable-sandbox']); @@ -1561,7 +1557,8 @@ describe('app module', () => { }); }); - describe('commandLine.hasSwitch (existing argv)', () => { + // Running child app under ASan might receive SIGKILL because of OOM. + ifdescribe(!process.env.IS_ASAN)('commandLine.hasSwitch (existing argv)', () => { it('returns true when present', async () => { const { hasSwitch } = await runTestApp('command-line', '--foobar'); expect(hasSwitch).to.equal(true); @@ -1589,7 +1586,8 @@ describe('app module', () => { }); }); - describe('commandLine.getSwitchValue (existing argv)', () => { + // Running child app under ASan might receive SIGKILL because of OOM. + ifdescribe(!process.env.IS_ASAN)('commandLine.getSwitchValue (existing argv)', () => { it('returns the value when present', async () => { const { getSwitchValue } = await runTestApp('command-line', '--foobar=test'); expect(getSwitchValue).to.equal('test'); @@ -1616,7 +1614,8 @@ describe('app module', () => { }); }); -describe('default behavior', () => { +// Running child app under ASan might receive SIGKILL because of OOM. +ifdescribe(!process.env.IS_ASAN)('default behavior', () => { describe('application menu', () => { it('creates the default menu if the app does not set it', async () => { const result = await runTestApp('default-menu'); diff --git a/spec-main/api-protocol-spec.ts b/spec-main/api-protocol-spec.ts index 54483eb98a..31abb6ce13 100644 --- a/spec-main/api-protocol-spec.ts +++ b/spec-main/api-protocol-spec.ts @@ -704,7 +704,7 @@ describe('protocol module', () => { }); describe('protocol.registerSchemeAsPrivileged', () => { - // TODO(jeremy): figure out why this times out under ASan + // Running child app under ASan might receive SIGKILL because of OOM. ifit(!process.env.IS_ASAN)('does not crash on exit', async () => { const appPath = path.join(__dirname, 'fixtures', 'api', 'custom-protocol-shutdown.js'); const appProcess = ChildProcess.spawn(process.execPath, ['--enable-logging', appPath]); diff --git a/spec-main/api-web-contents-spec.ts b/spec-main/api-web-contents-spec.ts index ed30aa76c6..058af2649f 100644 --- a/spec-main/api-web-contents-spec.ts +++ b/spec-main/api-web-contents-spec.ts @@ -3,7 +3,6 @@ import { AddressInfo } from 'net'; import * as path from 'path'; import * as fs from 'fs'; import * as http from 'http'; -import * as ChildProcess from 'child_process'; import { BrowserWindow, ipcMain, webContents, session, WebContents, app } from 'electron/main'; import { clipboard } from 'electron/common'; import { emittedOnce } from './events-helpers'; @@ -1268,16 +1267,6 @@ describe('webContents module', () => { }); }); - describe('create()', () => { - it('does not crash on exit', async () => { - const appPath = path.join(fixturesPath, 'api', 'leak-exit-webcontents.js'); - const electronPath = process.execPath; - const appProcess = ChildProcess.spawn(electronPath, [appPath]); - const [code] = await emittedOnce(appProcess, 'close'); - expect(code).to.equal(0); - }); - }); - const crashPrefs = [ { nodeIntegration: true @@ -2016,13 +2005,6 @@ describe('webContents module', () => { }); contents.loadURL('about:blank').then(() => contents.forcefullyCrashRenderer()); }); - - it('does not crash main process when quiting in it', async () => { - const appPath = path.join(mainFixturesPath, 'apps', 'quit', 'main.js'); - const appProcess = ChildProcess.spawn(process.execPath, [appPath]); - const [code] = await emittedOnce(appProcess, 'close'); - expect(code).to.equal(0); - }); }); it('emits a cancelable event before creating a child webcontents', async () => { diff --git a/spec-main/api-web-contents-view-spec.ts b/spec-main/api-web-contents-view-spec.ts index 4388dc2678..b8b7b26030 100644 --- a/spec-main/api-web-contents-view-spec.ts +++ b/spec-main/api-web-contents-view-spec.ts @@ -1,7 +1,3 @@ -import { expect } from 'chai'; -import * as ChildProcess from 'child_process'; -import * as path from 'path'; -import { emittedOnce } from './events-helpers'; import { closeWindow } from './window-helpers'; import { BaseWindow, WebContentsView } from 'electron/main'; @@ -15,22 +11,6 @@ describe('WebContentsView', () => { w.setContentView(new WebContentsView({})); }); - describe('new WebContentsView()', () => { - it('does not crash on exit', async () => { - const appPath = path.join(__dirname, 'fixtures', 'api', 'leak-exit-webcontentsview.js'); - const electronPath = process.execPath; - const appProcess = ChildProcess.spawn(electronPath, ['--enable-logging', appPath]); - let output = ''; - appProcess.stdout.on('data', data => { output += data; }); - appProcess.stderr.on('data', data => { output += data; }); - const [code] = await emittedOnce(appProcess, 'exit'); - if (code !== 0) { - console.log(code, output); - } - expect(code).to.equal(0); - }); - }); - function triggerGCByAllocation () { const arr = []; for (let i = 0; i < 1000000; i++) { diff --git a/spec-main/chromium-spec.ts b/spec-main/chromium-spec.ts index d753932064..c019114785 100644 --- a/spec-main/chromium-spec.ts +++ b/spec-main/chromium-spec.ts @@ -18,8 +18,6 @@ const features = process._linkedBinding('electron_common_features'); const fixturesPath = path.resolve(__dirname, '..', 'spec', 'fixtures'); -const isAsan = process.env.IS_ASAN; - describe('reporting api', () => { // TODO(nornagon): this started failing a lot on CI. Figure out why and fix // it. @@ -298,7 +296,8 @@ describe('web security', () => { }); }); -describe('command line switches', () => { +// Running child app under ASan might receive SIGKILL because of OOM. +ifdescribe(!process.env.IS_ASAN)('command line switches', () => { let appProcess: ChildProcess.ChildProcessWithoutNullStreams | undefined; afterEach(() => { if (appProcess && !appProcess.killed) { @@ -343,8 +342,7 @@ describe('command line switches', () => { ifit(process.platform === 'linux')('should not change LC_ALL when --lang is not set', async () => testLocale('', lcAll, true)); }); - // TODO(nornagon): figure out why these tests fail under ASan. - ifdescribe(!isAsan)('--remote-debugging-pipe switch', () => { + describe('--remote-debugging-pipe switch', () => { it('should expose CDP via pipe', async () => { const electronPath = process.execPath; appProcess = ChildProcess.spawn(electronPath, ['--remote-debugging-pipe'], { @@ -386,8 +384,7 @@ describe('command line switches', () => { }); }); - // TODO(nornagon): figure out why these tests fail under ASan. - ifdescribe(!isAsan)('--remote-debugging-port switch', () => { + describe('--remote-debugging-port switch', () => { it('should display the discovery page', (done) => { const electronPath = process.execPath; let output = ''; diff --git a/spec-main/crash-spec.ts b/spec-main/crash-spec.ts index eb9718dac5..4457e9bcb8 100644 --- a/spec-main/crash-spec.ts +++ b/spec-main/crash-spec.ts @@ -2,6 +2,7 @@ import { expect } from 'chai'; import * as cp from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; +import { ifdescribe } from './spec-helpers'; const fixturePath = path.resolve(__dirname, 'fixtures', 'crash-cases'); @@ -30,7 +31,8 @@ const runFixtureAndEnsureCleanExit = (args: string[]) => { }); }; -describe('crash cases', () => { +// Running child app under ASan might receive SIGKILL because of OOM. +ifdescribe(!process.env.IS_ASAN)('crash cases', () => { afterEach(() => { for (const child of children) { child.kill(); diff --git a/spec-main/fixtures/apps/quit/main.js b/spec-main/fixtures/crash-cases/quit-on-crashed-event/index.js similarity index 100% rename from spec-main/fixtures/apps/quit/main.js rename to spec-main/fixtures/crash-cases/quit-on-crashed-event/index.js diff --git a/spec/fixtures/api/leak-exit-webcontents.js b/spec-main/fixtures/crash-cases/webcontents-create-leak-exit/index.js similarity index 100% rename from spec/fixtures/api/leak-exit-webcontents.js rename to spec-main/fixtures/crash-cases/webcontents-create-leak-exit/index.js diff --git a/spec-main/fixtures/api/leak-exit-webcontentsview.js b/spec-main/fixtures/crash-cases/webcontentsview-create-leak-exit/index.js similarity index 100% rename from spec-main/fixtures/api/leak-exit-webcontentsview.js rename to spec-main/fixtures/crash-cases/webcontentsview-create-leak-exit/index.js diff --git a/spec-main/node-spec.ts b/spec-main/node-spec.ts index 227f9c4003..def9ad1e46 100644 --- a/spec-main/node-spec.ts +++ b/spec-main/node-spec.ts @@ -123,11 +123,12 @@ describe('node feature', () => { }); }); - describe('Node.js cli flags', () => { + // Running child app under ASan might receive SIGKILL because of OOM. + ifdescribe(features.isRunAsNodeEnabled() && !process.env.IS_ASAN)('Node.js cli flags', () => { let child: childProcess.ChildProcessWithoutNullStreams; let exitPromise: Promise; - ifit(features.isRunAsNodeEnabled())('Prohibits crypto-related flags in ELECTRON_RUN_AS_NODE mode', (done) => { + it('Prohibits crypto-related flags in ELECTRON_RUN_AS_NODE mode', (done) => { after(async () => { const [code, signal] = await exitPromise; expect(signal).to.equal(null); @@ -165,7 +166,8 @@ describe('node feature', () => { }); }); - ifdescribe(features.isRunAsNodeEnabled())('inspector', () => { + // Running child app under ASan might receive SIGKILL because of OOM. + ifdescribe(features.isRunAsNodeEnabled() && !process.env.IS_ASAN)('inspector', () => { let child: childProcess.ChildProcessWithoutNullStreams; let exitPromise: Promise; @@ -242,9 +244,8 @@ describe('node feature', () => { } }); - // IPC Electron child process not supported on Windows - // TODO(jeremy): figure out why this times out under ASan - ifit(process.platform !== 'win32' && !process.env.IS_ASAN)('does not crash when quitting with the inspector connected', function (done) { + // IPC Electron child process not supported on Windows. + ifit(process.platform !== 'win32')('does not crash when quitting with the inspector connected', function (done) { child = childProcess.spawn(process.execPath, [path.join(fixtures, 'module', 'delay-exit'), '--inspect=0'], { stdio: ['ipc'] }) as childProcess.ChildProcessWithoutNullStreams; @@ -304,7 +305,8 @@ describe('node feature', () => { }); }); - it('Can find a module using a package.json main field', () => { + // Running child app under ASan might receive SIGKILL because of OOM. + ifit(!process.env.IS_ASAN)('Can find a module using a package.json main field', () => { const result = childProcess.spawnSync(process.execPath, [path.resolve(fixtures, 'api', 'electron-main-module', 'app.asar')]); expect(result.status).to.equal(0); }); diff --git a/spec-main/spellchecker-spec.ts b/spec-main/spellchecker-spec.ts index e4ef5ae81e..31443d6a4a 100644 --- a/spec-main/spellchecker-spec.ts +++ b/spec-main/spellchecker-spec.ts @@ -9,7 +9,9 @@ import { ifit, ifdescribe, delay } from './spec-helpers'; const features = process._linkedBinding('electron_common_features'); const v8Util = process._linkedBinding('electron_common_v8_util'); -ifdescribe(features.isBuiltinSpellCheckerEnabled())('spellchecker', () => { +ifdescribe(features.isBuiltinSpellCheckerEnabled())('spellchecker', function () { + this.timeout(200 * 1000); + let w: BrowserWindow; async function rightClick () { @@ -28,7 +30,7 @@ ifdescribe(features.isBuiltinSpellCheckerEnabled())('spellchecker', () => { // to detect spellchecker is to keep checking with a busy loop. async function rightClickUntil (fn: (params: Electron.ContextMenuParams) => boolean) { const now = Date.now(); - const timeout = 10 * 1000; + const timeout = (process.env.IS_ASAN ? 180 : 10) * 1000; let contextMenuParams = await rightClick(); while (!fn(contextMenuParams) && (Date.now() - now < timeout)) { await delay(100); diff --git a/spec-main/webview-spec.ts b/spec-main/webview-spec.ts index 46b164a9dc..9478457814 100644 --- a/spec-main/webview-spec.ts +++ b/spec-main/webview-spec.ts @@ -3,6 +3,7 @@ import * as url from 'url'; import { BrowserWindow, session, ipcMain, app, WebContents } from 'electron/main'; import { closeAllWindows } from './window-helpers'; import { emittedOnce, emittedUntil } from './events-helpers'; +import { ifdescribe } from './spec-helpers'; import { expect } from 'chai'; async function loadWebView (w: WebContents, attributes: Record, openDevTools: boolean = false): Promise { @@ -25,7 +26,8 @@ async function loadWebView (w: WebContents, attributes: Record, `); } -describe(' tag', function () { +// The render process of webview might receive SIGKILL because of OOM. +ifdescribe(!process.env.IS_ASAN)(' tag', function () { const fixtures = path.join(__dirname, '..', 'spec', 'fixtures'); afterEach(closeAllWindows);