• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tfcollins / telemetry / 12804737190

16 Jan 2025 08:17AM UTC coverage: 37.59% (+4.2%) from 33.437%
12804737190

push

github

web-flow
Merge pull request #45 from trishaange01/pytest_parser

Update pytest xml parser and markdown gist results

78 of 107 new or added lines in 2 files covered. (72.9%)

1 existing line in 1 file now uncovered.

524 of 1394 relevant lines covered (37.59%)

0.38 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

16.25
/telemetry/report/markdown.py
1
import os
×
2
import re
×
3
import telemetry
×
4
from string import Template
×
5

6
class Markdown:
×
7
    def __init__(self, file):
×
8
        self.filename = os.path.basename(file)
1✔
9
        with open(file,'r') as f:
1✔
10
            self.template_str = f.read() 
1✔
11
            self.template = Template(self.template_str)
1✔
12

13
    def get_identifiers(self):
×
14
        return re.findall('\$(\w+)\s',self.template_str)
1✔
15

16
    def substitute(self, fields):
×
17
        return self.template.substitute(fields)
1✔
18
    
19
    def generate(self, fields, custom_file_name=None):
×
20
        formatted = self.substitute(fields)
1✔
21
        output = self.filename.split('.')[0] + ".md"
1✔
22
        if custom_file_name:
1✔
23
            output = custom_file_name
1✔
24
        with open(f"{os.path.join(output)}",'w') as f:
1✔
25
            f.write(formatted)
1✔
26
        return output
1✔
27
    
28
class ResultsMarkdown(Markdown):
×
29
    CRITICAL = ["UpdateBOOTFiles"]
×
30

31
    def __init__(self, data):
×
32
        self.param_dict = self.generate_param(data)
×
33
        dir = os.path.dirname(os.path.realpath(__file__))
×
34
        template_path = os.path.join(dir, "templates", "results.template.md")
×
35
        super(ResultsMarkdown, self).__init__(template_path)
×
36

37
    def generate_param(self,data):
×
38
        param_dict = {}
×
39
        for bn, info in data.items():
×
40
            if info == "NA":
×
41
                param_dict[bn] = None
×
42
                continue
×
43
            test_build_status = None
×
44
            if str(info["last_failing_stage"]) in self.CRITICAL:
×
45
                test_build_status = "FAILURE"
×
46
            elif int(info["drivers_missing"])>0 or\
×
47
                int(info["dmesg_errors_found"])>0 or\
48
                int(info["pytest_errors"])>0 or\
49
                int(info["pytest_failures"])>0 or\
50
                (int(info["pytest_skipped"])==0 and int(info["pytest_tests"]==0)):
51
                test_build_status = "UNSTABLE"
×
52
            elif str(info["last_failing_stage"]) == "NA":
×
53
                test_build_status = "PASSING"
×
54
            else:
55
                test_build_status = "INVALID"
×
56

57
            # update test stage status
58
            uboot_reached_status = "✔" if bool(info["uboot_reached"]) else "❌"
×
59
            linux_prompt_reached_status = "✔" if bool(info["linux_prompt_reached"]) else "❌"
×
60
            drivers_enumerated_status = "✔" if int(info["drivers_missing"]) == 0 and test_build_status != "FAILURE" else "❌"
×
61
            dmesg_status = "✔" if int(info["dmesg_errors_found"]) == 0 and test_build_status != "FAILURE" else "❌"
×
62
            pytest_tests_status = "✔" if int(info["pytest_failures"]) == 0 and test_build_status != "FAILURE" else "❌"
×
63

64
            # added validations
65
            pytest_tests_status = "⛔" if int(info["pytest_skipped"]) == 0 and int(info["pytest_tests"]) == 0 else pytest_tests_status
×
66

67
            # update test stage details
68
            if test_build_status == "FAILURE":
×
69
                iio_drivers_missing_details = "No Details"
×
70
                iio_drivers_found_details = "No Details"
×
71
                dmesg_errors_found_details = "No Details"
