liyujie
2025-08-28 786ff4f4ca2374bdd9177f2e24b503d43e7a3b93
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
#!/usr/bin/python
 
import datetime, time, unittest
 
import common
from autotest_lib.client.common_lib import utils
from autotest_lib.tko.parsers import version_1
 
 
class test_status_line(unittest.TestCase):
    """Tests for status lines."""
 
    statuses = ['GOOD', 'WARN', 'FAIL', 'ABORT']
 
 
    def test_handles_start(self):
        """Tests that START is handled properly."""
        line = version_1.status_line(0, 'START', '----', 'test',
                                     '', {})
        self.assertEquals(line.type, 'START')
        self.assertEquals(line.status, None)
 
 
    def test_handles_info(self):
        """Tests that INFO is handled properly."""
        line = version_1.status_line(0, 'INFO', '----', '----',
                                     '', {})
        self.assertEquals(line.type, 'INFO')
        self.assertEquals(line.status, None)
 
 
    def test_handles_status(self):
        """Tests that STATUS is handled properly."""
        for stat in self.statuses:
            line = version_1.status_line(0, stat, '----', 'test',
                                         '', {})
            self.assertEquals(line.type, 'STATUS')
            self.assertEquals(line.status, stat)
 
 
    def test_handles_endstatus(self):
        """Tests that END is handled properly."""
        for stat in self.statuses:
            line = version_1.status_line(0, 'END ' + stat, '----',
                                         'test', '', {})
            self.assertEquals(line.type, 'END')
            self.assertEquals(line.status, stat)
 
 
    def test_fails_on_bad_status(self):
        """Tests that an exception is raised on a bad status."""
        for stat in self.statuses:
            self.assertRaises(AssertionError,
                              version_1.status_line, 0,
                              'BAD ' + stat, '----', 'test',
                              '', {})
 
 
    def test_saves_all_fields(self):
        """Tests that all fields are saved."""
        line = version_1.status_line(5, 'GOOD', 'subdir_name',
                                     'test_name', 'my reason here',
                                     {'key1': 'value',
                                      'key2': 'another value',
                                      'key3': 'value3'})
        self.assertEquals(line.indent, 5)
        self.assertEquals(line.status, 'GOOD')
        self.assertEquals(line.subdir, 'subdir_name')
        self.assertEquals(line.testname, 'test_name')
        self.assertEquals(line.reason, 'my reason here')
        self.assertEquals(line.optional_fields,
                          {'key1': 'value', 'key2': 'another value',
                           'key3': 'value3'})
 
 
    def test_parses_blank_subdir(self):
        """Tests that a blank subdirectory is parsed properly."""
        line = version_1.status_line(0, 'GOOD', '----', 'test',
                                     '', {})
        self.assertEquals(line.subdir, None)
 
 
    def test_parses_blank_testname(self):
        """Tests that a blank test name is parsed properly."""
        line = version_1.status_line(0, 'GOOD', 'subdir', '----',
                                     '', {})
        self.assertEquals(line.testname, None)
 
 
    def test_parse_line_smoketest(self):
        """Runs a parse line smoke test."""
        input_data = ('\t\t\tGOOD\t----\t----\t'
                      'field1=val1\tfield2=val2\tTest Passed')
        line = version_1.status_line.parse_line(input_data)
        self.assertEquals(line.indent, 3)
        self.assertEquals(line.type, 'STATUS')
        self.assertEquals(line.status, 'GOOD')
        self.assertEquals(line.subdir, None)
        self.assertEquals(line.testname, None)
        self.assertEquals(line.reason, 'Test Passed')
        self.assertEquals(line.optional_fields,
                          {'field1': 'val1', 'field2': 'val2'})
 
    def test_parse_line_handles_newline(self):
        """Tests that newlines are handled properly."""
        input_data = ('\t\tGOOD\t----\t----\t'
                      'field1=val1\tfield2=val2\tNo newline here!')
        for suffix in ('', '\n'):
            line = version_1.status_line.parse_line(input_data +
                                                    suffix)
            self.assertEquals(line.indent, 2)
            self.assertEquals(line.type, 'STATUS')
            self.assertEquals(line.status, 'GOOD')
            self.assertEquals(line.subdir, None)
            self.assertEquals(line.testname, None)
            self.assertEquals(line.reason, 'No newline here!')
            self.assertEquals(line.optional_fields,
                              {'field1': 'val1',
                               'field2': 'val2'})
 
 
    def test_parse_line_fails_on_untabbed_lines(self):
        """Tests that untabbed lines do not parse."""
        input_data = '   GOOD\trandom\tfields\tof text'
        line = version_1.status_line.parse_line(input_data)
        self.assertEquals(line, None)
        line = version_1.status_line.parse_line(input_data.lstrip())
        self.assertEquals(line.indent, 0)
        self.assertEquals(line.type, 'STATUS')
        self.assertEquals(line.status, 'GOOD')
        self.assertEquals(line.subdir, 'random')
        self.assertEquals(line.testname, 'fields')
        self.assertEquals(line.reason, 'of text')
        self.assertEquals(line.optional_fields, {})
 
 
    def test_parse_line_fails_on_incomplete_lines(self):
        """Tests that incomplete lines do not parse."""
        input_data = '\t\tGOOD\tfield\tsecond field'
        complete_data = input_data + '\tneeded last field'
        line = version_1.status_line.parse_line(input_data)
        self.assertEquals(line, None)
        line = version_1.status_line.parse_line(complete_data)
        self.assertEquals(line.indent, 2)
        self.assertEquals(line.type, 'STATUS')
        self.assertEquals(line.status, 'GOOD')
        self.assertEquals(line.subdir, 'field')
        self.assertEquals(line.testname, 'second field')
        self.assertEquals(line.reason, 'needed last field')
        self.assertEquals(line.optional_fields, {})
 
 
    def test_good_reboot_passes_success_test(self):
        """Tests good reboot statuses."""
        line = version_1.status_line(0, 'NOSTATUS', None, 'reboot',
                                     'reboot success', {})
        self.assertEquals(line.is_successful_reboot('GOOD'), True)
        self.assertEquals(line.is_successful_reboot('WARN'), True)
 
 
    def test_bad_reboot_passes_success_test(self):
        """Tests bad reboot statuses."""
        line = version_1.status_line(0, 'NOSTATUS', None, 'reboot',
                                     'reboot success', {})
        self.assertEquals(line.is_successful_reboot('FAIL'), False)
        self.assertEquals(line.is_successful_reboot('ABORT'), False)
 
 
    def test_get_kernel_returns_kernel_plus_patches(self):
        """Tests that get_kernel returns the appropriate info."""
        line = version_1.status_line(0, 'GOOD', 'subdir', 'testname',
                                     'reason text',
                                     {'kernel': '2.6.24-rc40',
                                      'patch0': 'first_patch 0 0',
                                      'patch1': 'another_patch 0 0'})
        kern = line.get_kernel()
        kernel_hash = utils.hash('md5', '2.6.24-rc40,0,0').hexdigest()
        self.assertEquals(kern.base, '2.6.24-rc40')
        self.assertEquals(kern.patches[0].spec, 'first_patch')
        self.assertEquals(kern.patches[1].spec, 'another_patch')
        self.assertEquals(len(kern.patches), 2)
        self.assertEquals(kern.kernel_hash, kernel_hash)
 
 
    def test_get_kernel_ignores_out_of_sequence_patches(self):
        """Tests that get_kernel ignores patches that are out of sequence."""
        line = version_1.status_line(0, 'GOOD', 'subdir', 'testname',
                                     'reason text',
                                     {'kernel': '2.6.24-rc40',
                                      'patch0': 'first_patch 0 0',
                                      'patch2': 'another_patch 0 0'})
        kern = line.get_kernel()
        kernel_hash = utils.hash('md5', '2.6.24-rc40,0').hexdigest()
        self.assertEquals(kern.base, '2.6.24-rc40')
        self.assertEquals(kern.patches[0].spec, 'first_patch')
        self.assertEquals(len(kern.patches), 1)
        self.assertEquals(kern.kernel_hash, kernel_hash)
 
 
    def test_get_kernel_returns_unknown_with_no_kernel(self):
        """Tests that a missing kernel is handled properly."""
        line = version_1.status_line(0, 'GOOD', 'subdir', 'testname',
                                     'reason text',
                                     {'patch0': 'first_patch 0 0',
                                      'patch2': 'another_patch 0 0'})
        kern = line.get_kernel()
        self.assertEquals(kern.base, 'UNKNOWN')
        self.assertEquals(kern.patches, [])
        self.assertEquals(kern.kernel_hash, 'UNKNOWN')
 
 
    def test_get_timestamp_returns_timestamp_field(self):
        """Tests that get_timestamp returns the expected info."""
        timestamp = datetime.datetime(1970, 1, 1, 4, 30)
        timestamp -= datetime.timedelta(seconds=time.timezone)
        line = version_1.status_line(0, 'GOOD', 'subdir', 'testname',
                                     'reason text',
                                     {'timestamp': '16200'})
        self.assertEquals(timestamp, line.get_timestamp())
 
 
    def test_get_timestamp_returns_none_on_missing_field(self):
        """Tests that get_timestamp returns None if no timestamp exists."""
        line = version_1.status_line(0, 'GOOD', 'subdir', 'testname',
                                     'reason text', {})
        self.assertEquals(None, line.get_timestamp())
 
 
