aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerge Broslavsky <serge.broslavsky@linaro.org>2020-10-30 16:37:43 +0200
committerSerge Broslavsky <serge.broslavsky@linaro.org>2020-10-30 16:37:43 +0200
commit970d146181d37c11119af95cf673c06ad0c8fef3 (patch)
treec3d3029a67a392ec067e73ee7e2892f9e1de7b3e
parent367334f94efdc1b9d4e1319b85d71fd7a3e2951c (diff)
downloadlkft-bucket-970d146181d37c11119af95cf673c06ad0c8fef3.tar.gz
all done but the send_mail() function implementation
-rw-r--r--stable_report.py180
-rw-r--r--stable_report_config.py25
2 files changed, 146 insertions, 59 deletions
diff --git a/stable_report.py b/stable_report.py
index 580cf0a..58004a4 100644
--- a/stable_report.py
+++ b/stable_report.py
@@ -17,11 +17,12 @@ from squad_client.core.models import Squad, Project
import stable_report_config as config
-DEBUG=True
-#DEBUG=False
+DEBUG = False
+# DEBUG=False
if DEBUG:
import requests_cache
+
requests_cache.install_cache()
"""LKFT Stable Report
@@ -87,6 +88,9 @@ RESULT_WHEN_FAILED_TO_CHECK_IF_PROCESSED = True
# regexp to parse builds name
REGEXP_STABLE_BUILD = "^v(?P<major>\d+)\.(?P<minor>\d+)(?:\.(?P<patch>\d+))?(?:-(?P<count>\d+)-g(?P<hash>[\da-f]+))?$"
+# parse report file name
+REGEXP_REPORT_FILE_NAME = "^(?P<project>.*)--(?P<build>.*)\.[^.]*$"
+
# parse suite url to get suite id
# https://qa-reports.linaro.org/api/suites/66446/
@@ -132,7 +136,7 @@ if os.environ.get(ENV_AWS_MODE):
return "Item" in response
- def set_already_processed(project, builds, build):
+ def set_already_processed(project, build):
"""
Flags the build as already processed.
"""
@@ -167,9 +171,8 @@ if os.environ.get(ENV_AWS_MODE):
table.put_item(Item=record)
-
- def send_email(headers, body):
- pass
+ def send_email(email):
+ return False
# not deployed to AWS - limited functionality
@@ -192,7 +195,7 @@ else: # not os.environ.get(ENV_AWS_MODE)
return True
- def set_already_processed(project, builds, build):
+ def set_already_processed(project, build):
"""
Flags the build as already processed.
"""
@@ -200,9 +203,8 @@ else: # not os.environ.get(ENV_AWS_MODE)
### Dummy implementation
return
-
- def send_email(headers, body):
- pass
+ def send_email(email):
+ return False
def list_builds(group, list_all=False):
@@ -631,7 +633,9 @@ def scan_builds(group):
# create job files
for project in projects_to_process:
if not project.builds_to_process:
- with open("{0}/{1}.txt".format(DIRECTORY_SUMMARIES, project.slug), "w") as fp:
+ with open(
+ "{0}/{1}.txt".format(DIRECTORY_SUMMARIES, project.slug), "w"
+ ) as fp:
fp.write("Project {0} has no unreported builds\n".format(project.slug))
try:
os.remove(job_file_name)
@@ -759,7 +763,7 @@ def process_job_file(group, job_file_name, job_index=None):
"{0}Processing job {1}:\n{2}".format(
"({0}) ".format(job_index) if job_index != None else "",
job_file_name,
- json.dumps(setup_list, indent=2)
+ json.dumps(setup_list, indent=2),
)
)
@@ -776,7 +780,13 @@ def increment_build_counter(stats, counter_type):
def increment_environment_counter(stats, environment, counter_type):
env_record = stats["environments"].get(environment)
if not env_record:
- env_record = stats["environments"][environment] = {"suites": {}, "pass": 0, "fail": 0, "skip": 0, "xfail": 0}
+ env_record = stats["environments"][environment] = {
+ "suites": {},
+ "pass": 0,
+ "fail": 0,
+ "skip": 0,
+ "xfail": 0,
+ }
if env_record.get(counter_type) == None:
env_record[counter_type] = 0
env_record[counter_type] += 1
@@ -786,17 +796,33 @@ def increment_suite_counter(stats, environment, suite, counter_type):
# suite counter
suite_record = stats["suites"].get(suite)
if not suite_record:
- suite_record = stats["suites"][suite] = {"pass": 0, "fail": 0, "skip": 0, "xfail": 0}
+ suite_record = stats["suites"][suite] = {
+ "pass": 0,
+ "fail": 0,
+ "skip": 0,
+ "xfail": 0,
+ }
if suite_record.get(counter_type) == None:
suite_record[counter_type] = 0
suite_record[counter_type] += 1
# suite-in-environment counter
env_record = stats["environments"].get(environment)
if not env_record:
- env_record = stats["environments"][environment] = {"suites": {}, "pass": 0, "fail": 0, "skip": 0, "xfail": 0}
+ env_record = stats["environments"][environment] = {
+ "suites": {},
+ "pass": 0,
+ "fail": 0,
+ "skip": 0,
+ "xfail": 0,
+ }
suite_record = env_record["suites"].get(suite)
if not suite_record:
- suite_record = env_record["suites"][suite] = {"pass": 0, "fail": 0, "skip": 0, "xfail": 0}
+ suite_record = env_record["suites"][suite] = {
+ "pass": 0,
+ "fail": 0,
+ "skip": 0,
+ "xfail": 0,
+ }
if suite_record.get(counter_type) == None:
suite_record[counter_type] = 0
@@ -804,6 +830,7 @@ def increment_suite_counter(stats, environment, suite, counter_type):
# in memory cache of suite names retrieved by suite id from suite urls
g_suite_name_by_url = {}
+
def suite_name_from_url(group, project, url):
global g_suite_name_by_url
@@ -831,11 +858,12 @@ def suite_name_from_url(group, project, url):
def get_build_stats(group, project, build):
- build_stats = {"build": {"pass": 0, "fail": 0, "skip": 0, "xfail": 0},
- "environments": {},
- "suites": {},
- "failures": [],
- "skips": []
+ build_stats = {
+ "build": {"pass": 0, "fail": 0, "skip": 0, "xfail": 0},
+ "environments": {},
+ "suites": {},
+ "failures": [],
+ "skips": [],
}
testruns = build.testruns(count=1000)
@@ -845,15 +873,31 @@ def get_build_stats(group, project, build):
for test_id, test in tests.items():
increment_build_counter(build_stats, test.status)
- increment_environment_counter(build_stats, testrun.environment.slug, test.status)
- increment_suite_counter(build_stats, testrun.environment.slug, test.suite, test.status)
+ increment_environment_counter(
+ build_stats, testrun.environment.slug, test.status
+ )
+ increment_suite_counter(
+ build_stats, testrun.environment.slug, test.suite, test.status
+ )
if test.status == "fail":
- build_stats["failures"].append((testrun.environment.slug, suite_name_from_url(group, project, test.suite), test.name))
+ build_stats["failures"].append(
+ (
+ testrun.environment.slug,
+ suite_name_from_url(group, project, test.suite),
+ test.name,
+ )
+ )
build_stats["build"][test.status] += 1
elif test.status == "skip":
- build_stats["skips"].append((testrun.environment.slug, suite_name_from_url(group, project, test.suite), test.name))
+ build_stats["skips"].append(
+ (
+ testrun.environment.slug,
+ suite_name_from_url(group, project, test.suite),
+ test.name,
+ )
+ )
build_stats["build"][test.status] += 1
elif test.status == "pass":
@@ -868,8 +912,7 @@ def get_build_stats(group, project, build):
sorted_suites.append((suite, stats))
sorted_suites = sorted(
- ((suite, stats) for suite, stats in sorted_suites),
- key=lambda item: item[0]
+ ((suite, stats) for suite, stats in sorted_suites), key=lambda item: item[0]
)
build_stats["suites"] = sorted_suites
@@ -878,7 +921,10 @@ def get_build_stats(group, project, build):
for environment, stats in build_stats["environments"].items():
suites = stats["suites"]
sorted_suites = sorted(
- ((suite_name_from_url(group, project, url), stats) for url, stats in suites.items()),
+ (
+ (suite_name_from_url(group, project, url), stats)
+ for url, stats in suites.items()
+ ),
key=lambda item: item[0],
)
stats["suites"] = sorted_suites
@@ -920,7 +966,9 @@ def build_report(report_setup):
)
return None
- print("Generating report for build {0} of {1} ...".format(build.version, project.slug))
+ print(
+ "Generating report for build {0} of {1} ...".format(build.version, project.slug)
+ )
if not report_setup["prev_build"]:
prev_build = None
@@ -980,7 +1028,7 @@ def build_report(report_setup):
compared_to_prev=compared_to_prev,
compared_to_base=compared_to_base,
build_details_url=build_details_url,
- build_stats=build_stats
+ build_stats=build_stats,
)
msg = email.message_from_bytes(bytearray(report, "utf-8"))
@@ -989,17 +1037,14 @@ def build_report(report_setup):
subject = msg["Subject"]
del msg["Subject"]
- setup = {
- "From": "LKFT <lkft@linaro.org>",
- "To": "LKFT <lkft@linaro.org>"
- }
+ setup = {"From": "LKFT <lkft@linaro.org>", "To": "LKFT <lkft@linaro.org>"}
for regexp, a_setup in config.report_email_by_project:
match = re.match(regexp, project.slug)
if match:
setup.update(a_setup)
break
- msg["From"]= setup.get("From", config.default_report_from)
+ msg["From"] = setup.get("From", config.default_report_from)
values = setup.get("To", config.default_report_to)
msg["To"] = ", ".join(values)
@@ -1010,9 +1055,14 @@ def build_report(report_setup):
msg["Subject"] = subject
- file_name = "{0}/{1}--{2}.eml".format(DIRECTORY_REPORTS, project.slug, build.version)
+ file_name = "{0}/{1}--{2}.eml".format(
+ DIRECTORY_REPORTS, project.slug, build.version
+ )
- with open(file_name, "w",) as f:
+ with open(
+ file_name,
+ "w",
+ ) as f:
f.write(msg.as_string())
print("... wrote the report into {0}".format(file_name))
@@ -1024,7 +1074,7 @@ def build_report(report_setup):
compared_to_base=compared_to_base,
build_details_url=build_details_url,
build_stats=build_stats,
- details_url=os.environ.get(ENV_JOB_DETAILS_URL)
+ details_url=os.environ.get(ENV_JOB_DETAILS_URL),
)
with open("{0}/{1}.txt".format(DIRECTORY_SUMMARIES, project.slug), "a") as fp:
fp.write(summary)
@@ -1034,9 +1084,7 @@ def send_notifications(group):
try:
summary_files = os.listdir(DIRECTORY_SUMMARIES)
except FileNotFoundError as e:
- print(
- "Summary directory '{1}' not found".format(DIRECTORY_JOBS)
- )
+ print("Summary directory '{1}' not found".format(DIRECTORY_SUMMARIES))
return
if not summary_files:
@@ -1054,7 +1102,9 @@ def send_notifications(group):
msg = EmailMessage()
msg.set_content(body)
- msg["From"]= config.notification_email.get("From", config.default_notification_from)
+ msg["From"] = config.notification_email.get(
+ "From", config.default_notification_from
+ )
values = config.notification_email.get("To")
if len(values):
@@ -1068,14 +1118,51 @@ def send_notifications(group):
elif config.default_notification_cc and len(config.default_notification_cc):
msg["Cc"] = ", ".join(config.default_notification_cc)
- msg["Subject"] = config.notification_email.get("Subject", config.default_notification_subject)
+ msg["Subject"] = config.notification_email.get(
+ "Subject", config.default_notification_subject
+ )
with open("{0}/summary.eml".format(DIRECTORY_SUMMARIES), "w") as f:
f.write(msg.as_string())
+ send_email(email)
+
def send_reports(group):
- pass
+ try:
+ report_files = os.listdir(DIRECTORY_REPORTS)
+ except FileNotFoundError as e:
+ print("Report directory '{1}' not found".format(DIRECTORY_REPORTS))
+ return
+
+ if not report_files:
+ print("No summaries found")
+ return
+
+ report_files.sort()
+
+ for report_file in report_files:
+ match = re.match(REGEXP_REPORT_FILE_NAME, report_file)
+ if not match:
+ print("Skipped a report file with an invalid name: {0}".format(report_file))
+ continue
+
+ project = group.project(match.group("project"))
+ if not project:
+ print("Unknown project in report file: {0}".format(report_file))
+ continue
+
+ build = project.build(match.group("build"))
+ if not build:
+ print("Unknown build in report file: {0}".format(report_file))
+ continue
+
+ with open(os.path.join(DIRECTORY_REPORTS, report_file), "r") as f:
+ msg = email.message_from_bytes(bytearray(f.read(), "utf-8"))
+ if send_email(msg):
+ set_already_processed(project, build)
+ else:
+ print("Was not able to send email for report: {0}".format(report_file))
def dump_object(obj, margin="", escape_nls=True):
@@ -1110,6 +1197,7 @@ g_stages = {
"list-all": list_all_builds,
}
+
def main():
global g_stages
@@ -1120,7 +1208,9 @@ def main():
type=str,
nargs="+",
choices=g_stages.keys(),
- help="mention which stage(s) to run, one or more of: {0}".format(", ".join(g_stages.keys())),
+ help="mention which stage(s) to run, one or more of: {0}".format(
+ ", ".join(g_stages.keys())
+ ),
)
args = ap.parse_args()
diff --git a/stable_report_config.py b/stable_report_config.py
index 599c0d0..9ce97b4 100644
--- a/stable_report_config.py
+++ b/stable_report_config.py
@@ -14,12 +14,9 @@ default_notification_subject = "Stable RC reports have been generated"
notification_email = {
"From": "LKFT <lkft@linaro.org>",
- "To": [
- "Serge Broslavsky <serge.broslavsky@linaro.org>"
- ],
- "Cc": [
- ],
- "Subject": "Stable RC reports have been generated"
+ "To": ["Serge Broslavsky <serge.broslavsky@linaro.org>"],
+ "Cc": [],
+ "Subject": "Stable RC reports have been generated",
}
@@ -30,12 +27,12 @@ default_report_cc = None
# project name matching regexp => email setup
report_email_by_project = [
- ("^.*$", {
- "From": "LKFT <lkft@linaro.org>",
- "To": [
- "Serge Broslavsky <serge.broslavsky@linaro.org>"
- ],
- "Cc": [
- ]
- }),
+ (
+ "^.*$",
+ {
+ "From": "LKFT <lkft@linaro.org>",
+ "To": ["Serge Broslavsky <serge.broslavsky@linaro.org>"],
+ "Cc": [],
+ },
+ ),
]