2727import re
2828import threading
2929import logging
30+ import collections
31+
3032try :
3133 from command_runner import *
3234except ImportError : # would be ModuleNotFoundError in Python 3+
@@ -48,11 +50,36 @@ def timestamp(date):
4850 return date .timestamp ()
4951
5052
53+ # Log capture class, blatantly copied from https://stackoverflow.com/a/37967421/2635443
54+ class TailLogHandler (logging .Handler ):
55+
56+ def __init__ (self , log_queue ):
57+ logging .Handler .__init__ (self )
58+ self .log_queue = log_queue
59+
60+ def emit (self , record ):
61+ self .log_queue .append (self .format (record ))
62+
63+
64+ class TailLogger (object ):
65+
66+ def __init__ (self , maxlen ):
67+ self ._log_queue = collections .deque (maxlen = maxlen )
68+ self ._log_handler = TailLogHandler (self ._log_queue )
69+
70+ def contents (self ):
71+ return '\n ' .join (self ._log_queue )
72+
73+ @property
74+ def log_handler (self ):
75+ return self ._log_handler
76+
77+
5178# We need a logging unit here
5279logger = logging .getLogger ()
53- logger .setLevel (logging .ERROR )
80+ logger .setLevel (logging .DEBUG )
5481handler = logging .StreamHandler (sys .stdout )
55- handler .setLevel (logging .ERROR )
82+ handler .setLevel (logging .DEBUG )
5683formatter = logging .Formatter ('%(asctime)s - %(name)s - %(levelname)s - %(message)s' )
5784handler .setFormatter (formatter )
5885logger .addHandler (handler )
@@ -64,6 +91,7 @@ def timestamp(date):
6491if os .name == 'nt' :
6592 ENCODING = 'cp437'
6693 PING_CMD = 'ping 127.0.0.1 -n 4'
94+ PING_CMD_10S = 'ping 127.0.0.1 -n 10'
6795 PING_CMD_REDIR = PING_CMD + ' 1>&2'
6896 # Make sure we run the failure command first so end result is okay
6997 PING_CMD_AND_FAILURE = 'ping 0.0.0.0 -n 2 1>&2 & ping 127.0.0.1 -n 2'
@@ -73,6 +101,7 @@ def timestamp(date):
73101else :
74102 ENCODING = 'utf-8'
75103 PING_CMD = ['ping' , '-c' , '4' , '127.0.0.1' ]
104+ PING_CMD_10S = ['ping' , '-c' , '10' , '127.0.0.1' ]
76105 PING_CMD_REDIR = 'ping -c 4 127.0.0.1 1>&2'
77106 PING_CMD_AND_FAILURE = 'ping -c 2 0.0.0.0 1>&2; ping -c 2 127.0.0.1'
78107 PRINT_FILE_CMD = 'cat {}' .format (TEST_FILENAME )
@@ -779,13 +808,26 @@ def test_no_close_queues():
779808
780809
781810def test_heartbeat ():
782- exit_code , output = command_runner (PING_CMD , heartbeat = 2 , shell = False )
811+ tail = TailLogger (10 )
812+
813+ formatter = logging .Formatter ('%(asctime)s - %(name)s - %(levelname)s - %(message)s' )
814+
815+ log_handler = tail .log_handler
816+ log_handler .setFormatter (formatter )
817+ logger .addHandler (log_handler ) # Add the handler to the logger
818+
819+
820+ exit_code , output = command_runner (PING_CMD_10S + " -n 10" , heartbeat = 2 , shell = False )
821+ log_contents = tail .contents ()
822+ print ("LOGS\n " , log_contents )
783823 assert exit_code == 0 , 'Exit code should be 0 for ping command with heartbeat'
784- assert 'Still running command after 2 seconds' in output , 'Output should have heartbeat'
824+ # We should have a modulo 2 heeatbeat
825+ assert "Still running command after 4 seconds" in log_contents , 'Output should have heartbeat'
785826
786827
787828if __name__ == "__main__" :
788829 print ("Example code for %s, %s" % (__intname__ , __build__ ))
830+
789831 test_standard_ping_with_encoding ()
790832 test_standard_ping_with_default_encoding ()
791833 test_standard_ping_with_encoding_disabled ()
0 commit comments