class iteration_parse_line_into_dicts(unittest.TestCase):
    """Tests for parsing iteration keyvals into dictionaries."""
 
    def parse_line(self, line):
        """
        Invokes parse_line_into_dicts with two empty dictionaries.
 
        @param line: The line to parse.
 
        @return A 2-tuple representing the filled-in attr and perf dictionaries,
            respectively.
 
        """
        attr, perf = {}, {}
        version_1.iteration.parse_line_into_dicts(line, attr, perf)
        return attr, perf
 
 
    def test_perf_entry(self):
        """Tests a basic perf keyval line."""
        result = self.parse_line('perf-val{perf}=-173')
        self.assertEqual(({}, {'perf-val': -173}), result)
 
 
    def test_attr_entry(self):
        """Tests a basic attr keyval line."""
        result = self.parse_line('attr-val{attr}=173')
        self.assertEqual(({'attr-val': '173'}, {}), result)
 
 
    def test_untagged_is_perf(self):
        """Tests that an untagged keyval is considered to be perf by default."""
        result = self.parse_line('untagged=-678.5e5')
        self.assertEqual(({}, {'untagged': -678.5e5}), result)
 
 
    def test_invalid_tag_ignored(self):
        """Tests that invalid tags are ignored."""
        result = self.parse_line('bad-tag{invalid}=56')
        self.assertEqual(({}, {}), result)
 
 
    def test_non_numeric_perf_ignored(self):
        """Tests that non-numeric perf values are ignored."""
        result = self.parse_line('perf-val{perf}=FooBar')
        self.assertEqual(({}, {}), result)
 
 
    def test_non_numeric_untagged_ignored(self):
        """Tests that non-numeric untagged keyvals are ignored."""
        result = self.parse_line('untagged=FooBar')
        self.assertEqual(({}, {}), result)
 
 
