11'use strict' ;
22
3+ // Testcases for situations involving fatal errors, like Javascript heap OOM
4+
35require ( '../common' ) ;
46const assert = require ( 'assert' ) ;
5- // Testcase to produce report on fatal error (javascript heap OOM)
7+ const fs = require ( 'fs' ) ;
8+ const helper = require ( '../common/report.js' ) ;
9+ const spawnSync = require ( 'child_process' ) . spawnSync ;
10+ const tmpdir = require ( '../common/tmpdir' ) ;
11+
612if ( process . argv [ 2 ] === 'child' ) {
713
814 const list = [ ] ;
@@ -16,30 +22,100 @@ if (process.argv[2] === 'child') {
1622 this . id = 128 ;
1723 this . account = 98454324 ;
1824 }
19- } else {
20- const helper = require ( '../common/report.js' ) ;
21- const tmpdir = require ( '../common/tmpdir' ) ;
25+ }
26+
27+ // Common args that will cause an out-of-memory error for child process.
28+ const ARGS = [
29+ '--max-old-space-size=20' ,
30+ __filename ,
31+ 'child'
32+ ] ;
33+
34+ {
35+ // Verify that --report-on-fatalerror is respected when set.
2236 tmpdir . refresh ( ) ;
23- const spawnSync = require ( 'child_process' ) . spawnSync ;
24- let args = [ '--report-on-fatalerror' ,
25- '--max-old-space-size=20' ,
26- __filename ,
27- 'child' ] ;
37+ const args = [ '--report-on-fatalerror' , ...ARGS ] ;
38+ const child = spawnSync ( process . execPath , args , { cwd : tmpdir . path } ) ;
39+ assert . notStrictEqual ( child . status , 0 , 'Process exited unexpectedly' ) ;
2840
29- let child = spawnSync ( process . execPath , args , { cwd : tmpdir . path } ) ;
41+ const reports = helper . findReports ( child . pid , tmpdir . path ) ;
42+ assert . strictEqual ( reports . length , 1 ) ;
3043
44+ const report = reports [ 0 ] ;
45+ helper . validate ( report ) ;
46+
47+ // Errors occur in a context where env is not available, so thread ID is
48+ // unknown. Assert this, to verify that the underlying env-less situation is
49+ // actually reached.
50+ assert . strictEqual ( require ( report ) . header . threadId , null ) ;
51+ }
52+
53+ {
54+ // Verify that --report-on-fatalerror is respected when not set.
55+ const args = ARGS ;
56+ const child = spawnSync ( process . execPath , args , { cwd : tmpdir . path } ) ;
57+ assert . notStrictEqual ( child . status , 0 , 'Process exited unexpectedly' ) ;
58+ const reports = helper . findReports ( child . pid , tmpdir . path ) ;
59+ assert . strictEqual ( reports . length , 0 ) ;
60+ }
61+
62+ {
63+ // Verify that --report-directory is respected when set.
64+ // Verify that --report-compact is respected when not set.
65+ tmpdir . refresh ( ) ;
66+ const dir = '--report-directory=' + tmpdir . path ;
67+ const args = [ '--report-on-fatalerror' , dir , ...ARGS ] ;
68+ const child = spawnSync ( process . execPath , args , { } ) ;
3169 assert . notStrictEqual ( child . status , 0 , 'Process exited unexpectedly' ) ;
32- let reports = helper . findReports ( child . pid , tmpdir . path ) ;
70+
71+ const reports = helper . findReports ( child . pid , tmpdir . path ) ;
72+ assert . strictEqual ( reports . length , 1 ) ;
73+
74+ const report = reports [ 0 ] ;
75+ helper . validate ( report ) ;
76+ assert . strictEqual ( require ( report ) . header . threadId , null ) ;
77+ const lines = fs . readFileSync ( report , 'utf8' ) . split ( '\n' ) . length - 1 ;
78+ assert ( lines > 10 ) ;
79+ }
80+
81+ {
82+ // Verify that --report-compact is respected when set.
83+ tmpdir . refresh ( ) ;
84+ const args = [ '--report-on-fatalerror' , '--report-compact' , ...ARGS ] ;
85+ const child = spawnSync ( process . execPath , args , { cwd : tmpdir . path } ) ;
86+ assert . notStrictEqual ( child . status , 0 , 'Process exited unexpectedly' ) ;
87+
88+ const reports = helper . findReports ( child . pid , tmpdir . path ) ;
3389 assert . strictEqual ( reports . length , 1 ) ;
90+
3491 const report = reports [ 0 ] ;
3592 helper . validate ( report ) ;
36- // Verify that reports are not created on fatal error by default.
37- args = [ '--max-old-space-size=20' ,
38- __filename ,
39- 'child' ] ;
93+ assert . strictEqual ( require ( report ) . header . threadId , null ) ;
94+ // Subtract 1 because "xx\n".split("\n") => [ 'xx', '' ].
95+ const lines = fs . readFileSync ( report , 'utf8' ) . split ( '\n' ) . length - 1 ;
96+ assert . strictEqual ( lines , 1 ) ;
97+ }
4098
41- child = spawnSync ( process . execPath , args , { cwd : tmpdir . path } ) ;
99+ {
100+ // Verify that --report-compact is respected when set.
101+ // Verify that --report-filename is respected when set.
102+ tmpdir . refresh ( ) ;
103+ const args = [
104+ '--report-on-fatalerror' ,
105+ '--report-compact' ,
106+ '--report-filename=stderr' ,
107+ ...ARGS
108+ ] ;
109+ const child = spawnSync ( process . execPath , args , { encoding : 'utf8' } ) ;
42110 assert . notStrictEqual ( child . status , 0 , 'Process exited unexpectedly' ) ;
43- reports = helper . findReports ( child . pid , tmpdir . path ) ;
111+
112+ const reports = helper . findReports ( child . pid , tmpdir . path ) ;
44113 assert . strictEqual ( reports . length , 0 ) ;
114+
115+ const lines = child . stderr . split ( '\n' ) ;
116+ // Skip over unavoidable free-form output from V8.
117+ const report = lines [ 1 ] ;
118+ const json = JSON . parse ( report ) ;
119+
120+ assert . strictEqual ( json . header . threadId , null ) ;
45121}
0 commit comments