@@ -20,9 +20,12 @@ import { ReadableSpan } from '@opentelemetry/tracing';
20
20
import * as http from 'http' ;
21
21
import * as assert from 'assert' ;
22
22
import * as sinon from 'sinon' ;
23
+ import { PassThrough , Stream } from 'stream' ;
24
+ import * as zlib from 'zlib' ;
23
25
import {
24
26
CollectorTraceExporter ,
25
27
CollectorExporterNodeConfigBase ,
28
+ CompressionAlgorithm ,
26
29
} from '../../src/platform/node' ;
27
30
import * as collectorTypes from '../../src/types' ;
28
31
import { MockedResponse } from './nodeHelpers' ;
@@ -33,22 +36,19 @@ import {
33
36
mockedReadableSpan ,
34
37
} from '../helper' ;
35
38
36
- const fakeRequest = {
37
- end : function ( ) { } ,
38
- on : function ( ) { } ,
39
- write : function ( ) { } ,
40
- } ;
39
+ let fakeRequest : PassThrough ;
41
40
42
41
const address = 'localhost:1501' ;
43
42
44
43
describe ( 'CollectorTraceExporter - node with json over http' , ( ) => {
45
44
let collectorExporter : CollectorTraceExporter ;
46
45
let collectorExporterConfig : CollectorExporterNodeConfigBase ;
47
46
let stubRequest : sinon . SinonStub ;
48
- let stubWrite : sinon . SinonStub ;
47
+ let spySetHeader : sinon . SinonSpy ;
49
48
let spans : ReadableSpan [ ] ;
50
49
51
50
afterEach ( ( ) => {
51
+ fakeRequest = new Stream . PassThrough ( ) ;
52
52
sinon . restore ( ) ;
53
53
} ) ;
54
54
@@ -109,7 +109,6 @@ describe('CollectorTraceExporter - node with json over http', () => {
109
109
describe ( 'export' , ( ) => {
110
110
beforeEach ( ( ) => {
111
111
stubRequest = sinon . stub ( http , 'request' ) . returns ( fakeRequest as any ) ;
112
- stubWrite = sinon . stub ( fakeRequest , 'write' ) ;
113
112
collectorExporterConfig = {
114
113
headers : {
115
114
foo : 'bar' ,
@@ -126,7 +125,7 @@ describe('CollectorTraceExporter - node with json over http', () => {
126
125
} ) ;
127
126
128
127
it ( 'should open the connection' , done => {
129
- collectorExporter . export ( spans , ( ) => { } ) ;
128
+ collectorExporter . export ( spans , ( ) => { } ) ;
130
129
131
130
setTimeout ( ( ) => {
132
131
const args = stubRequest . args [ 0 ] ;
@@ -140,7 +139,7 @@ describe('CollectorTraceExporter - node with json over http', () => {
140
139
} ) ;
141
140
142
141
it ( 'should set custom headers' , done => {
143
- collectorExporter . export ( spans , ( ) => { } ) ;
142
+ collectorExporter . export ( spans , ( ) => { } ) ;
144
143
145
144
setTimeout ( ( ) => {
146
145
const args = stubRequest . args [ 0 ] ;
@@ -150,8 +149,19 @@ describe('CollectorTraceExporter - node with json over http', () => {
150
149
} ) ;
151
150
} ) ;
152
151
152
+ it ( 'should not have Content-Encoding header' , done => {
153
+ collectorExporter . export ( spans , ( ) => { } ) ;
154
+
155
+ setTimeout ( ( ) => {
156
+ const args = stubRequest . args [ 0 ] ;
157
+ const options = args [ 0 ] ;
158
+ assert . strictEqual ( options . headers [ 'Content-Encoding' ] , undefined ) ;
159
+ done ( ) ;
160
+ } ) ;
161
+ } ) ;
162
+
153
163
it ( 'should have keep alive and keepAliveMsecs option set' , done => {
154
- collectorExporter . export ( spans , ( ) => { } ) ;
164
+ collectorExporter . export ( spans , ( ) => { } ) ;
155
165
156
166
setTimeout ( ( ) => {
157
167
const args = stubRequest . args [ 0 ] ;
@@ -164,8 +174,8 @@ describe('CollectorTraceExporter - node with json over http', () => {
164
174
} ) ;
165
175
166
176
it ( 'different http export requests should use the same agent' , done => {
167
- collectorExporter . export ( spans , ( ) => { } ) ;
168
- collectorExporter . export ( spans , ( ) => { } ) ;
177
+ collectorExporter . export ( spans , ( ) => { } ) ;
178
+ collectorExporter . export ( spans , ( ) => { } ) ;
169
179
170
180
setTimeout ( ( ) => {
171
181
const [ firstExportAgent , secondExportAgent ] = stubRequest . args . map (
@@ -177,12 +187,13 @@ describe('CollectorTraceExporter - node with json over http', () => {
177
187
} ) ;
178
188
179
189
it ( 'should successfully send the spans' , done => {
180
- collectorExporter . export ( spans , ( ) => { } ) ;
190
+ let buff = Buffer . from ( '' ) ;
191
+
192
+ fakeRequest . on ( 'end' , ( ) => {
193
+ const responseBody = buff . toString ( ) ;
181
194
182
- setTimeout ( ( ) => {
183
- const writeArgs = stubWrite . args [ 0 ] ;
184
195
const json = JSON . parse (
185
- writeArgs [ 0 ]
196
+ responseBody
186
197
) as collectorTypes . opentelemetryProto . collector . trace . v1 . ExportTraceServiceRequest ;
187
198
const span1 =
188
199
json . resourceSpans [ 0 ] . instrumentationLibrarySpans [ 0 ] . spans [ 0 ] ;
@@ -195,6 +206,12 @@ describe('CollectorTraceExporter - node with json over http', () => {
195
206
196
207
done ( ) ;
197
208
} ) ;
209
+
210
+ fakeRequest . on ( 'data' , chunk => {
211
+ buff = Buffer . concat ( [ buff , chunk ] ) ;
212
+ } ) ;
213
+
214
+ collectorExporter . export ( spans , ( ) => { } ) ;
198
215
} ) ;
199
216
200
217
it ( 'should log the successful message' , done => {
@@ -242,6 +259,58 @@ describe('CollectorTraceExporter - node with json over http', () => {
242
259
} ) ;
243
260
} ) ;
244
261
} ) ;
262
+
263
+ describe ( 'export - with compression' , ( ) => {
264
+ beforeEach ( ( ) => {
265
+ stubRequest = sinon . stub ( http , 'request' ) . returns ( fakeRequest as any ) ;
266
+ spySetHeader = sinon . spy ( ) ;
267
+ ( fakeRequest as any ) . setHeader = spySetHeader ;
268
+ collectorExporterConfig = {
269
+ headers : {
270
+ foo : 'bar' ,
271
+ } ,
272
+ hostname : 'foo' ,
273
+ attributes : { } ,
274
+ url : 'http://foo.bar.com' ,
275
+ keepAlive : true ,
276
+ compression : CompressionAlgorithm . GZIP ,
277
+ httpAgentOptions : { keepAliveMsecs : 2000 } ,
278
+ } ;
279
+ collectorExporter = new CollectorTraceExporter ( collectorExporterConfig ) ;
280
+ spans = [ ] ;
281
+ spans . push ( Object . assign ( { } , mockedReadableSpan ) ) ;
282
+ } ) ;
283
+
284
+ it ( 'should successfully send the spans' , done => {
285
+ collectorExporter . export ( spans , ( ) => { } ) ;
286
+ let buff = Buffer . from ( '' ) ;
287
+
288
+ fakeRequest . on ( 'end' , ( ) => {
289
+ const responseBody = zlib . gunzipSync ( buff ) . toString ( ) ;
290
+
291
+ const json = JSON . parse (
292
+ responseBody
293
+ ) as collectorTypes . opentelemetryProto . collector . trace . v1 . ExportTraceServiceRequest ;
294
+ const span1 =
295
+ json . resourceSpans [ 0 ] . instrumentationLibrarySpans [ 0 ] . spans [ 0 ] ;
296
+ assert . ok ( typeof span1 !== 'undefined' , "span doesn't exist" ) ;
297
+ if ( span1 ) {
298
+ ensureSpanIsCorrect ( span1 ) ;
299
+ }
300
+
301
+ ensureExportTraceServiceRequestIsSet ( json ) ;
302
+ assert . ok ( spySetHeader . calledWith ( 'Content-Encoding' , 'gzip' ) ) ;
303
+
304
+ done ( ) ;
305
+ } ) ;
306
+
307
+ fakeRequest . on ( 'data' , chunk => {
308
+ buff = Buffer . concat ( [ buff , chunk ] ) ;
309
+ } ) ;
310
+ } ) ;
311
+
312
+ } ) ;
313
+
245
314
describe ( 'CollectorTraceExporter - node (getDefaultUrl)' , ( ) => {
246
315
it ( 'should default to localhost' , done => {
247
316
const collectorExporter = new CollectorTraceExporter ( ) ;
0 commit comments