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

tfcollins / telemetry / 10495659905

21 Aug 2024 06:45PM UTC coverage: 34.158% (-24.1%) from 58.234%
10495659905

push

github

tfcollins
Put exceptions back for missing backends

Signed-off-by: Travis F. Collins <travis.collins@analog.com>

0 of 2 new or added lines in 1 file covered. (0.0%)

211 existing lines in 13 files now uncovered.

428 of 1253 relevant lines covered (34.16%)

0.34 hits per line

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

46.67
/telemetry/gparser/parser.py
UNCOV
1
from urllib.parse import urlparse
×
UNCOV
2
import json
×
UNCOV
3
import os
×
UNCOV
4
import re
×
UNCOV
5
import traceback
×
UNCOV
6
import junitparser
×
UNCOV
7
import telemetry
×
UNCOV
8
from junitparser import JUnitXml, Skipped, Error, Failure
×
9

UNCOV
10
def get_parser(url,grabber=None):
×
11
    '''Factory method that provides appropriate parser object base on given url'''
12
    parsers = {
1✔
13
        '^.*dmesg_[a-zA-Z0-9-]+\.log': Dmesg,
14
        '^.*dmesg_.+err\.log': DmesgError,
15
        '^.*dmesg_.+warn\.log': DmesgWarning,
16
        '^.*enumerated_devs\.log': EnumeratedDevs,
17
        '^.*missing_devs\.log': MissingDevs,
18
        '^.*pyadi-iio.*\.xml': [PytestFailure, PytestSkipped, PytestError],
19
        '^.*HWTestResults\.xml': [MatlabFailure, MatlabSkipped, MatlabError],
20
        '^.*info\.txt': InfoTxt,
21
    }
22

23
    # find parser
24
    for sk, parser in parsers.items():
1✔
25
        if re.match(sk, url):
1✔
26
            if isinstance(parser, list):
1✔
27
                return [p(url, grabber) for p in parser]
×
28
            return parser(url, grabber)
1✔
29

30
    raise Exception("Cannot find Parser for {}".format(url))
×
31

UNCOV
32
def remove_suffix(input_string, suffix):
×
33
    if suffix and input_string.endswith(suffix):
1✔
34
        return input_string[:-len(suffix)]
1✔
35
    return input_string
1✔
36

UNCOV
37
class Parser():
×
38
    '''Base class for a parser object'''
UNCOV
39
    def __init__(self, url, grabber=None):
×
40
        
41
        self.url = url
1✔
42
        self.server = None
1✔
43
        self.job = None
1✔
44
        self.job_no = None
1✔
45
        self.job_date = None
1✔
46
        self.file_name = None
1✔
47
        self.file_info = None
1✔
48
        self.target_board = None
1✔
49
        self.artifact_info_type = None
1✔
50
        self.payload_raw = []
1✔
51
        self.payload = []
1✔
52
        self.payload_param = []
1✔
53
        if not grabber:
1✔
54
            self.grabber = telemetry.grabber.Grabber()
×
55
        else:
56
            self.grabber = grabber
1✔
57
        self.initialize()
1✔
58

UNCOV
59
    def initialize(self):
×
60
        url_ = urlparse(self.url)
1✔
61
        self.multilevel = False
1✔
62
        if len(url_.path.split('/job/')) > 2:
1✔
63
            self.multilevel = True
1✔
64

65
        # initialize attributes
66
        self.server = url_.scheme + '://' + url_.netloc + '/' + url_.path.split('/')[1]
1✔
67
        self.job, self.job_no, self.job_date  = self.get_job_info()
1✔
68
        file_info = self.get_file_info()
1✔
69
        self.file_name = file_info[0]
1✔
70
        self.file_info = file_info[1]
1✔
71
        self.target_board = file_info[2]
1✔
72
        self.artifact_info_type=file_info[3]
1✔
73
        self.payload_raw=self.get_payload_raw()
