Skip to content

Commit

Permalink
add CRI connection timeout; rerun smokehouse on these timeouts
Browse files Browse the repository at this point in the history
  • Loading branch information
brendankenny committed Nov 8, 2016
1 parent 0243440 commit 4cd87d0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 11 deletions.
8 changes: 8 additions & 0 deletions lighthouse-cli/bin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
const _SIGINT = 'SIGINT';
const _ERROR_EXIT_CODE = 130;
const _RUNTIME_ERROR_CODE = 1;
const _PROTOCOL_TIMEOUT_EXIT_CODE = 67;

interface LightHouseError extends Error {
code?: string
Expand Down Expand Up @@ -255,9 +256,16 @@ function showRuntimeError(err: LightHouseError) {
process.exit(_RUNTIME_ERROR_CODE);
}

function showProtocolTimeoutError() {
console.error('Debugger protocol timed out while connecting to Chrome.');
process.exit(_PROTOCOL_TIMEOUT_EXIT_CODE);
}

function handleError(err: LightHouseError) {
if (err.code === 'ECONNREFUSED') {
showConnectionError();
} else if (err.code === 'CRI_TIMEOUT') {
showProtocolTimeoutError();
} else {
showRuntimeError(err);
}
Expand Down
51 changes: 41 additions & 10 deletions lighthouse-cli/test/smokehouse/smokehouse.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@
'use strict';

const path = require('path');
const execSync = require('child_process').execSync;
const spawnSync = require('child_process').spawnSync;
const yargs = require('yargs');

const DEFAULT_CONFIG_PATH = 'pwa-config';
const DEFAULT_EXPECTATIONS_PATH = 'pwa-expectations';

const PROTOCOL_TIMEOUT_EXIT_CODE = 67;
const RETRIES = 3;

const GREEN = '\x1B[32m';
const RED = '\x1B[31m';
const RESET = '\x1B[0m';
Expand Down Expand Up @@ -73,18 +76,46 @@ function resolveLocalOrCwd(payloadPath) {
* @return {!LighthouseResults}
*/
function runLighthouse(url, configPath) {
// Assume if currently running in Node v4 that child process will as well, so
// run Lighthouse with --harmony flag.
const harmony = /v4/.test(process.version) ? '--harmony' : '';
const command = `node ${harmony} lighthouse-cli/index.js ${url}`;
const options = [
const command = 'node';
const args = [
'lighthouse-cli/index.js',
url,
`--config-path=${configPath}`,
'--output=json',
'--quiet'
].join(' ');
'--quiet',
'--port=0'
];

// Assume if currently running in Node v4 that child process will as well, so
// run Lighthouse with --harmony flag.
if (/v4/.test(process.version)) {
args.unshift('--harmony');
}

// Lighthouse sometimes times out waiting to for a connection to Chrome in CI.
// Watch for this error and retry relaunching Chrome and running Lighthouse up
// to RETRIES times. See https://github.com/GoogleChrome/lighthouse/issues/833
let runResults;
let runCount = 0;
do {
if (runCount > 0) {
console.log(' Lighthouse error: timed out waiting for debugger connection. Retrying...');
}

runCount++;
runResults = spawnSync(command, args, {encoding: 'utf8', stdio: ['pipe', 'pipe', 'inherit']});
} while (runResults.status === PROTOCOL_TIMEOUT_EXIT_CODE && runCount <= RETRIES);

if (runResults.status === PROTOCOL_TIMEOUT_EXIT_CODE) {
console.error(`Lighthouse debugger connection timed out ${RETRIES} times. Giving up.`);
process.exit(1);
} else if (runResults.status !== 0) {
console.error(`Lighthouse run failed with exit code ${runResults.status}. stderr to follow:`);
console.error(runResults.stderr);
process.exit(runResults.status);
}

const rawResults = execSync(command + ' ' + options, {encoding: 'utf8'});
return JSON.parse(rawResults);
return JSON.parse(runResults.stdout);
}

/**
Expand Down
15 changes: 14 additions & 1 deletion lighthouse-core/gather/connections/cri.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
const Connection = require('./connection.js');
const WebSocket = require('ws');
const http = require('http');
const log = require('../../lib/log.js');

const hostname = 'localhost';
const CONNECT_TIMEOUT = 10000;

class CriConnection extends Connection {
/**
Expand Down Expand Up @@ -58,7 +61,7 @@ class CriConnection extends Connection {
*/
_runJsonCommand(command) {
return new Promise((resolve, reject) => {
http.get({
const request = http.get({
hostname: hostname,
port: this.port,
path: '/json/' + command
Expand All @@ -75,6 +78,16 @@ class CriConnection extends Connection {
reject(new Error(`Unable to fetch webSocketDebuggerUrl, status: ${response.statusCode}`));
});
});

request.setTimeout(CONNECT_TIMEOUT, _ => {
request.abort();

const err = new Error('Timeout waiting for initial Debugger Protocol connection.');
err.code = 'CRI_TIMEOUT';

log.error('CriConnection', err.message);
reject(err);
});
});
}

Expand Down

0 comments on commit 4cd87d0

Please sign in to comment.