Browse Source

test: disable some tests under ASan which might receive SIGKILL because of OOM (#28156)

* test: running child app under ASan might receive SIGKILL

* test: renderer process of webview might receive SIGKILL under ASan

* test: increase timeout for asan build
Cheng Zhao 4 years ago
parent
commit
80f89a3472

+ 18 - 19
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');

+ 1 - 1
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]);

+ 0 - 18
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 () => {

+ 0 - 20
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++) {

+ 4 - 7
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 = '';

+ 3 - 1
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();

+ 0 - 0
spec-main/fixtures/apps/quit/main.js → spec-main/fixtures/crash-cases/quit-on-crashed-event/index.js


+ 0 - 0
spec/fixtures/api/leak-exit-webcontents.js → spec-main/fixtures/crash-cases/webcontents-create-leak-exit/index.js


+ 0 - 0
spec-main/fixtures/api/leak-exit-webcontentsview.js → spec-main/fixtures/crash-cases/webcontentsview-create-leak-exit/index.js


+ 9 - 7
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<any[]>;
 
-    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<any[]>;
 
@@ -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);
   });

+ 4 - 2
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);

+ 3 - 1
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<string, string>, openDevTools: boolean = false): Promise<void> {
@@ -25,7 +26,8 @@ async function loadWebView (w: WebContents, attributes: Record<string, string>,
   `);
 }
 
-describe('<webview> tag', function () {
+// The render process of webview might receive SIGKILL because of OOM.
+ifdescribe(!process.env.IS_ASAN)('<webview> tag', function () {
   const fixtures = path.join(__dirname, '..', 'spec', 'fixtures');
 
   afterEach(closeAllWindows);