1✔
74
        payload_parsed=self.get_payload_parsed()
1✔
75
        if isinstance(payload_parsed, tuple):
1✔
76
            self.payload=payload_parsed[0]
1✔
77
            self.payload_param=payload_parsed[1]
1✔
78
        else:
79
            self.payload=payload_parsed
1✔
80
            self.payload_param=self.get_payload_param() 
1✔
81

UNCOV
82
    def show_info(self):
×
83
        return self.__dict__
×
84

UNCOV
85
    def get_job_info(self):
×
86
        '''returns jenkins project name, job no and job date'''
87
        if self.multilevel:
1✔
88
            url = urlparse(self.url)
1✔
89
            job=url.path.split('/')[3] + '/' + url.path.split('/')[5]
1✔
90
            job_no=url.path.split('/')[6]
1✔
91
            # TODO: get job date using jenkins api
92
            job_date=None
1✔
93
            return (job,job_no,job_date)
1✔
94

95
        raise Exception("Does not support non multilevel yet!")
×
96

UNCOV
97
    def get_file_info(self):
×
98
        '''returns file name, file info, target_board, artifact_info_type'''
UNCOV
99
        if self.multilevel:
×
UNCOV
100
            url = urlparse(self.url)
×
UNCOV
101
            file_name = url.path.split('/')[-1]
×
UNCOV
102
            file_info = file_name.split('_')
×
UNCOV
103
            target_board=file_info[0]
×
UNCOV
104
            artifact_info_type=file_info[1] + '_' + file_info[2]
×
UNCOV
105
            artifact_info_type = remove_suffix(artifact_info_type,".log")
×
UNCOV
106
            return (file_name, file_info, target_board, artifact_info_type)
×
107

108
        raise Exception("Does not support non multilevel yet!")
×
109

110

UNCOV
111
    def get_payload_raw(self):
×
112
        payload = []
1✔
113
        try:
1✔
114
            file_path = self.grabber.download_file(self.url, self.file_name)
1✔
115
            with open(file_path, "r") as f:
1✔
116
                payload = [l.strip() for l in f.readlines()]
1✔
117
        except Exception as ex:
×
118
            traceback.print_exc()
×
119
            print("Error Parsing File!")
×
120
        finally:
121
            os.remove(file_path)
1✔
122
        return payload
1✔
123

UNCOV
124
    def get_payload_parsed(self):
×
125
        payload = []
1✔
126
        for p in self.payload_raw:
1✔
127
            # try to extract timestamp from data
128
            x = re.search("\[.*(\d+\.\d*)\]\s(.*)", p)
1✔
129
            if x:
1✔
130
                payload.append((x.group(1),x.group(2)))
×
131
            else:
132
                x = re.search("(.*)", p)
1✔
133
                payload.append(x.group(1))
1✔
134
        return payload
1✔
135
    
UNCOV
136
    def get_payload_param(self):
×
137
        payload_param = list()
1✔
138
        for k in self.payload:
1✔
139
            payload_param.append("NA")
1✔
140
        return payload_param
1✔
141

UNCOV
142
class Dmesg(Parser):
×
143

UNCOV
144
    def __init__(self, url, grabber):
×
145
        super(Dmesg, self).__init__(url, grabber)
1✔
146

UNCOV
147
    def get_file_info(self):
×
148
        '''returns file name, file info, target_board, artifact_info_type'''
149
        if self.multilevel:
1✔
150
            url = urlparse(self.url)
1✔
151
            file_name = url.path.split('/')[-1]
1✔
152
            file_info = file_name.split('_')
1✔
153
            target_board=file_info[1]
1✔
154
            artifact_info_type=file_info[0]
1✔
155
            if len(file_info) == 3:
1✔
156
                artifact_info_type += '_' + file_info[2]
1✔
157
            artifact_info_type = remove_suffix(artifact_info_type,".log")
1✔
158
            return (file_name, file_info, target_board, artifact_info_type)
1✔
159

