11#!/usr/bin/env python3
22import os
33import sys
4- import smtplib
54import argparse
65import subprocess
76import time
87
8+ from smtplib import SMTP
9+ from datetime import date
910from email .mime .multipart import MIMEMultipart
1011from email .mime .text import MIMEText
1112from pathlib import Path
1213from typing import Dict , List
1314
14- default_mails = [
15- "phracek@redhat.com" ,
16- "hhorak@redhat.com" ,
17- "pkubat@redhat.com" ,
18- "pkhartsk@redhat.com" ,
19- ]
20- upstream_mails = [
21- "phracek@redhat.com" ,
22- "cpapasta@redhat.com" ,
23- "nodeshiftcore@redhat.com" ,
24- ]
25-
26- SCLORG_MAILS = {
27- # Format is 'repo_name', and list of mails to infor
28- "s2i-ruby-container" : ["jprokop@redhat.com" ],
29- "s2i-python-container" : [
30- "lbalhar@redhat.com" ,
31- "ksurma@redhat.com" ,
32- "thrnciar@redhat.com" ,
33- ],
34- "postgresql-container" : [
35- "fjanus@redhat.com" ,
36- "ljavorsk@redhat.com" ,
37- "mschorm@redhat.com" ,
38- "psloboda@redhat.com" ,
39- ],
40- "mariadb-container" : [
41- "fjanus@redhat.com" ,
42- "ljavorsk@redhat.com" ,
43- "mschorm@redhat.com" ,
44- "psloboda@redhat.com" ,
45- ],
46- "mysql-container" : [
47- "fjanus@redhat.com" ,
48- "ljavorsk@redhat.com" ,
49- "mschorm@redhat.com" ,
50- "psloboda@redhat.com" ,
51- ],
52- "s2i-perl-container" : ["jplesnik@redhat.com" , "mspacek@redhat.com" ],
53- "s2i-nodejs-container" : [
54- "cpapasta@redhat.com" ,
55- "nodeshiftcore@redhat.com" ,
56- "jprokop@redhat.com" ,
57- ],
58- }
59-
60- SCLORG_UPSTREAM_TESTS_MAILS = {
61- "s2i-nodejs-container" : ["cpapasta@redhat.com" , "nodeshiftcore@redhat.com" ]
62- }
15+ default_mails : List [str ] = []
16+ SCLORG_MAILS = {}
17+ SEND_PASTE_BIN = "/root/ci-scripts/send_to_paste_bin.sh"
6318
6419TEST_CASES = {
6520 # Format is test for OS and king of test, what TMT Plan is used and MSG to mail
10358}
10459
10560# The default directory used for nightly build
106- RESULTS_DIR = "/var/tmp /daily_reports_dir"
61+ RESULTS_DIR = Path ( "/var/ci-scripts /daily_reports_dir" )
10762# The default directory used for running build
108- SCLORG_DIR = "/var/tmp /daily_scl_tests"
63+ SCLORG_DIR = Path ( "/var/ci-scripts /daily_scl_tests" )
10964
11065
11166def run_command (
@@ -163,6 +118,9 @@ def __init__(self):
163118 self .log_dir = os .getcwd ()
164119 self .mime_msg = MIMEMultipart ()
165120 self .body = ""
121+ self .date = date .today ().strftime ("%Y-%m-%d" )
122+ self .reports_dir = RESULTS_DIR / self .date
123+ self .sclorg_dir = SCLORG_DIR / self .date
166124 self .add_email = []
167125 self .full_success = False
168126 if self .args .upstream_tests :
@@ -173,7 +131,7 @@ def __init__(self):
173131 def parse_args (self ):
174132 parser = argparse .ArgumentParser (
175133 description = "NightlyTestsReport program report all failures"
176- "over all OS and Tests (tests, test-openshift , test-openshift-4 )."
134+ "over all OS and Tests (tests, test-pytest , test-openshift-pytest )."
177135 )
178136 parser .add_argument (
179137 "--send-email" ,
@@ -193,19 +151,41 @@ def parse_args(self):
193151
194152 return parser .parse_args ()
195153
196- def prepare (self ) -> bool :
197- if self .args .log_dir :
198- if not os .path .exists (self .args .log_dir ):
199- print ("Log dir you specified by --log-dir parameter does not exist." )
200- return False
201- self .log_dir = self .args .log_dir
202- return True
154+ def return_plan_name (self , item ) -> str :
155+ return "" .join (
156+ [x [1 ] for x in self .available_test_case if item .startswith (x [0 ])]
157+ )
203158
204- def send_file_to_pastebin (self , log_path , log_name : str ):
159+ def load_mails_from_environment (self ):
160+ if "DB_MAILS" in os .environ :
161+ SCLORG_MAILS ["mariadb-container" ] = os .environ ["DB_MAILS" ].split ("," )
162+ SCLORG_MAILS ["mysql-container" ] = os .environ ["DB_MAILS" ].split ("," )
163+ SCLORG_MAILS ["postgresql-container" ] = os .environ ["DB_MAILS" ].split ("," )
164+ if "RUBY_MAILS" in os .environ :
165+ SCLORG_MAILS ["s2i-ruby-container" ] = os .environ ["RUBY_MAILS" ].split ("," )
166+ if "PYTHON_MAILS" in os .environ :
167+ SCLORG_MAILS ["s2i-python-container" ] = os .environ ["PYTHON_MAILS" ].split ("," )
168+ if "NODEJS_MAILS" in os .environ :
169+ SCLORG_MAILS ["s2i-nodejs-container" ] = os .environ ["NODEJS_MAILS" ].split ("," )
170+ if "PERL_MAILS" in os .environ :
171+ SCLORG_MAILS ["s2i-perl-container" ] = os .environ ["PERL_MAILS" ].split ("," )
172+ if "UPSTREAM_TESTS_MAILS" in os .environ :
173+ SCLORG_MAILS ["upstream-tests" ] = os .environ ["UPSTREAM_TESTS_MAILS" ].split (
174+ ","
175+ )
176+ if "DEFAULT_MAILS" in os .environ :
177+ default_mails .extend (os .environ ["DEFAULT_MAILS" ].split ("," ))
178+ self .send_email = os .environ .get ("SEND_EMAIL" , False )
179+ self .send_email = True
180+
181+ print (f"Loaded mails from environment: '{ SCLORG_MAILS } '" )
182+ print (f"Default mails: '{ default_mails } '" )
183+ print (f"Send email: '{ self .send_email } '" )
184+
185+ def send_file_to_pastebin (self , log_path , log_name : Path ):
205186 if not os .path .exists (log_path ):
206187 return
207- send_paste_bin = os .getenv ("HOME" ) + "/ci-scripts/send_to_paste_bin.sh"
208- cmd = f'{ send_paste_bin } "{ log_path } " "{ log_name } "'
188+ cmd = f'{ SEND_PASTE_BIN } "{ log_path } " "{ str (log_name )} "'
209189 print (f"sending logs to pastebin: { cmd } " )
210190 for count in range (5 ):
211191 try :
@@ -226,6 +206,39 @@ def get_pastebin_url(self, log_name: str) -> str:
226206 return line .replace ("Link:" , "" ).strip ()
227207 return ""
228208
209+ def store_tmt_logs_to_dict (
210+ self , path_dir : Path , test_case , is_running = False , not_exists = False
211+ ):
212+ if not_exists :
213+ msg = (
214+ f"Data dir for test case { test_case } does not exist."
215+ f"Look at log in attachment called '{ test_case } -log.txt'."
216+ )
217+ else :
218+ if is_running :
219+ msg = (
220+ f"tmt tests for case { test_case } is still running."
221+ f"Look at log in attachment called '{ test_case } -log.txt'."
222+ )
223+ else :
224+ msg = (
225+ f"tmt command has failed for test case { test_case } ."
226+ f"Look at log in attachment called '{ test_case } -log.txt'."
227+ )
228+ self .data_dict ["tmt" ]["msg" ].append (msg )
229+ if is_running :
230+ dictionary_key = "tmt_running"
231+ else :
232+ dictionary_key = "tmt_failed"
233+ self .data_dict ["tmt" ][dictionary_key ].append (test_case )
234+ log_path = self .sclorg_dir / f"{ test_case } " / "log.txt"
235+ log_name = path_dir / f"{ test_case } .log.txt"
236+ self .send_file_to_pastebin (log_path = log_path , log_name = log_name )
237+ if log_name .exists ():
238+ with open (log_name ) as f :
239+ print (f .readlines ())
240+ self .data_dict ["tmt" ]["logs" ].append ((test_case , log_path , log_name ))
241+
229242 def collect_data (self ):
230243 # Collect data to class dictionary
231244 # self.data_dict['tmt'] item is used for Testing Farm errors per each OS and test case
@@ -240,74 +253,39 @@ def collect_data(self):
240253 self .data_dict ["SUCCESS_DATA" ] = []
241254 failed_tests = False
242255 for test_case , plan , _ in self .available_test_case :
243- path_dir = Path (RESULTS_DIR ) / test_case / "nightly"
256+ path_dir = self .reports_dir / test_case
257+ if not self .reports_dir .is_dir ():
258+ print (
259+ f"The reports directory { self .reports_dir } does not exist, skipping it."
260+ )
261+ continue
244262 if not path_dir .is_dir ():
245- print (f"The test case { path_dir } does not exists that is weird" )
263+ print (f"The test case { path_dir } does not exist that is weird" )
246264 continue
265+ plan_name = self .return_plan_name (plan )
266+ print (f"Collecting data for test case { test_case } with plan { plan_name } " )
267+ print (f"Path for test case { test_case } is: { path_dir } " )
247268 # It looks like TMT is still running for long time
248269 if (path_dir / "tmt_running" ).exists ():
249- self .data_dict ["tmt" ]["msg" ].append (
250- f"tmt tests for case { test_case } is still running."
251- f"Look at log in attachment called '{ test_case } -log.txt'."
252- )
253- self .data_dict ["tmt" ]["tmt_running" ].append (test_case )
254- for sclorg in ["S2I" , "NOS2I" ]:
255- name = f"{ test_case } -{ sclorg } "
256- self .send_file_to_pastebin (
257- log_path = Path (SCLORG_DIR ) / f"{ name } " / "log.txt" ,
258- log_name = f"{ path_dir } /{ name } .log.txt" ,
259- )
260- self .data_dict ["tmt" ]["logs" ].append (
261- (
262- name ,
263- Path (SCLORG_DIR ) / f"{ name } " / "log.txt" ,
264- Path (path_dir ) / f"{ name } .log.txt" ,
265- )
266- )
270+ print (f"tmt tests for case { test_case } is still running." )
271+ self .store_tmt_logs_to_dict (path_dir , test_case , is_running = True )
267272 failed_tests = True
268273 continue
269274 # TMT command failed for some reason. Look at logs for given namespace
270275 # /var/tmp/daily_scl_tests/<test_case>/log.txt file
271276 if (path_dir / "tmt_failed" ).exists ():
272- self .data_dict ["tmt" ]["msg" ].append (
273- f"tmt command has failed for test case { test_case } ."
274- f"Look at log in attachment called '{ test_case } -log.txt'."
275- )
276- self .data_dict ["tmt" ]["tmt_failed" ].append (test_case )
277- for sclorg in ["S2I" , "NOS2I" ]:
278- name = f"{ test_case } -{ sclorg } "
279- self .send_file_to_pastebin (
280- log_path = Path (SCLORG_DIR ) / f"{ name } " / "log.txt" ,
281- log_name = f"{ path_dir } /{ name } .log.txt" ,
282- )
283- self .data_dict ["tmt" ]["logs" ].append (
284- (
285- name ,
286- Path (SCLORG_DIR ) / f"{ name } " / "log.txt" ,
287- Path (path_dir ) / f"{ name } .log.txt" ,
288- )
289- )
277+ print (f"tmt command has failed for test case { test_case } ." )
278+ self .store_tmt_logs_to_dict (path_dir , test_case )
290279 failed_tests = True
291280 continue
292- data_dir = path_dir / "plans" / plan / "data"
281+ data_dir = path_dir / "plans/nightly" / plan_name / "data"
282+ print (f"Data dir for test case { test_case } is: { data_dir } " )
293283 if not data_dir .is_dir ():
294- self .data_dict ["tmt" ]["msg" ].append (
295- f"Data dir for test case { test_case } does not exist."
296- f"Look at log in attachment called '{ test_case } -log.txt'."
284+ self .store_tmt_logs_to_dict (path_dir , test_case , not_exists = True )
285+ self .send_file_to_pastebin (
286+ log_path = self .sclorg_dir / f"{ test_case } " / "log.txt" ,
287+ log_name = f"{ path_dir } /{ test_case } .log.txt" ,
297288 )
298- for sclorg in ["S2I" , "NOS2I" ]:
299- name = f"{ test_case } -{ sclorg } "
300- self .send_file_to_pastebin (
301- log_path = Path (SCLORG_DIR ) / f"{ name } " / "log.txt" ,
302- log_name = f"{ path_dir } /{ name } .log.txt" ,
303- )
304- self .data_dict ["tmt" ]["logs" ].append (
305- (
306- name ,
307- Path (SCLORG_DIR ) / f"{ name } " / "log.txt" ,
308- Path (path_dir ) / f"{ name } .log.txt" ,
309- )
310- )
311289 failed_tests = True
312290 continue
313291 results_dir = data_dir / "results"
@@ -411,6 +389,7 @@ def generate_tmt_logs_containers(self):
411389 self .body += "<br>"
412390
413391 def generate_emails (self ):
392+ print ("generate_emails: " , self .data_dict )
414393 for test_case , plan , _ in self .available_test_case :
415394 if test_case not in self .data_dict :
416395 continue
@@ -422,8 +401,8 @@ def generate_emails(self):
422401 [ml for ml in mails if ml not in self .add_email ]
423402 )
424403
425- def send_email (self ):
426- if not self .args . send_email :
404+ def send_emails (self ):
405+ if not self .send_email :
427406 print ("Sending email is not allowed" )
428407 return
429408 if self .full_success :
@@ -439,29 +418,25 @@ def send_email(self):
439418
440419 send_from = "phracek@redhat.com"
441420 if self .args .upstream_tests :
442- send_to = upstream_mails
421+ send_to = SCLORG_MAILS . get ( "upstream-tests" , [])
443422 else :
444423 send_to = default_mails + self .add_email
445424
446425 self .mime_msg ["From" ] = send_from
447426 self .mime_msg ["To" ] = ", " .join (send_to )
448427 self .mime_msg ["Subject" ] = subject_msg
449428 self .mime_msg .attach (MIMEText (self .body , "html" ))
450- smtp = smtplib . SMTP ("127.0.0.1 " )
429+ smtp = SMTP ("smtp.redhat.com " )
451430 smtp .sendmail (send_from , send_to , self .mime_msg .as_string ())
452431 smtp .close ()
453432 print ("Sending email finished" )
454433
455434
456435if __name__ == "__main__" :
457436 ntr = NightlyTestsReport ()
458- if not ntr .prepare ():
459- print (
460- "Preparation for NightlyBuild report has failed. Please look what's wrong."
461- )
462- sys .exit (1 )
437+ ntr .load_mails_from_environment ()
463438 ntr .collect_data ()
464439 ntr .generate_email_body ()
465440 ntr .generate_emails ()
466- ntr .send_email ()
441+ ntr .send_emails ()
467442 sys .exit (0 )
0 commit comments