Skip to content

Commit 56d35f1

Browse files
committed
Add first draft of nightly reports
Signed-off-by: Petr "Stone" Hracek <phracek@redhat.com>
1 parent a5280ab commit 56d35f1

10 files changed

Lines changed: 146 additions & 144 deletions

.github/workflows/build-and-push.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,6 @@ jobs:
1919
registry_username: ${{ secrets.QUAY_IMAGE_SCLORG_BUILDER_USERNAME }}
2020
registry_token: ${{ secrets.QUAY_IMAGE_SCLORG_BUILDER_TOKEN }}
2121
dockerfile: Dockerfile.daily-tests
22-
tag: "0.7.1"
22+
tag: "0.8.0"
2323
image_name: "upstream-daily-tests"
2424
quay_application_token: ${{ secrets.QUAY_IMAGE_SCLORG_UPDATE_DESC }}

Dockerfile.daily-tests

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM quay.io/fedora/fedora:42
22

33
ENV SHARED_DIR="/var/ci-scripts" \
44
VERSION="42" \
5-
RELEASE_UPSTREAM="0.7.1" \
5+
RELEASE_UPSTREAM="0.8.0" \
66
UPSTREAM_TMT_REPO="https://github.com/sclorg/sclorg-testing-farm" \
77
UPSTREAM_TMT_DIR="sclorg-testing-farm" \
88
HOME="/home/nightly" \

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ shellcheck:
77
./run-shellcheck.sh `git ls-files *.sh`
88

99
build_images:
10-
podman build -t quay.io/sclorg/upstream-daily-tests:0.7.1 -f Dockerfile.daily-tests .
10+
podman build -t quay.io/sclorg/upstream-daily-tests:0.8.0 -f Dockerfile.daily-tests .

daily_tests/daily_nightly_tests_report.py

Lines changed: 103 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,65 +1,20 @@
11
#!/usr/bin/env python3
22
import os
33
import sys
4-
import smtplib
54
import argparse
65
import subprocess
76
import time
87

8+
from smtplib import SMTP
9+
from datetime import date
910
from email.mime.multipart import MIMEMultipart
1011
from email.mime.text import MIMEText
1112
from pathlib import Path
1213
from 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

6419
TEST_CASES = {
6520
# Format is test for OS and king of test, what TMT Plan is used and MSG to mail
@@ -103,9 +58,9 @@
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

11166
def 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

456435
if __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)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#!/bin/bash
2+
3+
set -x
4+
5+
cd /root/ci-scripts/daily_tests
6+
CUR_DATE=$(date +%Y-%m-%d)
7+
id
8+
9+
#find "/var/ci-scripts" -ctime +30 -type d -exec rm-rf {} \;
10+
echo "Daily nightly reports log files every 10 minutes..."
11+
postfix start &
12+
ls -la $SHARED_DIR/${CUR_DATE}
13+
find "${SHARED_DIR}/${CUR_DATE}" -type f -name "tmt_*"
14+
echo "--------------------"
15+
python3 ./daily_nightly_tests_report.py
16+
# Let's sleep for 10 minutes

0 commit comments

Comments
 (0)