@@ -452,4 +452,141 @@ describe('AwsEcsResourceDetector', () => {
452
452
} ) ;
453
453
} ) ;
454
454
} ) ;
455
+
456
+ describe ( 'Container ID extraction' , ( ) => {
457
+ const testMetadataUri = 'http://169.254.170.2/v4/test' ;
458
+ const testHostname = 'test-hostname' ;
459
+ let readStub : sinon . SinonStub ;
460
+
461
+ beforeEach ( ( ) => {
462
+ process . env . ECS_CONTAINER_METADATA_URI_V4 = testMetadataUri ;
463
+ } ) ;
464
+
465
+ afterEach ( ( ) => {
466
+ sinon . restore ( ) ;
467
+ } ) ;
468
+
469
+ function setupMocks ( cgroupData : string ) {
470
+ sinon . stub ( os , 'hostname' ) . returns ( testHostname ) ;
471
+ readStub = sinon
472
+ . stub ( AwsEcsDetector , 'readFileAsync' as any )
473
+ . resolves ( cgroupData ) ;
474
+ }
475
+
476
+ function setupMetadataNock ( ) {
477
+ return nock ( 'http://169.254.170.2:80' )
478
+ . persist ( false )
479
+ . get ( '/v4/test' )
480
+ . reply ( 200 , {
481
+ ContainerARN : 'arn:aws:ecs:us-west-2:111122223333:container/test' ,
482
+ } )
483
+ . get ( '/v4/test/task' )
484
+ . reply ( 200 , {
485
+ TaskARN : 'arn:aws:ecs:us-west-2:111122223333:task/default/test' ,
486
+ Family : 'test-family' ,
487
+ Revision : '1' ,
488
+ Cluster : 'test-cluster' ,
489
+ LaunchType : 'FARGATE' ,
490
+ } ) ;
491
+ }
492
+
493
+ it ( 'should extract full container ID from new ECS Fargate format' , async ( ) => {
494
+ const taskId = 'c23e5f76c09d438aa1824ca4058bdcab' ;
495
+ const containerId = '1234567890abcdef' ;
496
+ const cgroupData = `/ecs/${ taskId } /${ taskId } -${ containerId } ` ;
497
+
498
+ setupMocks ( cgroupData ) ;
499
+ const nockScope = setupMetadataNock ( ) ;
500
+
501
+ const resource = detectResources ( { detectors : [ awsEcsDetector ] } ) ;
502
+ await resource . waitForAsyncAttributes ?.( ) ;
503
+
504
+ sinon . assert . calledOnce ( readStub ) ;
505
+ assert . ok ( resource ) ;
506
+ assertEcsResource ( resource , { } ) ;
507
+ assertContainerResource ( resource , {
508
+ name : testHostname ,
509
+ id : `${ taskId } -${ containerId } ` ,
510
+ } ) ;
511
+
512
+ nockScope . done ( ) ;
513
+ } ) ;
514
+
515
+ it ( 'should handle backward compatibility with legacy format' , async ( ) => {
516
+ const legacyContainerId =
517
+ 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm' ;
518
+
519
+ setupMocks ( legacyContainerId ) ;
520
+ const nockScope = setupMetadataNock ( ) ;
521
+
522
+ const resource = detectResources ( { detectors : [ awsEcsDetector ] } ) ;
523
+ await resource . waitForAsyncAttributes ?.( ) ;
524
+
525
+ sinon . assert . calledOnce ( readStub ) ;
526
+ assert . ok ( resource ) ;
527
+ assertEcsResource ( resource , { } ) ;
528
+ assertContainerResource ( resource , {
529
+ name : testHostname ,
530
+ id : 'bcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm' ,
531
+ } ) ;
532
+
533
+ nockScope . done ( ) ;
534
+ } ) ;
535
+
536
+ it ( 'should extract container ID from Docker format cgroup' , async ( ) => {
537
+ const dockerContainerId =
538
+ 'a4d00c9dd675d67f866c786181419e1b44832d4696780152e61afd44a3e02856' ;
539
+ const cgroupData = `1:blkio:/docker/${ dockerContainerId }
540
+ 2:cpu:/docker/${ dockerContainerId }
541
+ 3:cpuacct:/docker/${ dockerContainerId } ` ;
542
+
543
+ setupMocks ( cgroupData ) ;
544
+ const nockScope = setupMetadataNock ( ) ;
545
+
546
+ const resource = detectResources ( { detectors : [ awsEcsDetector ] } ) ;
547
+ await resource . waitForAsyncAttributes ?.( ) ;
548
+
549
+ sinon . assert . calledOnce ( readStub ) ;
550
+ assert . ok ( resource ) ;
551
+ assertEcsResource ( resource , { } ) ;
552
+ assertContainerResource ( resource , {
553
+ name : testHostname ,
554
+ id : dockerContainerId ,
555
+ } ) ;
556
+
557
+ nockScope . done ( ) ;
558
+ } ) ;
559
+
560
+ it ( 'should extract container ID from mixed ECS and Docker format cgroup' , async ( ) => {
561
+ const taskId = '447438d8540d49dca93b4f0a488ebe90' ;
562
+ const containerId = `${ taskId } -1364044452` ;
563
+ const cgroupData = `11:memory:/ecs/${ taskId } /${ containerId }
564
+ 10:devices:/ecs/${ taskId } /${ containerId }
565
+ 9:freezer:/ecs/${ taskId } /${ containerId }
566
+ 8:blkio:/ecs/${ taskId } /${ containerId }
567
+ 7:perf_event:/ecs/${ taskId } /${ containerId }
568
+ 6:net_cls,net_prio:/ecs/${ taskId } /${ containerId }
569
+ 5:cpuset:/ecs/${ taskId } /${ containerId }
570
+ 4:pids:/ecs/${ taskId } /${ containerId }
571
+ 3:hugetlb:/ecs/${ taskId } /${ containerId }
572
+ 2:cpu,cpuacct:/ecs/${ taskId } /${ containerId }
573
+ 1:name=systemd:/ecs/${ taskId } /${ containerId } ` ;
574
+
575
+ setupMocks ( cgroupData ) ;
576
+ const nockScope = setupMetadataNock ( ) ;
577
+
578
+ const resource = detectResources ( { detectors : [ awsEcsDetector ] } ) ;
579
+ await resource . waitForAsyncAttributes ?.( ) ;
580
+
581
+ sinon . assert . calledOnce ( readStub ) ;
582
+ assert . ok ( resource ) ;
583
+ assertEcsResource ( resource , { } ) ;
584
+ assertContainerResource ( resource , {
585
+ name : testHostname ,
586
+ id : containerId ,
587
+ } ) ;
588
+
589
+ nockScope . done ( ) ;
590
+ } ) ;
591
+ } ) ;
455
592
} ) ;
0 commit comments