@@ -4,7 +4,7 @@ const EventEmitter = require('node:events')
4
4
const os = require ( 'node:os' )
5
5
const t = require ( 'tap' )
6
6
const fsMiniPass = require ( 'fs-minipass' )
7
- const { output, time, log } = require ( 'proc-log' )
7
+ const { output, time } = require ( 'proc-log' )
8
8
const errorMessage = require ( '../../../lib/utils/error-message.js' )
9
9
const ExecCommand = require ( '../../../lib/commands/exec.js' )
10
10
const { load : loadMockNpm } = require ( '../../fixtures/mock-npm' )
@@ -707,136 +707,3 @@ t.test('do no fancy handling for shellouts', async t => {
707
707
} )
708
708
} )
709
709
} )
710
-
711
- t . test ( 'container scenarios that trigger exit handler bug' , async t => {
712
- t . test ( 'process.exit() called before exit handler cleanup' , async ( t ) => {
713
- // Simulates when npm process exits directly without going through proper cleanup
714
-
715
- let exitHandlerNeverCalledLogged = false
716
- let npmBugReportLogged = false
717
-
718
- await mockExitHandler ( t , {
719
- config : { loglevel : 'notice' } ,
720
- } )
721
-
722
- // Override log.error to capture the specific error messages
723
- const originalLogError = log . error
724
- log . error = ( prefix , msg ) => {
725
- if ( msg === 'Exit handler never called!' ) {
726
- exitHandlerNeverCalledLogged = true
727
- }
728
- if ( msg === 'This is an error with npm itself. Please report this error at:' ) {
729
- npmBugReportLogged = true
730
- }
731
- return originalLogError ( prefix , msg )
732
- }
733
-
734
- t . teardown ( ( ) => {
735
- log . error = originalLogError
736
- } )
737
-
738
- // This happens when containers are stopped/killed before npm can clean up properly
739
- process . emit ( 'exit' , 1 )
740
-
741
- // Verify the bug is detected and logged correctly
742
- t . equal ( exitHandlerNeverCalledLogged , true , 'should log "Exit handler never called!" error' )
743
- t . equal ( npmBugReportLogged , true , 'should log npm bug report message' )
744
- } )
745
-
746
- t . test ( 'SIGTERM signal is handled properly' , ( t ) => {
747
- // This test verifies that our fix handles SIGTERM signals
748
-
749
- const ExitHandler = tmock ( t , '{LIB}/cli/exit-handler.js' )
750
- const exitHandler = new ExitHandler ( { process } )
751
-
752
- const initialSigtermCount = process . listeners ( 'SIGTERM' ) . length
753
- const initialSigintCount = process . listeners ( 'SIGINT' ) . length
754
- const initialSighupCount = process . listeners ( 'SIGHUP' ) . length
755
-
756
- // Register signal handlers
757
- exitHandler . registerUncaughtHandlers ( )
758
-
759
- const finalSigtermCount = process . listeners ( 'SIGTERM' ) . length
760
- const finalSigintCount = process . listeners ( 'SIGINT' ) . length
761
- const finalSighupCount = process . listeners ( 'SIGHUP' ) . length
762
-
763
- // Verify the fix: signal handlers should be registered
764
- t . ok ( finalSigtermCount > initialSigtermCount , 'SIGTERM handler should be registered' )
765
- t . ok ( finalSigintCount > initialSigintCount , 'SIGINT handler should be registered' )
766
- t . ok ( finalSighupCount > initialSighupCount , 'SIGHUP handler should be registered' )
767
-
768
- // Clean up listeners to avoid affecting other tests
769
- const sigtermListeners = process . listeners ( 'SIGTERM' )
770
- const sigintListeners = process . listeners ( 'SIGINT' )
771
- const sighupListeners = process . listeners ( 'SIGHUP' )
772
-
773
- for ( const listener of sigtermListeners ) {
774
- process . removeListener ( 'SIGTERM' , listener )
775
- }
776
- for ( const listener of sigintListeners ) {
777
- process . removeListener ( 'SIGINT' , listener )
778
- }
779
- for ( const listener of sighupListeners ) {
780
- process . removeListener ( 'SIGHUP' , listener )
781
- }
782
-
783
- t . end ( )
784
- } )
785
-
786
- t . test ( 'signal handler execution' , async ( t ) => {
787
- const ExitHandler = tmock ( t , '{LIB}/cli/exit-handler.js' )
788
- const exitHandler = new ExitHandler ( { process } )
789
-
790
- // Register signal handlers
791
- exitHandler . registerUncaughtHandlers ( )
792
-
793
- process . emit ( 'SIGTERM' )
794
- process . emit ( 'SIGINT' )
795
- process . emit ( 'SIGHUP' )
796
-
797
- // Clean up listeners
798
- process . removeAllListeners ( 'SIGTERM' )
799
- process . removeAllListeners ( 'SIGINT' )
800
- process . removeAllListeners ( 'SIGHUP' )
801
-
802
- t . pass ( 'signal handlers executed successfully' )
803
- t . end ( )
804
- } )
805
-
806
- t . test ( 'hanging async operation interrupted by signal' , async ( t ) => {
807
- // This test simulates the scenario where npm hangs on a long operation and receives SIGTERM/SIGKILL before it can complete
808
-
809
- let exitHandlerNeverCalledLogged = false
810
-
811
- const { exitHandler } = await mockExitHandler ( t , {
812
- config : { loglevel : 'notice' } ,
813
- } )
814
-
815
- // Override log.error to detect the bug message
816
- const originalLogError = log . error
817
- log . error = ( prefix , msg ) => {
818
- if ( msg === 'Exit handler never called!' ) {
819
- exitHandlerNeverCalledLogged = true
820
- }
821
- return originalLogError ( prefix , msg )
822
- }
823
-
824
- t . teardown ( ( ) => {
825
- log . error = originalLogError
826
- } )
827
-
828
- // Track if exit handler was called properly
829
- let exitHandlerCalled = false
830
- exitHandler . exit = ( ) => {
831
- exitHandlerCalled = true
832
- }
833
-
834
- // Simulate sending signal to the process without proper cleanup
835
- // This mimics what happens when a container is terminated
836
- process . emit ( 'exit' , 1 )
837
-
838
- // Verify the bug conditions
839
- t . equal ( exitHandlerCalled , false , 'exit handler should not be called in this scenario' )
840
- t . equal ( exitHandlerNeverCalledLogged , true , 'should detect and log the exit handler bug' )
841
- } )
842
- } )
0 commit comments