@@ -527,3 +527,89 @@ def test_full_pass(self, sub_factory, monkeypatch, tmp_tle):
527
527
assert snd_msg .data == expected_msg .data
528
528
finally :
529
529
gatherer .stop ()
530
+
531
+
532
+ def test_sigterm (tmp_config_file , tmp_config_parser ):
533
+ """Test that SIGTERM signal is handled."""
534
+ import os
535
+ import signal
536
+ import time
537
+ from multiprocessing import Process
538
+
539
+ from pytroll_collectors .geographic_gatherer import GeographicGatherer
540
+
541
+ with open (tmp_config_file , mode = "w" ) as fp :
542
+ tmp_config_parser .write (fp )
543
+
544
+ opts = arg_parse (["-c" , "minimal_config" , "-p" , "40000" , "-n" , "false" , "-i" , "localhost:12345" ,
545
+ str (tmp_config_file )])
546
+ # We don't need the triggers here. They also interfere with completing the test (the test never exits)
547
+ with patch ("pytroll_collectors.geographic_gatherer.TriggerFactory.create" ):
548
+ gatherer = GeographicGatherer (opts )
549
+ proc = Process (target = gatherer .run )
550
+ proc .start ()
551
+ time .sleep (1 )
552
+ os .kill (proc .pid , signal .SIGTERM )
553
+ proc .join ()
554
+
555
+ assert proc .exitcode == 0
556
+
557
+
558
+ def test_sigterm_with_collection (tmp_config_file , tmp_config_parser ):
559
+ """Test that SIGTERM signal is handled when there is collection ongoing."""
560
+ import os
561
+ import signal
562
+ import time
563
+ from multiprocessing import Process
564
+
565
+ from pytroll_collectors .geographic_gatherer import GeographicGatherer
566
+
567
+ with open (tmp_config_file , mode = "w" ) as fp :
568
+ tmp_config_parser .write (fp )
569
+
570
+ opts = arg_parse (["-c" , "posttroll_section" , "-p" , "40000" , "-n" , "false" , "-i" , "localhost:12345" ,
571
+ str (tmp_config_file )])
572
+ # Use a fake trigger that initially sets some granules and after a while clears them
573
+ with patch ("pytroll_collectors.geographic_gatherer.PostTrollTrigger" ,
574
+ new = FakeTriggerWithGranules ):
575
+ gatherer = GeographicGatherer (opts )
576
+ proc = Process (target = gatherer .run )
577
+ proc .start ()
578
+ time .sleep (1 )
579
+ os .kill (proc .pid , signal .SIGTERM )
580
+ proc .join ()
581
+
582
+ assert proc .exitcode == 0
583
+
584
+
585
+ class FakeTriggerWithGranules :
586
+ """Fake trigger class used in testing SIGTERM handling.
587
+
588
+ At creation, adds "foo" to collector granules. When is_alive() is called the second time, it clears the granules.
589
+ """
590
+
591
+ def __init__ (self , collectors , * args , ** kwargs ):
592
+ """Initialize the trigger class."""
593
+ self .collectors = collectors
594
+ for col in self .collectors :
595
+ col .granules .append ("foo" )
596
+ self ._args = args
597
+ self ._kwargs = kwargs
598
+ self ._counter = 0
599
+
600
+ def is_alive (self ):
601
+ """Return True for alive thread."""
602
+ if self ._counter > 0 :
603
+ # On the second call clear the granules
604
+ for col in self .collectors :
605
+ col .granules = []
606
+ self ._counter += 1
607
+ return True
608
+
609
+ def start (self ):
610
+ """Start the trigger."""
611
+ pass
612
+
613
+ def stop (self ):
614
+ """Stop the trigger."""
615
+ pass
0 commit comments