@@ -51,7 +51,10 @@ import {
51
51
defaultTextMapGetter ,
52
52
} from '@opentelemetry/api' ;
53
53
import { AWSXRayPropagator } from '@opentelemetry/propagator-aws-xray' ;
54
- import { W3CTraceContextPropagator } from '@opentelemetry/core' ;
54
+ import {
55
+ hrTimeToMilliseconds ,
56
+ W3CTraceContextPropagator ,
57
+ } from '@opentelemetry/core' ;
55
58
import { AWSXRayLambdaPropagator } from '@opentelemetry/propagator-aws-xray-lambda' ;
56
59
57
60
const memoryExporter = new InMemorySpanExporter ( ) ;
@@ -266,10 +269,15 @@ describe('lambda handler', () => {
266
269
} ) ;
267
270
268
271
it ( 'should record coldstart' , async ( ) => {
269
- initializeHandler ( 'lambda-test/sync.handler' ) ;
272
+ const time0 = Date . now ( ) ;
273
+ initializeHandler ( 'lambda-test/sync.handler' , { lambdaStartTime : time0 } ) ;
274
+
275
+ // Simulate initialization time
276
+ await new Promise ( resolve => setTimeout ( resolve , 10 ) ) ;
270
277
271
278
const handlerModule = lambdaRequire ( 'lambda-test/sync' ) ;
272
279
280
+ const time1 = Date . now ( ) ;
273
281
const result1 = await new Promise ( ( resolve , reject ) => {
274
282
handlerModule . handler ( 'arg' , ctx , ( err : Error , res : any ) => {
275
283
if ( err ) {
@@ -280,6 +288,7 @@ describe('lambda handler', () => {
280
288
} ) ;
281
289
} ) ;
282
290
291
+ const time2 = Date . now ( ) ;
283
292
const result2 = await new Promise ( ( resolve , reject ) => {
284
293
handlerModule . handler ( 'arg' , ctx , ( err : Error , res : any ) => {
285
294
if ( err ) {
@@ -298,18 +307,28 @@ describe('lambda handler', () => {
298
307
assertSpanSuccess ( span1 ) ;
299
308
assert . strictEqual ( span1 . parentSpanId , undefined ) ;
300
309
assert . strictEqual ( span1 . attributes [ SEMATTRS_FAAS_COLDSTART ] , true ) ;
310
+ // Since it is coldstart, invocation span start time should be equal to lambda start time
311
+ assert . strictEqual ( hrTimeToMilliseconds ( span1 . startTime ) , time0 ) ;
312
+ // Since it is coldstart, invocation span start time should be before actual handler call time
313
+ assert . ok ( hrTimeToMilliseconds ( span1 . startTime ) < time1 ) ;
301
314
302
315
assert . strictEqual ( result2 , 'ok' ) ;
303
316
assertSpanSuccess ( span2 ) ;
304
317
assert . strictEqual ( span2 . parentSpanId , undefined ) ;
305
318
assert . strictEqual ( span2 . attributes [ SEMATTRS_FAAS_COLDSTART ] , false ) ;
319
+ // Since it is warm invocation, invocation span start time should be after than lambda start time
320
+ assert . ok ( hrTimeToMilliseconds ( span2 . startTime ) > time0 ) ;
321
+ // Since it is warm invocation, invocation span start time should be equal or after than handler call time
322
+ assert . ok ( hrTimeToMilliseconds ( span2 . startTime ) >= time2 ) ;
306
323
} ) ;
307
324
308
325
it ( 'should record coldstart with provisioned concurrency' , async ( ) => {
309
326
process . env . AWS_LAMBDA_INITIALIZATION_TYPE = 'provisioned-concurrency' ;
310
327
311
- initializeHandler ( 'lambda-test/sync.handler' ) ;
328
+ const time0 = Date . now ( ) - 1 ;
329
+ initializeHandler ( 'lambda-test/sync.handler' , { lambdaStartTime : time0 } ) ;
312
330
331
+ const time1 = Date . now ( ) ;
313
332
const result = await new Promise ( ( resolve , reject ) => {
314
333
lambdaRequire ( 'lambda-test/sync' ) . handler (
315
334
'arg' ,
@@ -323,20 +342,26 @@ describe('lambda handler', () => {
323
342
}
324
343
) ;
325
344
} ) ;
345
+
326
346
assert . strictEqual ( result , 'ok' ) ;
327
347
const spans = memoryExporter . getFinishedSpans ( ) ;
328
348
const [ span ] = spans ;
349
+
329
350
assert . strictEqual ( spans . length , 1 ) ;
330
351
assertSpanSuccess ( span ) ;
331
352
assert . strictEqual ( span . parentSpanId , undefined ) ;
332
353
assert . strictEqual ( span . attributes [ SEMATTRS_FAAS_COLDSTART ] , false ) ;
354
+ // Since it is warm invocation, invocation span start time should be after than lambda start time
355
+ assert . ok ( hrTimeToMilliseconds ( span . startTime ) > time0 ) ;
356
+ // Since it is warm invocation, invocation span start time should be equal or after than handler call time
357
+ assert . ok ( hrTimeToMilliseconds ( span . startTime ) >= time1 ) ;
333
358
} ) ;
334
359
335
360
it ( 'should record coldstart with proactive initialization' , async ( ) => {
336
- initializeHandler ( 'lambda-test/sync.handler' , {
337
- lambdaStartTime : Date . now ( ) - 2 * lambdaMaxInitInMilliseconds ,
338
- } ) ;
361
+ const time0 = Date . now ( ) - 2 * lambdaMaxInitInMilliseconds ;
362
+ initializeHandler ( 'lambda-test/sync.handler' , { lambdaStartTime : time0 } ) ;
339
363
364
+ const time1 = Date . now ( ) ;
340
365
const result = await new Promise ( ( resolve , reject ) => {
341
366
lambdaRequire ( 'lambda-test/sync' ) . handler (
342
367
'arg' ,
@@ -350,13 +375,19 @@ describe('lambda handler', () => {
350
375
}
351
376
) ;
352
377
} ) ;
378
+
353
379
assert . strictEqual ( result , 'ok' ) ;
354
380
const spans = memoryExporter . getFinishedSpans ( ) ;
355
381
const [ span ] = spans ;
382
+
356
383
assert . strictEqual ( spans . length , 1 ) ;
357
384
assertSpanSuccess ( span ) ;
358
385
assert . strictEqual ( span . parentSpanId , undefined ) ;
359
386
assert . strictEqual ( span . attributes [ SEMATTRS_FAAS_COLDSTART ] , false ) ;
387
+ // Since it is warm invocation, invocation span start time should be after than lambda start time
388
+ assert . ok ( hrTimeToMilliseconds ( span . startTime ) > time0 ) ;
389
+ // Since it is warm invocation, invocation span start time should be equal or after than handler call time
390
+ assert . ok ( hrTimeToMilliseconds ( span . startTime ) >= time1 ) ;
360
391
} ) ;
361
392
362
393
it ( 'should record error' , async ( ) => {
0 commit comments