160
        raise Exception("Does not support non multilevel yet!")
×
161

UNCOV
162
class DmesgError(Dmesg):
×
163
    
UNCOV
164
    def __init__(self, url, grabber):
×
165
        super(DmesgError, self).__init__(url, grabber)
1✔
166

UNCOV
167
class DmesgWarning(Dmesg):
×
168
    
UNCOV
169
    def __init__(self, url, grabber):
×
170
        super(DmesgWarning, self).__init__(url, grabber)
1✔
171

UNCOV
172
class EnumeratedDevs(Parser):
×
173
    
UNCOV
174
    def __init__(self, url, grabber):
×
UNCOV
175
        super(EnumeratedDevs, self).__init__(url, grabber)
×
176

UNCOV
177
class MissingDevs(Parser):
×
178
    
UNCOV
179
    def __init__(self, url, grabber):
×
UNCOV
180
        super(MissingDevs, self).__init__(url, grabber)
×
181

UNCOV
182
class xmlParser(Parser):
×
UNCOV
183
    def __init__(self, url, grabber):
×
184
        super(xmlParser, self).__init__(url, grabber)
×
185
        
UNCOV
186
    def get_file_info(self):
×
187
        '''returns file name, file info, target_board, artifact_info_type'''
188
        if self.multilevel:
×
189
            url = urlparse(self.url)
×
190
            url_path = url.path.split('/')
×
191
            file_name = url_path[-1]
×
192
            parser_type = type(self).__name__
×
193
            x = [i for i, c in enumerate(parser_type) if c.isupper()]
×
194
            file_info = (parser_type[:x[1]]+'_'+parser_type[x[1]:]).lower()
×
195
            target_board = file_name.replace('_','-')
×
196
            target_board = remove_suffix(target_board,"-reports.xml")
×
197
            target_board = remove_suffix(target_board,"-HWTestResults.xml")
×
198
            artifact_info_type=file_info
×
199
            return (file_name, file_info, target_board, artifact_info_type)
×
200

201
        raise Exception("Does not support non multilevel yet!")
×
202
        
UNCOV
203
    def get_payload_raw(self):
×
204
        payload = []
×
205
        try:
×
206
            file_path = self.grabber.download_file(self.url, self.file_name)
×
207
            # Parser
208
            xml = JUnitXml.fromfile(file_path)
×
209
            resultType = getattr(junitparser, self.file_info.split("_")[1].capitalize())
×
210
            for suite in xml:
×
211
                for case in suite:
×
212
                    if case.result and type(case.result[0]) is resultType:
×
213
                        payload.append(case.name)
×
214
        except Exception as ex:
×
215
            traceback.print_exc()
×
216
            print("Error Parsing File!")
×
217
        finally:
218
            os.remove(file_path)
×
219
        return payload
×
220
    
UNCOV
221
    def get_payload_parsed(self):
×
222
        num_payload = len(self.payload_raw)
×
223
        procedure = list(range(num_payload))
×
224
        param = list(range(num_payload))
×
225
        for k, payload_str in enumerate(self.payload_raw):
×
226
            # remove trailing adi.xxxx device name
227
            payload_str = re.sub("-adi\.\w*", "", payload_str)
×
228
            # remove multiple dashes
229
            payload_str = re.sub("-+", "-", payload_str)
×
230
            # replace () from MATLAB xml with []
231
            payload_str = payload_str.replace("(","[").replace(")","]")
×
232
            procedure_param = payload_str.split("[")
×
233
            procedure[k] = procedure_param[0]
×
234
            if len(procedure_param) == 2:
×
235
                # remove path from profile filename
236
                if any(x in procedure[k] for x in ["profile_write", "write_profile"]):
×
237
                    param[k] = re.findall("(\w*\..*)]",procedure_param[1])[0]
×
238
                else:
239
                    param[k] = procedure_param[1][:-1]
×
240
            else:
241
                param[k] = "NA"
×
242
        payload = procedure
