1818# limitations under the License.
1919
2020import os
21+ import shlex
2122import sys
2223
2324TS_PID_SCRIPT = 'ts_process_handler.py'
25+ ROTATE_DIAGS_SCRIPT = 'sigusr2_rotate_diags.sh'
26+ ROTATE_CUSTOM_LOG_SCRIPT = 'sigusr2_rotate_custom_log.sh'
2427
2528
2629class Sigusr2Test :
@@ -29,17 +32,29 @@ class Sigusr2Test:
2932 """
3033
3134 __ts_counter = 1
32- __server = None
33-
34- def __init__ (self ):
35- self .server = self .__configure_server ()
36- self .ts = self .__configure_traffic_server ()
37-
38- def __configure_traffic_server (self ):
39- self ._ts_name = "sigusr2_ts{}" .format (Sigusr2Test .__ts_counter )
40- Sigusr2Test .__ts_counter += 1
41- self .ts = Test .MakeATSProcess (self ._ts_name )
42- self .ts .Disk .records_config .update (
35+ __server_counter = 1
36+
37+ @classmethod
38+ def _next_ts_name (cls ):
39+ ts_name = f"sigusr2_ts{ cls .__ts_counter } "
40+ cls .__ts_counter += 1
41+ return ts_name
42+
43+ @classmethod
44+ def _next_server_name (cls ):
45+ server_name = f"sigusr2_server{ cls .__server_counter } "
46+ cls .__server_counter += 1
47+ return server_name
48+
49+ @staticmethod
50+ def _make_script_command (script_name , * args ):
51+ quoted_args = ' ' .join (shlex .quote (str (arg )) for arg in args )
52+ return f"bash ./{ script_name } { quoted_args } "
53+
54+ def _configure_traffic_server (self , tr ):
55+ ts_name = self ._next_ts_name ()
56+ ts = tr .MakeATSProcess (ts_name )
57+ ts .Disk .records_config .update (
4358 {
4459 'proxy.config.http.wait_for_cache' : 1 ,
4560 'proxy.config.diags.debug.enabled' : 1 ,
@@ -50,18 +65,54 @@ def __configure_traffic_server(self):
5065 'proxy.config.log.rolling_enabled' : 0 ,
5166 'proxy.config.log.auto_delete_rolled_files' : 0 ,
5267 })
68+ return ts , ts_name
5369
54- self .diags_log = self .ts .Disk .diags_log .AbsPath
70+ def _configure_server (self ):
71+ server = Test .MakeOriginServer (self ._next_server_name ())
5572
56- # Add content handles for the rotated logs.
57- self .rotated_diags_log = self .diags_log + "_old"
58- self .ts .Disk .File (self .rotated_diags_log , id = "diags_log_old" )
73+ for path in ['/first' , '/second' , '/third' ]:
74+ request_header = {
75+ 'headers' : f'GET { path } HTTP/1.1\r \n Host: does.not.matter\r \n \r \n ' ,
76+ 'timestamp' : '1469733493.993' ,
77+ 'body' : ''
78+ }
79+ response_header = {
80+ 'headers' : 'HTTP/1.1 200 OK\r \n '
81+ 'Connection: close\r \n '
82+ 'Cache-control: max-age=85000\r \n \r \n ' ,
83+ 'timestamp' : '1469733493.993' ,
84+ 'body' : 'xxx'
85+ }
86+ server .addResponse ('sessionlog.json' , request_header , response_header )
87+
88+ return server
5989
60- self .log_dir = os .path .dirname (self .diags_log )
90+ def add_system_log_test (self ):
91+ tr = Test .AddTestRun ('Verify system logs can be rotated' )
92+ ts , ts_name = self ._configure_traffic_server (tr )
6193
62- self .ts .Disk .remap_config .AddLine (
63- 'map http://127.0.0.1:{0} http://127.0.0.1:{1}' .format (self .ts .Variables .port , self .server .Variables .Port ))
64- self .ts .Disk .logging_yaml .AddLine (
94+ rotated_diags_log = f'{ ts .Disk .diags_log .AbsPath } _old'
95+ ts .Disk .File (rotated_diags_log , id = 'diags_log_old' )
96+
97+ tr .Processes .Default .Command = self ._make_script_command (
98+ ROTATE_DIAGS_SCRIPT , sys .executable , f'./{ TS_PID_SCRIPT } ' , ts_name , ts .Disk .diags_log .AbsPath , rotated_diags_log )
99+ tr .Processes .Default .ReturnCode = 0
100+ tr .Processes .Default .StartBefore (ts )
101+
102+ ts .Disk .diags_log .Content += Testers .ExcludesExpression (
103+ 'traffic server running' , 'The new diags.log should not reference the running traffic server' )
104+ ts .Disk .diags_log .Content += Testers .ContainsExpression (
105+ 'Reseated diags.log' , 'The new diags.log should indicate the newly opened diags.log' )
106+ ts .Disk .diags_log_old .Content += Testers .ContainsExpression (
107+ 'traffic server running' , 'The rotated diags.log should keep the original startup message' )
108+
109+ def add_configured_log_test (self ):
110+ tr = Test .AddTestRun ('Verify yaml.log logs can be rotated' )
111+ ts , ts_name = self ._configure_traffic_server (tr )
112+ server = self ._configure_server ()
113+
114+ ts .Disk .remap_config .AddLine (f'map http://127.0.0.1:{ ts .Variables .port } http://127.0.0.1:{ server .Variables .Port } ' )
115+ ts .Disk .logging_yaml .AddLine (
65116 '''
66117 logging:
67118 formats:
@@ -71,155 +122,43 @@ def __configure_traffic_server(self):
71122 - filename: test_rotation
72123 format: has_path
73124 ''' )
74- self .configured_log = os .path .join (self .log_dir , "test_rotation.log" )
75- self .ts .Disk .File (self .configured_log , id = "configured_log" )
76-
77- self .rotated_configured_log = self .configured_log + "_old"
78- self .ts .Disk .File (self .rotated_configured_log , id = "configured_log_old" )
79- self .ts .StartBefore (self .server )
80- return self .ts
81-
82- def __configure_server (self ):
83- if Sigusr2Test .__server :
84- return Sigusr2Test .__server
85- server = Test .MakeOriginServer ("server" )
86- Sigusr2Test .__server = server
87- for path in ['/first' , '/second' , '/third' ]:
88- request_header = {
89- "headers" : "GET {} HTTP/1.1\r \n "
90- "Host: does.not.matter\r \n \r \n " .format (path ),
91- "timestamp" : "1469733493.993" ,
92- "body" : ""
93- }
94- response_header = {
95- "headers" : "HTTP/1.1 200 OK\r \n "
96- "Connection: close\r \n "
97- "Cache-control: max-age=85000\r \n \r \n " ,
98- "timestamp" : "1469733493.993" ,
99- "body" : "xxx"
100- }
101- server .addResponse ("sessionlog.json" , request_header , response_header )
102- return server
103-
104- def get_sigusr2_signal_command (self ):
105- """
106- Return the command that will send a USR2 signal to the traffic server
107- process.
108- """
109- return (f"{ sys .executable } { TS_PID_SCRIPT } "
110- f"--signal SIGUSR2 { self ._ts_name } " )
111-
112-
113- Test .Summary = '''
114- Verify support of external log rotation via SIGUSR2.
115- '''
116125
117- Test .Setup .CopyAs (TS_PID_SCRIPT , Test .RunDirectory )
126+ configured_log = os .path .join (ts .Variables .LOGDIR , 'test_rotation.log' )
127+ ts .Disk .File (configured_log , id = 'configured_log' )
118128
119- #
120- # Test 1: Verify SIGUSR2 behavior for system logs.
121- #
122- tr1 = Test .AddTestRun ("Verify system logs can be rotated" )
129+ rotated_configured_log = f'{ configured_log } _old'
130+ ts .Disk .File (rotated_configured_log , id = 'configured_log_old' )
123131
124- # Configure Server.
125- diags_test = Sigusr2Test ()
132+ ts .StartBefore (server )
133+ tr .Processes .Default .Command = self ._make_script_command (
134+ ROTATE_CUSTOM_LOG_SCRIPT , sys .executable , f'./{ TS_PID_SCRIPT } ' , ts_name , ts .Variables .port , configured_log ,
135+ rotated_configured_log )
136+ tr .Processes .Default .ReturnCode = 0
137+ tr .Processes .Default .StartBefore (ts )
126138
127- # Configure our rotation processes.
128- rotate_diags_log = tr1 .Processes .Process ("rotate_diags_log" , "mv {} {}" .format (diags_test .diags_log , diags_test .rotated_diags_log ))
139+ ts .Disk .configured_log .Content += Testers .ExcludesExpression (
140+ '/first' , 'The new test_rotation.log should not have the first GET retrieval in it.' )
141+ ts .Disk .configured_log .Content += Testers .ExcludesExpression (
142+ '/second' , 'The new test_rotation.log should not have the second GET retrieval in it.' )
143+ ts .Disk .configured_log .Content += Testers .ContainsExpression (
144+ '/third' , 'The new test_rotation.log should have the third GET retrieval in it.' )
129145
130- # Configure the signaling of SIGUSR2 to traffic_server.
131- tr1 .Processes .Default .Command = diags_test .get_sigusr2_signal_command ()
132- tr1 .Processes .Default .Return = 0
133- tr1 .Processes .Default .Ready = When .FileExists (diags_test .diags_log )
146+ ts .Disk .configured_log_old .Content += Testers .ContainsExpression (
147+ '/first' , 'test_rotation.log_old should have the first GET retrieval in it.' )
148+ ts .Disk .configured_log_old .Content += Testers .ContainsExpression (
149+ '/second' , 'test_rotation.log_old should have the second GET retrieval in it.' )
150+ ts .Disk .configured_log_old .Content += Testers .ExcludesExpression (
151+ '/third' , 'test_rotation.log_old should not have the third GET retrieval in it.' )
134152
135- # Configure process order.
136- tr1 .Processes .Default .StartBefore (rotate_diags_log )
137- rotate_diags_log .StartBefore (diags_test .ts )
138- tr1 .StillRunningAfter = diags_test .ts
139- tr1 .StillRunningAfter = diags_test .server
140153
141- # diags.log should have been rotated. The old one had the reference to traffic
142- # server running, this new one shouldn't. But it should indicate that the new
143- # diags.log was opened.
144- diags_test .ts .Disk .diags_log .Content += Testers .ExcludesExpression (
145- "traffic server running" , "The new diags.log should not reference the running traffic server" )
154+ Test .Summary = '''
155+ Verify support of external log rotation via SIGUSR2.
156+ '''
146157
147- diags_test .ts .Disk .diags_log .Content += Testers .ContainsExpression (
148- "Reseated diags.log" , "The new diags.log should indicate the newly opened diags.log" )
158+ Test .Setup .Copy (TS_PID_SCRIPT )
159+ Test .Setup .Copy (ROTATE_DIAGS_SCRIPT )
160+ Test .Setup .Copy (ROTATE_CUSTOM_LOG_SCRIPT )
149161
150- #
151- # Test 2: Verify SIGUSR2 isn't needed for rotated configured logs.
152- #
153- tr2 = Test .AddTestRun ("Verify yaml.log logs can be rotated" )
154- configured_test = Sigusr2Test ()
155-
156- first_curl = tr2 .Processes .Process (
157- "first_curl" , 'curl "http://127.0.0.1:{0}/first" --verbose' .format (configured_test .ts .Variables .port ))
158- # Note that for each of these processes, aside from the final Default one, they
159- # are all treated like long-running servers to AuTest. Thus the long sleeps
160- # only allow us to wait until the logs get populated with the desired content,
161- # the test will not wait the entire time for them to complete.
162- first_curl_ready = tr2 .Processes .Process ("first_curl_ready" , 'sleep 30' )
163- # In the autest environment, it can take more than 10 seconds for the log file to be created.
164- first_curl_ready .StartupTimeout = 30
165- first_curl_ready .Ready = When .FileContains (configured_test .configured_log , "/first" )
166-
167- rotate_log = tr2 .Processes .Process (
168- "rotate_log_file" , "mv {} {}" .format (configured_test .configured_log , configured_test .rotated_configured_log ))
169-
170- second_curl = tr2 .Processes .Process (
171- "second_curl" , 'curl "http://127.0.0.1:{0}/second" --verbose' .format (configured_test .ts .Variables .port ))
172-
173- second_curl_ready = tr2 .Processes .Process ("second_curl_ready" , 'sleep 30' )
174- # In the autest environment, it can take more than 10 seconds for the log file to be created.
175- second_curl_ready .StartupTimeout = 30
176- second_curl_ready .Ready = When .FileContains (configured_test .rotated_configured_log , "/second" )
177-
178- send_pkill = tr2 .Processes .Process ("Send_SIGUSR2" , configured_test .get_sigusr2_signal_command ())
179- send_pkill_ready = tr2 .Processes .Process ("send_pkill_ready" , 'sleep 30' )
180- send_pkill_ready .StartupTimeout = 30
181- send_pkill_ready .Ready = When .FileExists (configured_test .configured_log )
182-
183- third_curl = tr2 .Processes .Process (
184- "third_curl" , 'curl "http://127.0.0.1:{0}/third" --verbose' .format (configured_test .ts .Variables .port ))
185- third_curl_ready = tr2 .Processes .Process ("third_curl_ready" , 'sleep 30' )
186- # In the autest environment, it can take more than 10 seconds for the log file to be created.
187- third_curl_ready .StartupTimeout = 30
188- third_curl_ready .Ready = When .FileContains (configured_test .configured_log , "/third" )
189-
190- tr2 .Processes .Default .Command = "echo waiting for test processes to be done"
191- tr2 .Processes .Default .Return = 0
192-
193- # Configure process order:
194- # 1. curl /first. The entry should be logged to current log which will be _old.
195- # 2. mv the log to _old.
196- # 3. curl /second. The entry should end up in _old log.
197- # 4. Send a SIGUSR2 to traffic_server. The log should be recreated.
198- # 5. curl /third. The entry should end up in the new, non-old, log file.
199- #
200- tr2 .Processes .Default .StartBefore (third_curl_ready )
201- third_curl_ready .StartBefore (third_curl )
202- third_curl .StartBefore (send_pkill_ready )
203- send_pkill_ready .StartBefore (send_pkill )
204- send_pkill .StartBefore (second_curl_ready )
205- second_curl_ready .StartBefore (second_curl )
206- second_curl .StartBefore (rotate_log )
207- rotate_log .StartBefore (first_curl_ready )
208- first_curl_ready .StartBefore (first_curl )
209- first_curl .StartBefore (configured_test .ts )
210- tr2 .StillRunningAfter = configured_test .ts
211-
212- # Verify that the logs are in the correct files.
213- configured_test .ts .Disk .configured_log .Content += Testers .ExcludesExpression (
214- "/first" , "The new test_rotation.log should not have the first GET retrieval in it." )
215- configured_test .ts .Disk .configured_log .Content += Testers .ExcludesExpression (
216- "/second" , "The new test_rotation.log should not have the second GET retrieval in it." )
217- configured_test .ts .Disk .configured_log .Content += Testers .ContainsExpression (
218- "/third" , "The new test_rotation.log should have the third GET retrieval in it." )
219-
220- configured_test .ts .Disk .configured_log_old .Content += Testers .ContainsExpression (
221- "/first" , "test_rotation.log_old should have the first GET retrieval in it." )
222- configured_test .ts .Disk .configured_log_old .Content += Testers .ContainsExpression (
223- "/second" , "test_rotation.log_old should have the second GET retrieval in it." )
224- configured_test .ts .Disk .configured_log_old .Content += Testers .ExcludesExpression (
225- "/third" , "test_rotation.log_old should not have the third GET retrieval in it." )
162+ sigusr2_test = Sigusr2Test ()
163+ sigusr2_test .add_system_log_test ()
164+ sigusr2_test .add_configured_log_test ()
0 commit comments