@@ -15,6 +15,30 @@ const honey = new Libhoney({
15
15
const spanId = process . env . CIRCLE_WORKFLOW_ID || uuidv4 ( )
16
16
const circleCiRootEvent = honey . newEvent ( )
17
17
18
+ // Mocha events ('test', 'test end', etc) have no way to wait
19
+ // for async callbacks, so we can't guarantee we have this
20
+ // data ready by the time any of the reporter's events are emitted.
21
+
22
+ // Therefore, we have each honeycomb event await this promise
23
+ // before sending itself.
24
+ let asyncInfo = Promise . all ( [ getNextVersionForPath ( '../../packages' ) , commitInfo ( ) ] )
25
+ . then ( ( [ nextVersion , commitInformation ] ) => {
26
+ const ciInformation = ciProvider . commitParams ( ) || { }
27
+
28
+ return {
29
+ nextVersion,
30
+ branch : commitInformation . branch || ciInformation . branch ,
31
+ commitSha : commitInformation . sha || ciInformation . sha ,
32
+ }
33
+ } )
34
+
35
+ function addAsyncInfoAndSend ( honeycombEvent ) {
36
+ return asyncInfo . then ( ( info ) => {
37
+ honeycombEvent . add ( info )
38
+ honeycombEvent . send ( )
39
+ } )
40
+ }
41
+
18
42
circleCiRootEvent . timestamp = Date . now ( )
19
43
circleCiRootEvent . add ( {
20
44
buildUrl : process . env . CIRCLE_BUILD_URL ,
@@ -29,9 +53,10 @@ circleCiRootEvent.add({
29
53
// so that we can send the root event exactly once and associate all the various
30
54
// system test tasks and build steps into a single span.
31
55
if ( require . main === module ) {
32
- console . log ( circleCiRootEvent . data )
33
- circleCiRootEvent . send ( )
34
- honey . flush ( )
56
+ addAsyncInfoAndSend ( circleCiRootEvent ) . then ( ( ) => {
57
+ console . log ( circleCiRootEvent . data )
58
+ honey . flush ( )
59
+ } )
35
60
}
36
61
37
62
class HoneycombReporter {
@@ -59,8 +84,6 @@ class HoneycombReporter {
59
84
spanId : uuidv4 ( ) ,
60
85
parentId : parent . data . spanId ,
61
86
} )
62
-
63
- this . addAsyncInfo ( suite . honeycombEvent )
64
87
} )
65
88
66
89
runner . on ( 'test' , ( test ) => {
@@ -82,8 +105,6 @@ class HoneycombReporter {
82
105
spanId : uuidv4 ( ) ,
83
106
parentId : test . parent . honeycombEvent . data . spanId ,
84
107
} )
85
-
86
- this . addAsyncInfo ( test . honeycombEvent )
87
108
} )
88
109
89
110
runner . on ( 'test end' , ( test ) => {
@@ -99,7 +120,7 @@ class HoneycombReporter {
99
120
durationMs : Date . now ( ) - test . honeycombEvent . timestamp ,
100
121
} )
101
122
102
- test . honeycombEvent . send ( )
123
+ addAsyncInfoAndSend ( test . honeycombEvent )
103
124
} )
104
125
105
126
runner . on ( 'suite end' , ( suite ) => {
@@ -111,35 +132,18 @@ class HoneycombReporter {
111
132
durationMs : Date . now ( ) - suite . honeycombEvent . timestamp ,
112
133
} )
113
134
114
- suite . honeycombEvent . send ( )
135
+ addAsyncInfoAndSend ( suite . honeycombEvent )
115
136
} )
116
137
}
117
138
118
- // If there is no done callback, then mocha-multi-reporter will kill the process without waiting for our honeycomb post to complete.
139
+ // If there is no done method, then mocha-multi-reporter will kill the process
140
+ // without waiting for our honeycomb posts to complete.
119
141
done ( failures , callback ) {
120
- honey . flush ( ) . then ( callback )
121
- }
122
-
123
- // Because mocha has no way to wait on async functions inside hooks,
124
- // and we need to call various async functions to gather data about
125
- // the testing environment, we create a promise that can be used by each
126
- // honeycomb event to add async data that won't be initialized by the
127
- // time mocha starts running tests.
128
- addAsyncInfo ( honeycombEvent ) {
129
- if ( ! this . asyncInfo ) {
130
- this . asyncInfo = Promise . all ( [ getNextVersionForPath ( '../../packages' ) , commitInfo ( ) ] )
131
- . then ( ( [ nextVersion , commitInformation ] ) => {
132
- const ciInformation = ciProvider . commitParams ( ) || { }
133
-
134
- return {
135
- nextVersion,
136
- branch : commitInformation . branch || ciInformation . branch ,
137
- commitSha : commitInformation . sha || ciInformation . sha ,
138
- }
139
- } )
140
- }
141
-
142
- this . asyncInfo . then ( ( info ) => honeycombEvent . add ( info ) )
142
+ // Await the asyncInfo promise one last time, to ensure all events have
143
+ // added the data and sent themselves before we flush honeycomb's queue and exit.
144
+ asyncInfo
145
+ . then ( ( ) => honey . flush ( ) )
146
+ . then ( callback )
143
147
}
144
148
}
145
149
0 commit comments