×
72
                pytest_failures_details = "No Details"
×
73
            else:
74
                iio_drivers_missing_details = "No missing drivers" if len(info["missing_devs"]) == 0 else ("<br>").join(info["missing_devs"])
×
75
                iio_drivers_found_details = "No iio drivers found" if len(info["enumerated_devs"]) == 0 else ("<br>").join(info["enumerated_devs"])
×
NEW
76
                dmesg_errors_found_details = "No errors" if len(info["dmesg_err"]) == 0 else ("<br>").join(info["dmesg_err"])                   
×
NEW
77
                pytest_failures_details = "No failures"      
×
UNCOV
78
                pytest_failures_details = "Invalid" if pytest_tests_status == "⛔" else pytest_failures_details
×
NEW
79
                pytest_details = []
×
NEW
80
                if len(info["pytest_failure"]) != 0:
×
NEW
81
                    pytest_details.append(info["pytest_failure"][0])
×
NEW
82
                    for item in info["pytest_failure"][1:]:
×
NEW
83
                        item_update = "- " + item
×
NEW
84
                        pytest_details.append(item_update)
×
NEW
85
                    pytest_failures_details = ("\n\n").join(pytest_details) 
×
86

87
            last_failing_stage = str(info["last_failing_stage"])
×
88
            last_failing_stage_failure = str(info["last_failing_stage_failure"])
×
89

90
            param_dict[bn] = {
×
91
                "board_name" : bn,
92
                "branch": info["info_txt"]["BRANCH"],
93
                "pr_id": info["info_txt"]["PR_ID"],
94
                "timestamp": info["info_txt"]["TIMESTAMP"],
95
                "direction": info["info_txt"]["DIRECTION"],
96
                "triggered_by": info["info_txt"]["Triggered by"],
97
                "commit_sha": info["info_txt"]["COMMIT SHA"],
98
                "commit_date": info["info_txt"]["COMMIT_DATE"],
99
                "test_job_name": info["jenkins_project_name"],
100
                "test_build_number": info["jenkins_build_number"],
101
                "test_build_status": test_build_status,
102
                "uboot_reached_status": uboot_reached_status,
103
                "linux_prompt_reached_status": linux_prompt_reached_status,
104
                "drivers_enumerated_status":  drivers_enumerated_status,
105
                "dmesg_status":  dmesg_status,
106
                "pytest_tests_status": pytest_tests_status,
107
                "drivers_enumerated": "",
108
                "drivers_missing": "",
109
                "dmesg_warnings_found": "",
110
                "dmesg_errors_found": "",
111
                "pytest_tests": "",
112
                "pytest_errors": "",
113
                "pytest_failures": "",
114
                "pytest_skipped": "",
115
                "last_failing_stage": last_failing_stage if last_failing_stage != "NA" else "No Details",
116
                "last_failing_stage_failure":last_failing_stage_failure if last_failing_stage_failure != "NA" else "No Details",
117
                "iio_drivers_missing_details": iio_drivers_missing_details,
118
                "iio_drivers_found_details": iio_drivers_found_details,
119
                "dmesg_errors_found_details": dmesg_errors_found_details,
120
                "pytest_failures_details": pytest_failures_details,
121
                "test_status": test_build_status,
122
            }
123
        return param_dict
×
124

125
    def generate_gist(self, url, token):
×
126
        print(f"========== Publish Results ==========")
×
127
        for bn,param in self.param_dict.items():
×
128
            if not param:
×
129
                print(f'Result: {bn} | ---- | HW not available')
×
130
                continue
×
131
            outfile = self.generate(param, bn+".md")
×
132
            gist = telemetry.gist.Gist(url, token)
×
133
            gist_link = gist.create_gist(outfile, f'''Boardname: {param["board_name"]}\n
×
134
                                           Branch: {param["branch"]}\nPR ID: {param["pr_id"]}\n
135
                                           timestamp: {param["timestamp"]}''')
136
            print(f'Result: {bn} | {gist.gh_url}/{gist_link} | {param["test_status"]}')
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc