33import logging
44import logging .config
55import os
6+ import re
67import threading
78from pathlib import Path
8- from subprocess import PIPE , STDOUT , Popen , run
9+ from subprocess import PIPE , Popen , run
910from tempfile import mkdtemp
1011from time import sleep
1112
@@ -20,6 +21,9 @@ def __init__(self):
2021 self .setup_environment ()
2122 self .setup_logging ()
2223 atexit .register (self .cleanup )
24+ self .log_expected_msgs : None | [str ] = None
25+ self .log_unexpected_msgs : None | [str ] = None
26+ self .log_msg_assertions_passed = False
2327 self .log .info ("Warnet test base initialized" )
2428
2529 def setup_environment (self ):
@@ -59,6 +63,19 @@ def cleanup(self, signum=None, frame=None):
5963 self .server_thread .join ()
6064 self .server = None
6165
66+ def _print_and_assert_msgs (self , message ):
67+ print (message )
68+ if (self .log_expected_msgs or self .log_unexpected_msgs ) and assert_log (
69+ message , self .log_expected_msgs , self .log_unexpected_msgs
70+ ):
71+ self .log_msg_assertions_passed = True
72+
73+ def assert_log_msgs (self ):
74+ assert (
75+ self .log_msg_assertions_passed
76+ ), f"Log assertion failed. Expected message not found: { self .log_expected_msgs } "
77+ self .log_msg_assertions_passed = False
78+
6279 def warcli (self , cmd , network = True ):
6380 self .log .debug (f"Executing warcli command: { cmd } " )
6481 command = ["warcli" ] + cmd .split ()
@@ -94,19 +111,19 @@ def start_server(self):
94111 # TODO: check for conflicting warnet process
95112 # maybe also ensure that no conflicting docker networks exist
96113
97- # For kubernetes we assume the server is started outside test base
114+ # For kubernetes we assume the server is started outside test base,
98115 # but we can still read its log output
99116 self .log .info ("Starting Warnet server" )
100117 self .server = Popen (
101- ["kubectl" , "logs" , "-f" , "rpc-0" ],
118+ ["kubectl" , "logs" , "-f" , "rpc-0" , "--since=1s" ],
102119 stdout = PIPE ,
103- stderr = STDOUT ,
120+ stderr = PIPE ,
104121 bufsize = 1 ,
105122 universal_newlines = True ,
106123 )
107124
108125 self .server_thread = threading .Thread (
109- target = self .output_reader , args = (self .server .stdout , print )
126+ target = self .output_reader , args = (self .server .stdout , self . _print_and_assert_msgs )
110127 )
111128 self .server_thread .daemon = True
112129 self .server_thread .start ()
@@ -176,3 +193,26 @@ def get_scenario_return_code(self, scenario_name):
176193 if len (scns ) == 0 :
177194 raise Exception (f"Scenario { scenario_name } not found in running scenarios" )
178195 return scns [0 ]["return_code" ]
196+
197+
198+ def assert_equal (thing1 , thing2 , * args ):
199+ if thing1 != thing2 or any (thing1 != arg for arg in args ):
200+ raise AssertionError (
201+ "not({})" .format (" == " .join (str (arg ) for arg in (thing1 , thing2 ) + args ))
202+ )
203+
204+
205+ def assert_log (log_message , expected_msgs , unexpected_msgs = None ) -> bool :
206+ if unexpected_msgs is None :
207+ unexpected_msgs = []
208+ assert_equal (type (expected_msgs ), list )
209+ assert_equal (type (unexpected_msgs ), list )
210+
211+ found = True
212+ for unexpected_msg in unexpected_msgs :
213+ if re .search (re .escape (unexpected_msg ), log_message , flags = re .MULTILINE ):
214+ raise AssertionError (f"Unexpected message found in log: { unexpected_msg } " )
215+ for expected_msg in expected_msgs :
216+ if re .search (re .escape (expected_msg ), log_message , flags = re .MULTILINE ) is None :
217+ found = False
218+ return found
0 commit comments