class perf_value_iteration_parse_line_into_dict(unittest.TestCase):
    """Tests for parsing perf value iterations into a dictionary."""
 
    def parse_line(self, line):
        """
        Invokes parse_line_into_dict with a line to parse.
 
        @param line: The string line to parse.
 
        @return A dictionary containing the information parsed from the line.
 
        """
        return version_1.perf_value_iteration.parse_line_into_dict(line)
 
    def test_invalid_json(self):
        """Tests that a non-JSON line is handled properly."""
        result = self.parse_line('{"invalid_json" "string"}')
        self.assertEqual(result, {})
 
    def test_single_value_int(self):
        """Tests that a single integer value is parsed properly."""
        result = self.parse_line('{"value": 7}')
        self.assertEqual(result, {'value': 7, 'stddev': 0})
 
    def test_single_value_float(self):
        """Tests that a single float value is parsed properly."""
        result = self.parse_line('{"value": 1.298}')
        self.assertEqual(result, {'value': 1.298, 'stddev': 0})
 
    def test_value_list_int(self):
        """Tests that an integer list is parsed properly."""
        result = self.parse_line('{"value": [10, 20, 30]}')
        self.assertEqual(result, {'value': 20.0, 'stddev': 10.0})
 
    def test_value_list_float(self):
        """Tests that a float list is parsed properly."""
        result = self.parse_line('{"value": [2.0, 3.0, 4.0]}')
        self.assertEqual(result, {'value': 3.0, 'stddev': 1.0})
 
 
class DummyAbortTestCase(unittest.TestCase):
    """Tests for the make_dummy_abort function."""
 
    def setUp(self):
        self.indent = 3
        self.subdir = "subdir"
        self.testname = 'testname'
        self.timestamp = 1220565792
        self.reason = 'Job aborted unexpectedly'
 
 
    def test_make_dummy_abort_with_timestamp(self):
        """Tests make_dummy_abort with a timestamp specified."""
        abort = version_1.parser.make_dummy_abort(
            self.indent, self.subdir, self.testname, self.timestamp,
            self.reason)
        self.assertEquals(
            abort, '%sEND ABORT\t%s\t%s\ttimestamp=%d\t%s' % (
            '\t' * self.indent, self.subdir, self.testname, self.timestamp,
            self.reason))
 
    def test_make_dummy_abort_with_no_subdir(self):
        """Tests make_dummy_abort with no subdir specified."""
        abort= version_1.parser.make_dummy_abort(
            self.indent, None, self.testname, self.timestamp, self.reason)
        self.assertEquals(
            abort, '%sEND ABORT\t----\t%s\ttimestamp=%d\t%s' % (
            '\t' * self.indent, self.testname, self.timestamp, self.reason))
 
    def test_make_dummy_abort_with_no_testname(self):
        """Tests make_dummy_abort with no testname specified."""
        abort= version_1.parser.make_dummy_abort(
        self.indent, self.subdir, None, self.timestamp, self.reason)
        self.assertEquals(
            abort, '%sEND ABORT\t%s\t----\ttimestamp=%d\t%s' % (
            '\t' * self.indent, self.subdir, self.timestamp, self.reason))
 
    def test_make_dummy_abort_no_timestamp(self):
        """Tests make_dummy_abort with no timestamp specified."""
        abort = version_1.parser.make_dummy_abort(
            self.indent, self.subdir, self.testname, None, self.reason)
        self.assertEquals(
            abort, '%sEND ABORT\t%s\t%s\t%s' % (
            '\t' * self.indent, self.subdir, self.testname, self.reason))
 
 
if __name__ == '__main__':
    unittest.main()