3
3
import sys
4
4
import smtplib
5
5
import argparse
6
+ import subprocess
6
7
7
- from email .mime .application import MIMEApplication
8
8
from email .mime .multipart import MIMEMultipart
9
9
from email .mime .text import MIMEText
10
10
from pathlib import Path
103
103
SCLORG_DIR = "/var/tmp/daily_scl_tests"
104
104
105
105
106
+ def run_command (
107
+ cmd ,
108
+ return_output : bool = True ,
109
+ ignore_error : bool = False ,
110
+ shell : bool = True ,
111
+ ** kwargs ,
112
+ ):
113
+ """
114
+ Run provided command on host system using the same user as invoked this code.
115
+ Raises subprocess.CalledProcessError if it fails.
116
+ :param cmd: list or str
117
+ :param return_output: bool, return output of the command
118
+ :param ignore_error: bool, do not fail in case nonzero return code
119
+ :param shell: bool, run command in shell
120
+ :param debug: bool, print command in shell, default is suppressed
121
+ :return: None or str
122
+ """
123
+ print (f"command: { cmd } " )
124
+ try :
125
+ if return_output :
126
+ return subprocess .check_output (
127
+ cmd ,
128
+ stderr = subprocess .STDOUT ,
129
+ universal_newlines = True ,
130
+ shell = shell ,
131
+ ** kwargs ,
132
+ )
133
+ else :
134
+ return subprocess .check_call (cmd , shell = shell , ** kwargs )
135
+ except subprocess .CalledProcessError as cpe :
136
+ if ignore_error :
137
+ if return_output :
138
+ return cpe .output
139
+ else :
140
+ return cpe .returncode
141
+ else :
142
+ print (f"failed with code { cpe .returncode } and output:\n { cpe .output } " )
143
+ raise cpe
144
+
145
+
106
146
class NightlyTestsReport (object ):
107
147
def __init__ (self ):
108
148
self .tmp_path_dir : Path
@@ -156,6 +196,16 @@ def prepare(self) -> bool:
156
196
self .log_dir = self .args .log_dir
157
197
return True
158
198
199
+ def send_file_to_pastebin (self , log_path , log_name : str ):
200
+ if not os .path .exists (log_name ):
201
+ return
202
+ send_paste_bin = os .getenv ("HOME" ) + "/ci-scripts/send_to_paste_bin.sh"
203
+ cmd = f'{ send_paste_bin } "{ log_path } " "{ log_name } "'
204
+ try :
205
+ run_command (cmd )
206
+ except subprocess .CalledProcessError :
207
+ pass
208
+
159
209
def get_pastebin_url (self , log_name : str ) -> str :
160
210
with open (log_name , "r" ) as f :
161
211
lines = f .read ()
@@ -183,33 +233,29 @@ def collect_data(self):
183
233
path_dir = Path (RESULTS_DIR ) / test_case
184
234
if not path_dir .is_dir ():
185
235
print (f"The test case { path_dir } does not exists that is weird" )
186
- self .data_dict ["tmt" ]["logs" ].append (
187
- f"Nightly build tests for { test_case } is not finished or did not run. "
188
- f"Check nightly build machine for logs."
236
+ continue
237
+ # It looks like TMT is still running for long time
238
+ if (path_dir / "tmt_running" ).exists ():
239
+ self .data_dict ["tmt" ]["msg" ].append (
240
+ f"tmt tests for case { test_case } is still running."
241
+ f"Look at log in attachment called '{ test_case } -log.txt'."
189
242
)
243
+ self .data_dict ["tmt" ]["tmt_running" ].append (test_case )
190
244
for sclorg in ["S2I" , "NOS2I" ]:
191
245
name = f"{ test_case } -{ sclorg } "
246
+ self .send_file_to_pastebin (
247
+ log_path = Path (SCLORG_DIR ) / f"{ test_case } -{ sclorg } " / "log.txt" ,
248
+ log_name = f"{ RESULTS_DIR } /{ name } .txt" ,
249
+ )
192
250
self .data_dict ["tmt" ]["logs" ].append (
193
251
(
194
252
name ,
195
253
Path (SCLORG_DIR ) / f"{ test_case } -{ sclorg } " / "log.txt" ,
196
- f"{ name } .txt" ,
254
+ Path ( RESULTS_DIR ) / f"{ name } .txt" ,
197
255
)
198
256
)
199
257
failed_tests = True
200
258
continue
201
- # It looks like TMT is still running for long time
202
- if (path_dir / "tmt_running" ).exists ():
203
- self .data_dict ["tmt" ]["msg" ].append (
204
- f"tmt tests for case { test_case } is still running."
205
- f"Look at log in attachment called '{ test_case } -log.txt'."
206
- )
207
- self .data_dict ["tmt" ]["tmt_running" ].append (test_case )
208
- self .data_dict ["tmt" ]["logs" ].append (
209
- (test_case , path_dir / "log.txt" , "log.txt" )
210
- )
211
- failed_tests = True
212
- continue
213
259
# TMT command failed for some reason. Look at logs for given namespace
214
260
# /var/tmp/daily_scl_tests/<test_case>/log.txt file
215
261
if (path_dir / "tmt_failed" ).exists ():
@@ -218,9 +264,19 @@ def collect_data(self):
218
264
f"Look at log in attachment called '{ test_case } -log.txt'."
219
265
)
220
266
self .data_dict ["tmt" ]["tmt_failed" ].append (test_case )
221
- self .data_dict ["tmt" ]["logs" ].append (
222
- (test_case , path_dir / "log.txt" , "log.txt" )
223
- )
267
+ for sclorg in ["S2I" , "NOS2I" ]:
268
+ name = f"{ test_case } -{ sclorg } "
269
+ self .send_file_to_pastebin (
270
+ log_path = Path (SCLORG_DIR ) / f"{ test_case } -{ sclorg } " / "log.txt" ,
271
+ log_name = f"{ RESULTS_DIR } /{ name } .txt" ,
272
+ )
273
+ self .data_dict ["tmt" ]["logs" ].append (
274
+ (
275
+ name ,
276
+ Path (SCLORG_DIR ) / f"{ test_case } -{ sclorg } " / "log.txt" ,
277
+ Path (RESULTS_DIR ) / f"{ name } .txt" ,
278
+ )
279
+ )
224
280
failed_tests = True
225
281
continue
226
282
data_dir = path_dir / "plans" / plan / "data"
@@ -229,9 +285,19 @@ def collect_data(self):
229
285
f"Data dir for test case { test_case } does not exist."
230
286
f"Look at log in attachment called '{ test_case } -log.txt'."
231
287
)
232
- self .data_dict ["tmt" ]["logs" ].append (
233
- (test_case , path_dir / "log.txt" , "log.txt" )
234
- )
288
+ for sclorg in ["S2I" , "NOS2I" ]:
289
+ name = f"{ test_case } -{ sclorg } "
290
+ self .send_file_to_pastebin (
291
+ log_path = Path (SCLORG_DIR ) / f"{ test_case } -{ sclorg } " / "log.txt" ,
292
+ log_name = f"{ RESULTS_DIR } /{ name } .txt" ,
293
+ )
294
+ self .data_dict ["tmt" ]["logs" ].append (
295
+ (
296
+ name ,
297
+ Path (SCLORG_DIR ) / f"{ test_case } -{ sclorg } " / "log.txt" ,
298
+ Path (RESULTS_DIR ) / f"{ name } .txt" ,
299
+ )
300
+ )
235
301
failed_tests = True
236
302
continue
237
303
results_dir = data_dir / "results"
@@ -266,7 +332,7 @@ def generate_email_body(self):
266
332
body_failure = "<b>Nightly builds Testing Farm failures:</b><br>"
267
333
body_success = "<b>These nightly builds were completely successful:</b><br>"
268
334
# Function for generation mail body
269
- if self .data_dict ["tmt" ]["logs " ]:
335
+ if self .data_dict ["tmt" ]["msg " ]:
270
336
self .body += (
271
337
f"{ body_failure } \n "
272
338
f"Tests were not successful because Testing Farm failures. "
@@ -305,22 +371,27 @@ def generate_failed_containers(self):
305
371
306
372
def generate_success_containers (self ):
307
373
for test_case , cont_path , log_name in self .data_dict ["SUCCESS_DATA" ]:
308
- mime_name = f"{ test_case } -{ log_name } "
309
- if os .path .exists (cont_path ):
310
- attach = MIMEApplication (open (cont_path , "r" ).read (), Name = mime_name )
311
- attach .add_header (
312
- "Content-Disposition" , 'attachment; filename="{}"' .format (mime_name )
374
+ if os .path .exists (log_name ):
375
+ self .body += (
376
+ f" <a href='{ self .get_pastebin_url (log_name = log_name )} '>See logs</a>"
377
+ f"<br>"
313
378
)
314
- self .mime_msg .attach (attach )
315
379
316
380
def generate_tmt_logs_containers (self ):
317
381
for test_case , cont_path , log_name in self .data_dict ["tmt" ]["logs" ]:
318
- print (cont_path , log_name )
319
- if os .path .exists (cont_path ):
382
+ print (test_case , cont_path , log_name )
383
+ if os .path .exists (log_name ):
384
+ self .body += (
385
+ f"<b>{ test_case } </b> <a href='{ self .get_pastebin_url (log_name = log_name )} '>"
386
+ f"See logs</a>"
387
+ f"<br>"
388
+ )
389
+ else :
320
390
self .body += (
321
- f"<a href=' { self . get_pastebin_url ( log_name = cont_path ) } ' >{ test_case } </a> "
322
- f"<br> <br>"
391
+ f"<b >{ test_case } </b> No logs available. "
392
+ f"Check nightly build machine <br>"
323
393
)
394
+ self .body += "<br>"
324
395
325
396
def generate_emails (self ):
326
397
for test_case , plan , _ in self .available_test_case :
0 commit comments