@@ -20,6 +20,69 @@ const path = require('path');
2020const { spawn } = require ( 'child-process-promise' ) ;
2121const { writeFileSync } = require ( 'fs' ) ;
2222
23+ /**
24+ * Creates and returns a "timestamp" string for the elapsed time.
25+ *
26+ * The given timestamp is taken as an offset from the first time that this
27+ * function is invoked. This allows log messages to start at "time 0" and make
28+ * it easy for humans to calculate the elapsed time.
29+ *
30+ * @returns The timestamp string with which to prefix log lines, created from
31+ * the elapsed time since this function's first invocation.
32+ */
33+ function elapsedTimeStr ( ) {
34+ const milliseconds = getElapsedMilliseconds ( ) ;
35+ const minutes = Math . floor ( milliseconds / ( 1000 * 60 ) ) ;
36+ const seconds = ( milliseconds - minutes * 1000 * 60 ) / 1000 ;
37+ return (
38+ ( minutes < 10 ? '0' : '' ) +
39+ minutes +
40+ ':' +
41+ ( seconds < 10 ? '0' : '' ) +
42+ seconds . toFixed ( 3 )
43+ ) ;
44+ }
45+
46+ /**
47+ * The "start time", which is set to a non-null value upon the first invocation
48+ * of `getElapsedMilliseconds()`. All subsequent invocations calculate the
49+ * elapsed time using this value.
50+ */
51+ let elapsedMillisecondsStartTime = null ;
52+
53+ /**
54+ * Returns the number of nanoseconds that have elapsed since this function's
55+ * first invocation. Returns 0 on its first invocation.
56+ */
57+ function getElapsedMilliseconds ( ) {
58+ const currentTimeMilliseconds = getCurrentMonotonicTimeMilliseconds ( ) ;
59+ if ( elapsedMillisecondsStartTime === null ) {
60+ elapsedMillisecondsStartTime = currentTimeMilliseconds ;
61+ return 0 ;
62+ }
63+ return currentTimeMilliseconds - elapsedMillisecondsStartTime ;
64+ }
65+
66+ /**
67+ * Returns the current time, in milliseconds, from a monotonic clock.
68+ */
69+ function getCurrentMonotonicTimeMilliseconds ( ) {
70+ const currentTime = process . hrtime ( ) ;
71+ return currentTime [ 0 ] * 1000 + currentTime [ 1 ] / 1_000_000 ;
72+ }
73+
74+ function debugLog ( ...args ) {
75+ // eslint-disable-next-line no-console
76+ console . log ( __filename , elapsedTimeStr ( ) , ...args ) ;
77+ }
78+
79+ function errorLog ( ...args ) {
80+ // eslint-disable-next-line no-console
81+ console . error ( __filename , elapsedTimeStr ( ) , ...args ) ;
82+ }
83+
84+ debugLog ( `command-line arguments: ${ process . argv . join ( ' ' ) } ` ) ;
85+
2386const LOGDIR = process . env . CI ? process . env . HOME : '/tmp' ;
2487// Maps the packages where we should not run `test:all` and instead isolate the cross-browser tests.
2588// TODO(dwyfrequency): Update object with `storage` and `firestore` packages.
@@ -69,7 +132,10 @@ const argv = yargs.options({
69132 }
70133 }
71134 }
72- const testProcess = spawn ( 'yarn' , [ '--cwd' , dir , scriptName ] ) ;
135+
136+ const yarnArgs = [ '--cwd' , dir , scriptName ] ;
137+ debugLog ( `spawning '${ name } ' process: yarn ${ yarnArgs . join ( ' ' ) } ` ) ;
138+ const testProcess = spawn ( 'yarn' , yarnArgs ) ;
73139
74140 testProcess . childProcess . stdout . on ( 'data' , data => {
75141 stdout += data . toString ( ) ;
@@ -79,13 +145,20 @@ const argv = yargs.options({
79145 } ) ;
80146
81147 await testProcess ;
82- console . log ( 'Success: ' + name ) ;
148+ debugLog (
149+ `'${ name } ' process completed successfully: yarn ${ yarnArgs . join ( ' ' ) } `
150+ ) ;
83151 writeLogs ( 'Success' , name , stdout + '\n' + stderr ) ;
84152 } catch ( e ) {
85- console . error ( 'Failure: ' + name ) ;
153+ errorLog ( `${ name } process FAILED` ) ;
154+ errorLog ( `${ name } process ==== STDOUT BEGIN ====` ) ;
86155 console . log ( stdout ) ;
156+ errorLog ( `${ name } process ==== STDOUT END ====` ) ;
157+ errorLog ( `${ name } process ==== STDERR BEGIN ====` ) ;
87158 console . error ( stderr ) ;
159+ errorLog ( `${ name } process ==== STDERR END ====` ) ;
88160 writeLogs ( 'Failure' , name , stdout + '\n' + stderr ) ;
89- process . exit ( 1 ) ;
161+ errorLog ( 'Completing with failure exit code 76' ) ;
162+ process . exit ( 76 ) ;
90163 }
91164} ) ( ) ;
0 commit comments