×
243
        payload_param = param
×
244
        return (payload, payload_param)
×
245

UNCOV
246
class PytestFailure(xmlParser):
×
UNCOV
247
    def __init__(self, url, grabber):
×
248
        super(PytestFailure, self).__init__(url, grabber)
×
UNCOV
249
class PytestSkipped(xmlParser):
×
UNCOV
250
    def __init__(self, url, grabber):
×
251
        super(PytestSkipped, self).__init__(url, grabber)
×
UNCOV
252
class PytestError(xmlParser,):
×
UNCOV
253
    def __init__(self, url, grabber):
×
254
        super(PytestError, self).__init__(url, grabber)
×
255

UNCOV
256
class MatlabFailure(xmlParser):
×
UNCOV
257
    def __init__(self, url, grabber):
×
258
        super(MatlabFailure, self).__init__(url, grabber)
×
UNCOV
259
class MatlabSkipped(xmlParser):
×
UNCOV
260
    def __init__(self, url, grabber):
×
261
        super(MatlabSkipped, self).__init__(url, grabber)
×
UNCOV
262
class MatlabError(xmlParser):
×
UNCOV
263
    def __init__(self, url, grabber):
×
264
        super(MatlabError, self).__init__(url, grabber)
×
265

UNCOV
266
class InfoTxt(Parser):
×
UNCOV
267
    def __init__(self, url, grabber):
×
268
        self.regex_patterns = [
1✔
269
            "(BRANCH):\s(.+)$",
270
            "(PR_ID):\s(.+)$",
271
            "(TIMESTAMP):\s(.+)$",
272
            "(DIRECTION):\s(.+)$",
273
            "(Triggered\sby):\s(.+)$",
274
            "(COMMIT\sSHA):\s(.+)$",
275
            "(COMMIT_DATE):\s(.+)$",
276
            "-\s([^:\s]+)$",
277
        ]
278
        super(InfoTxt, self).__init__(url, grabber)
1✔
279
        
280

UNCOV
281
    def get_file_info(self):
×
282
        '''returns file name, file info, target_board, artifact_info_type'''
283
        if self.multilevel:
1✔
284
            url = urlparse(self.url)
1✔
285
            file_name = url.path.split('/')[-1]
1✔
286
            file_info = "NA"
1✔
287
            target_board="NA"
1✔
288
            artifact_info_type = "info_txt"
1✔
289
            return (file_name, file_info, target_board, artifact_info_type)
1✔
290

291
        raise Exception("Does not support non multilevel yet!")
×
292

UNCOV
293
    def get_payload_raw(self):
×
294
        payload = []
1✔
295
        try:
1✔
296
            file_path = self.grabber.download_file(self.url, self.file_name)
1✔
297
            with open(file_path, "r") as f:
1✔
298
                for l in f.readlines():
1✔
299
                    found = False
1✔
300
                    for p in self.regex_patterns:
1✔
301
                        if re.search(p,l.strip()):
1✔
302
                            found=True
1✔
303
                    if found:
1✔
304
                        payload.append(l.strip())
1✔
305
        except Exception as ex:
×
306
            traceback.print_exc()
×
307
            print("Error Parsing File!")
×
308
        finally:
309
            os.remove(file_path)
1✔
310

311
        return payload
1✔
312
    
UNCOV
313
    def get_payload_parsed(self):
×
314
        payload = list()
1✔
315
        payload_param = list()
1✔
316
        for l in self.payload_raw:
1✔
317
            for p in self.regex_patterns:
1✔
318
                x = re.search(p,l)
1✔
319
                if x and len(x.groups())==1:
1✔
320
                    payload.append("Built projects")
1✔
321
                    payload_param.append(x.group(1))
1✔
322
                elif x and len(x.groups())==2:
1✔
323
                    payload.append(x.group(1))
1✔
324
                    payload_param.append(x.group(2))
1✔
325
        return (payload, payload_param)
1✔
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