From c46c689b91882d5c137c607b9a0b3585a0de1e1f Mon Sep 17 00:00:00 2001 From: Michael Giambalvo Date: Tue, 27 Dec 2016 12:51:22 -0800 Subject: [PATCH 1/2] fix(ci): Show progress when running tests. CircleCI will timeout the test if it doesn't see any output for 10 minutes. This prints out a '.' with every bit of stdio input to show that we're making progress. --- scripts/test/test_util.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/test/test_util.js b/scripts/test/test_util.js index 93bd39d05..ca2eb324b 100644 --- a/scripts/test/test_util.js +++ b/scripts/test/test_util.js @@ -79,14 +79,17 @@ var CommandlineTest = function(command) { test_process = child_process.spawn(args[0], args.slice(1)); test_process.stdout.on('data', function(data) { + process.stdout.write('.'); output += data; }); test_process.stderr.on('data', function(data) { + process.stdout.write('.'); output += data; }); } else { - test_process = child_process.spawn(args[0], args.slice(1), {stdio: 'inherit'}); + test_process = child_process + .spawn(args[0], args.slice(1), {stdio: 'inherit', stderr: 'inherit'}); } test_process.on('error', function(err) { @@ -209,10 +212,10 @@ exports.Executor = function() { if (i < tests.length) { console.log('running: ' + tests[i].command_); tests[i].run().then(function() { - console.log('>>> \033[1;32mpass\033[0m'); + console.log('\n>>> \033[1;32mpass\033[0m'); }, function(err) { failed = true; - console.log('>>> \033[1;31mfail: ' + err.toString() + '\033[0m'); + console.log('\n>>> \033[1;31mfail: ' + err.toString() + '\033[0m'); }).fin(function() { runTests(i + 1); }).done(); From 8beb9ec910a569c76c6af851fdbdac799e2ae18e Mon Sep 17 00:00:00 2001 From: Michael Giambalvo Date: Tue, 27 Dec 2016 15:28:46 -0800 Subject: [PATCH 2/2] fix(ci): Save stdout and stderr from test runs on CircleCI. Helps with debugging on CircleCI. If the test times out or is killed, we'll be able to see what it was doing. Also removes the unused alwaysEnableStdio() method. --- scripts/test.js | 8 ++++++- scripts/test/test_util.js | 46 +++++++++++++++++++-------------------- 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/scripts/test.js b/scripts/test.js index f544eb445..47c91c8cf 100755 --- a/scripts/test.js +++ b/scripts/test.js @@ -1,4 +1,5 @@ #!/usr/bin/env node +var path = require('path'); var Executor = require('./test/test_util').Executor; @@ -144,4 +145,9 @@ executor.addCommandlineTest('node built/cli.js spec/angular2TimeoutConf.js') {message: 'Timed out waiting for asynchronous Angular tasks to finish'}, ]); -executor.execute(); +// If we're running on CircleCI, save stdout and stderr from the test run to a log file. +if (process.env['CIRCLE_ARTIFACTS']) { + executor.execute(path.join(process.env['CIRCLE_ARTIFACTS'], 'test_log.txt')); +} else { + executor.execute(); +} diff --git a/scripts/test/test_util.js b/scripts/test/test_util.js index ca2eb324b..a608c1e5f 100644 --- a/scripts/test/test_util.js +++ b/scripts/test/test_util.js @@ -8,16 +8,9 @@ var CommandlineTest = function(command) { var self = this; this.command_ = command; this.expectedExitCode_ = 0; - this.stdioOnlyOnFailures_ = true; this.expectedErrors_ = []; this.assertExitCodeOnly_ = false; - - // If stdioOnlyOnFailures_ is true, do not stream stdio unless test failed. - // This is to prevent tests with expected failures from polluting the output. - this.alwaysEnableStdio = function() { - self.stdioOnlyOnFailures_ = false; - return self; - }; + this.testLogStream = undefined; // Only assert the exit code and not failures. // This must be true if the command you're running does not support @@ -27,6 +20,10 @@ var CommandlineTest = function(command) { return self; }; + this.setTestLogFile = function(filename) { + self.testLogStream = fs.createWriteStream(filename, {flags: 'a'}); + }; + // Set the expected exit code for the test command. this.expectExitCode = function(exitCode) { self.expectedExitCode_ = exitCode; @@ -75,22 +72,18 @@ var CommandlineTest = function(command) { var test_process; - if (self.stdioOnlyOnFailures_) { - test_process = child_process.spawn(args[0], args.slice(1)); + test_process = child_process.spawn(args[0], args.slice(1)); - test_process.stdout.on('data', function(data) { - process.stdout.write('.'); - output += data; - }); + var processData = function(data) { + process.stdout.write('.'); + output += data; + if (self.testLogStream) { + self.testLogStream.write(data); + } + }; - test_process.stderr.on('data', function(data) { - process.stdout.write('.'); - output += data; - }); - } else { - test_process = child_process - .spawn(args[0], args.slice(1), {stdio: 'inherit', stderr: 'inherit'}); - } + test_process.stdout.on('data', processData); + test_process.stderr.on('data', processData); test_process.on('error', function(err) { reject(err); @@ -105,6 +98,10 @@ var CommandlineTest = function(command) { ', actual: ' + exitCode); } + if (self.testLogStream) { + self.testLogStream.end(); + } + // Skip the rest if we are only verify exit code. // Note: we're expecting a file populated by '--resultJsonOutputFile' after // this point. @@ -205,12 +202,15 @@ exports.Executor = function() { return test; }; - this.execute = function() { + this.execute = function(logFile) { var failed = false; (function runTests(i) { if (i < tests.length) { console.log('running: ' + tests[i].command_); + if (logFile) { + tests[i].setTestLogFile(logFile); + } tests[i].run().then(function() { console.log('\n>>> \033[1;32mpass\033[0m'); }, function(err) {