Prathmesh Prabhu | 84a8595 | 2017-02-03 17:05:24 -0800 | [diff] [blame] | 1 | import json |
| 2 | import math |
| 3 | import os |
| 4 | import re |
jadmanski | cc54917 | 2008-05-21 18:11:51 +0000 | [diff] [blame] | 5 | |
Prathmesh Prabhu | 84a8595 | 2017-02-03 17:05:24 -0800 | [diff] [blame] | 6 | import common |
| 7 | from autotest_lib.tko import models |
| 8 | from autotest_lib.tko import status_lib |
| 9 | from autotest_lib.tko import utils as tko_utils |
| 10 | from autotest_lib.tko.parsers import base |
| 11 | from autotest_lib.tko.parsers import version_0 |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 12 | |
| 13 | |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 14 | class job(version_0.job): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 15 | """Represents a job.""" |
| 16 | |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 17 | def exit_status(self): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 18 | """Returns the string exit status of this job.""" |
| 19 | |
| 20 | # Find the .autoserv_execute path. |
jadmanski | 165fe4c | 2009-01-07 17:06:00 +0000 | [diff] [blame] | 21 | top_dir = tko_utils.find_toplevel_job_dir(self.dir) |
| 22 | if not top_dir: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 23 | return 'ABORT' |
| 24 | execute_path = os.path.join(top_dir, '.autoserv_execute') |
jadmanski | 165fe4c | 2009-01-07 17:06:00 +0000 | [diff] [blame] | 25 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 26 | # If for some reason we can't read the status code, assume disaster. |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 27 | if not os.path.exists(execute_path): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 28 | return 'ABORT' |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 29 | lines = open(execute_path).readlines() |
| 30 | if len(lines) < 2: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 31 | return 'ABORT' |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 32 | try: |
| 33 | status_code = int(lines[1]) |
| 34 | except ValueError: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 35 | return 'ABORT' |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 36 | |
| 37 | if not os.WIFEXITED(status_code): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 38 | # Looks like a signal - an ABORT. |
| 39 | return 'ABORT' |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 40 | elif os.WEXITSTATUS(status_code) != 0: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 41 | # Looks like a non-zero exit - a failure. |
| 42 | return 'FAIL' |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 43 | else: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 44 | # Looks like exit code == 0. |
| 45 | return 'GOOD' |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 46 | |
| 47 | |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 48 | class kernel(models.kernel): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 49 | """Represents a kernel.""" |
| 50 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 51 | def __init__(self, base, patches): |
| 52 | if base: |
| 53 | patches = [patch(*p.split()) for p in patches] |
| 54 | hashes = [p.hash for p in patches] |
| 55 | kernel_hash = self.compute_hash(base, hashes) |
| 56 | else: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 57 | base = 'UNKNOWN' |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 58 | patches = [] |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 59 | kernel_hash = 'UNKNOWN' |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 60 | super(kernel, self).__init__(base, patches, kernel_hash) |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 61 | |
| 62 | |
jadmanski | cc54917 | 2008-05-21 18:11:51 +0000 | [diff] [blame] | 63 | class test(models.test): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 64 | """Represents a test.""" |
| 65 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 66 | @staticmethod |
| 67 | def load_iterations(keyval_path): |
| 68 | return iteration.load_from_keyval(keyval_path) |
jadmanski | cc54917 | 2008-05-21 18:11:51 +0000 | [diff] [blame] | 69 | |
| 70 | |
Dennis Jeffrey | 05eb4b1 | 2013-07-17 11:11:52 -0700 | [diff] [blame] | 71 | @staticmethod |
| 72 | def load_perf_values(perf_values_file): |
| 73 | return perf_value_iteration.load_from_perf_values_file( |
| 74 | perf_values_file) |
| 75 | |
| 76 | |
jadmanski | cc54917 | 2008-05-21 18:11:51 +0000 | [diff] [blame] | 77 | class iteration(models.iteration): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 78 | """Represents an iteration.""" |
| 79 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 80 | @staticmethod |
| 81 | def parse_line_into_dicts(line, attr_dict, perf_dict): |
jadmanski | d2e0f0c | 2009-07-20 17:52:57 +0000 | [diff] [blame] | 82 | key, val_type, value = "", "", "" |
| 83 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 84 | # Figure out what the key, value and keyval type are. |
| 85 | typed_match = re.search('^([^=]*)\{(\w*)\}=(.*)$', line) |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 86 | if typed_match: |
| 87 | key, val_type, value = typed_match.groups() |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 88 | else: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 89 | # Old-fashioned untyped match, assume perf. |
| 90 | untyped_match = re.search('^([^=]*)=(.*)$', line) |
jadmanski | d2e0f0c | 2009-07-20 17:52:57 +0000 | [diff] [blame] | 91 | if untyped_match: |
| 92 | key, value = untyped_match.groups() |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 93 | val_type = 'perf' |
jadmanski | d2e0f0c | 2009-07-20 17:52:57 +0000 | [diff] [blame] | 94 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 95 | # Parse the actual value into a dict. |
Eric Li | 861b2d5 | 2011-02-04 14:50:35 -0800 | [diff] [blame] | 96 | try: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 97 | if val_type == 'attr': |
Eric Li | 861b2d5 | 2011-02-04 14:50:35 -0800 | [diff] [blame] | 98 | attr_dict[key] = value |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 99 | elif val_type == 'perf': |
Alex Khouderchah | b5f75eb | 2018-07-23 13:40:02 -0700 | [diff] [blame] | 100 | # first check if value is in the form of 'mean+-deviation' |
| 101 | if isinstance(value, str): |
| 102 | r = re.compile('(\d+.?\d*)\+-(\d+.?\d*)') |
| 103 | match = r.match(value) |
| 104 | if match: |
| 105 | perf_dict[key] = float(match.group(1)) |
| 106 | perf_dict['%s_dev' % key] = float(match.group(2)) |
| 107 | return |
| 108 | # otherwise try to interpret as a regular float |
Eric Li | 861b2d5 | 2011-02-04 14:50:35 -0800 | [diff] [blame] | 109 | perf_dict[key] = float(value) |
| 110 | else: |
| 111 | raise ValueError |
| 112 | except ValueError: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 113 | msg = ('WARNING: line "%s" found in test ' |
| 114 | 'iteration keyval could not be parsed') |
jadmanski | d2e0f0c | 2009-07-20 17:52:57 +0000 | [diff] [blame] | 115 | msg %= line |
| 116 | tko_utils.dprint(msg) |
jadmanski | cc54917 | 2008-05-21 18:11:51 +0000 | [diff] [blame] | 117 | |
| 118 | |
Dennis Jeffrey | 05eb4b1 | 2013-07-17 11:11:52 -0700 | [diff] [blame] | 119 | class perf_value_iteration(models.perf_value_iteration): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 120 | """Represents a perf value iteration.""" |
| 121 | |
Dennis Jeffrey | 05eb4b1 | 2013-07-17 11:11:52 -0700 | [diff] [blame] | 122 | @staticmethod |
| 123 | def parse_line_into_dict(line): |
| 124 | """ |
| 125 | Parse a perf measurement text line into a dictionary. |
| 126 | |
| 127 | The line is assumed to be a JSON-formatted string containing key/value |
| 128 | pairs, where each pair represents a piece of information associated |
| 129 | with a measured perf metric: |
| 130 | |
| 131 | 'description': a string description for the perf metric. |
| 132 | 'value': a numeric value, or list of numeric values. |
| 133 | 'units': the string units associated with the perf metric. |
| 134 | 'higher_is_better': a boolean whether a higher value is considered |
| 135 | better. If False, a lower value is considered better. |
Fang Deng | 7f24f0b | 2013-11-12 11:22:16 -0800 | [diff] [blame] | 136 | 'graph': a string indicating the name of the perf dashboard graph |
| 137 | on which the perf data will be displayed. |
Dennis Jeffrey | 05eb4b1 | 2013-07-17 11:11:52 -0700 | [diff] [blame] | 138 | |
| 139 | The resulting dictionary will also have a standard deviation key/value |
| 140 | pair, 'stddev'. If the perf measurement value is a list of values |
| 141 | instead of a single value, then the average and standard deviation of |
| 142 | the list of values is computed and stored. If a single value, the |
| 143 | value itself is used, and is associated with a standard deviation of 0. |
| 144 | |
| 145 | @param line: A string line of JSON text from a perf measurements output |
| 146 | file. |
| 147 | |
| 148 | @return A dictionary containing the parsed perf measurement information |
| 149 | along with a computed standard deviation value (key 'stddev'), or |
| 150 | an empty dictionary if the inputted line cannot be parsed. |
| 151 | """ |
Dennis Jeffrey | 05eb4b1 | 2013-07-17 11:11:52 -0700 | [diff] [blame] | 152 | try: |
| 153 | perf_dict = json.loads(line) |
| 154 | except ValueError: |
| 155 | msg = 'Could not parse perf measurements line as json: "%s"' % line |
| 156 | tko_utils.dprint(msg) |
| 157 | return {} |
| 158 | |
| 159 | def mean_and_standard_deviation(data): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 160 | """ |
| 161 | Computes the mean and standard deviation of a list of numbers. |
| 162 | |
| 163 | @param data: A list of numbers. |
| 164 | |
| 165 | @return A 2-tuple (mean, standard_deviation) computed from the list |
| 166 | of numbers. |
| 167 | |
| 168 | """ |
Dennis Jeffrey | 05eb4b1 | 2013-07-17 11:11:52 -0700 | [diff] [blame] | 169 | n = len(data) |
| 170 | if n == 0: |
| 171 | return 0.0, 0.0 |
| 172 | if n == 1: |
| 173 | return data[0], 0.0 |
| 174 | mean = float(sum(data)) / n |
| 175 | # Divide by n-1 to compute "sample standard deviation". |
| 176 | variance = sum([(elem - mean) ** 2 for elem in data]) / (n - 1) |
| 177 | return mean, math.sqrt(variance) |
| 178 | |
| 179 | value = perf_dict['value'] |
| 180 | perf_dict['stddev'] = 0.0 |
| 181 | if isinstance(value, list): |
| 182 | value, stddev = mean_and_standard_deviation(map(float, value)) |
| 183 | perf_dict['value'] = value |
| 184 | perf_dict['stddev'] = stddev |
| 185 | |
| 186 | return perf_dict |
| 187 | |
| 188 | |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 189 | class status_line(version_0.status_line): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 190 | """Represents a status line.""" |
| 191 | |
jadmanski | 807490c | 2008-09-15 19:15:02 +0000 | [diff] [blame] | 192 | def __init__(self, indent, status, subdir, testname, reason, |
| 193 | optional_fields): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 194 | # Handle INFO fields. |
| 195 | if status == 'INFO': |
| 196 | self.type = 'INFO' |
jadmanski | 807490c | 2008-09-15 19:15:02 +0000 | [diff] [blame] | 197 | self.indent = indent |
| 198 | self.status = self.subdir = self.testname = self.reason = None |
| 199 | self.optional_fields = optional_fields |
| 200 | else: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 201 | # Everything else is backwards compatible. |
jadmanski | 807490c | 2008-09-15 19:15:02 +0000 | [diff] [blame] | 202 | super(status_line, self).__init__(indent, status, subdir, |
| 203 | testname, reason, |
| 204 | optional_fields) |
| 205 | |
| 206 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 207 | def is_successful_reboot(self, current_status): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 208 | """ |
| 209 | Checks whether the status represents a successful reboot. |
| 210 | |
| 211 | @param current_status: A string representing the current status. |
| 212 | |
| 213 | @return True, if the status represents a successful reboot, or False |
| 214 | if not. |
| 215 | |
| 216 | """ |
| 217 | # Make sure this is a reboot line. |
| 218 | if self.testname != 'reboot': |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 219 | return False |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 220 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 221 | # Make sure this was not a failure. |
| 222 | if status_lib.is_worse_than_or_equal_to(current_status, 'FAIL'): |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 223 | return False |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 224 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 225 | # It must have been a successful reboot. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 226 | return True |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 227 | |
| 228 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 229 | def get_kernel(self): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 230 | # Get the base kernel version. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 231 | fields = self.optional_fields |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 232 | base = re.sub('-autotest$', '', fields.get('kernel', '')) |
| 233 | # Get a list of patches. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 234 | patches = [] |
| 235 | patch_index = 0 |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 236 | while ('patch%d' % patch_index) in fields: |
| 237 | patches.append(fields['patch%d' % patch_index]) |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 238 | patch_index += 1 |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 239 | # Create a new kernel instance. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 240 | return kernel(base, patches) |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 241 | |
| 242 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 243 | def get_timestamp(self): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 244 | return tko_utils.get_timestamp(self.optional_fields, 'timestamp') |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 245 | |
| 246 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 247 | # The default implementations from version 0 will do for now. |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 248 | patch = version_0.patch |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 249 | |
| 250 | |
| 251 | class parser(base.parser): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 252 | """Represents a parser.""" |
| 253 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 254 | @staticmethod |
| 255 | def make_job(dir): |
| 256 | return job(dir) |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 257 | |
| 258 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 259 | @staticmethod |
mbligh | b22c21f | 2008-11-27 00:40:38 +0000 | [diff] [blame] | 260 | def make_dummy_abort(indent, subdir, testname, timestamp, reason): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 261 | """ |
| 262 | Creates an abort string. |
| 263 | |
| 264 | @param indent: The number of indentation levels for the string. |
| 265 | @param subdir: The subdirectory name. |
| 266 | @param testname: The test name. |
| 267 | @param timestamp: The timestamp value. |
| 268 | @param reason: The reason string. |
| 269 | |
| 270 | @return A string describing the abort. |
| 271 | |
| 272 | """ |
| 273 | indent = '\t' * indent |
jadmanski | fd3ba2b | 2008-07-28 19:30:54 +0000 | [diff] [blame] | 274 | if not subdir: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 275 | subdir = '----' |
jadmanski | fd3ba2b | 2008-07-28 19:30:54 +0000 | [diff] [blame] | 276 | if not testname: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 277 | testname = '----' |
mbligh | b22c21f | 2008-11-27 00:40:38 +0000 | [diff] [blame] | 278 | |
| 279 | # There is no guarantee that this will be set. |
| 280 | timestamp_field = '' |
| 281 | if timestamp: |
| 282 | timestamp_field = '\ttimestamp=%s' % timestamp |
| 283 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 284 | msg = indent + 'END ABORT\t%s\t%s%s\t%s' |
mbligh | b22c21f | 2008-11-27 00:40:38 +0000 | [diff] [blame] | 285 | return msg % (subdir, testname, timestamp_field, reason) |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 286 | |
| 287 | |
jadmanski | b69f250 | 2008-08-27 19:49:30 +0000 | [diff] [blame] | 288 | @staticmethod |
mbligh | b22c21f | 2008-11-27 00:40:38 +0000 | [diff] [blame] | 289 | def put_back_line_and_abort( |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 290 | line_buffer, line, indent, subdir, testname, timestamp, reason): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 291 | """ |
| 292 | Appends a line to the line buffer and aborts. |
| 293 | |
| 294 | @param line_buffer: A line_buffer object. |
| 295 | @param line: A line to append to the line buffer. |
| 296 | @param indent: The number of indentation levels. |
| 297 | @param subdir: The subdirectory name. |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 298 | @param testname: The test name. |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 299 | @param timestamp: The timestamp value. |
| 300 | @param reason: The reason string. |
| 301 | |
| 302 | """ |
Luigi Semenzato | e706481 | 2017-02-03 14:47:59 -0800 | [diff] [blame] | 303 | tko_utils.dprint('Unexpected indent: aborting log parse') |
jadmanski | b69f250 | 2008-08-27 19:49:30 +0000 | [diff] [blame] | 304 | line_buffer.put_back(line) |
mbligh | b22c21f | 2008-11-27 00:40:38 +0000 | [diff] [blame] | 305 | abort = parser.make_dummy_abort( |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 306 | indent, subdir, testname, timestamp, reason) |
jadmanski | b69f250 | 2008-08-27 19:49:30 +0000 | [diff] [blame] | 307 | line_buffer.put_back(abort) |
| 308 | |
| 309 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 310 | def state_iterator(self, buffer): |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 311 | """ |
| 312 | Yields a list of tests out of the buffer. |
| 313 | |
| 314 | @param buffer: a buffer object |
| 315 | |
| 316 | """ |
jadmanski | fd3ba2b | 2008-07-28 19:30:54 +0000 | [diff] [blame] | 317 | line = None |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 318 | new_tests = [] |
jadmanski | ba1fa66 | 2008-07-11 21:18:30 +0000 | [diff] [blame] | 319 | job_count, boot_count = 0, 0 |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 320 | min_stack_size = 0 |
| 321 | stack = status_lib.status_stack() |
| 322 | current_kernel = kernel("", []) # UNKNOWN |
jadmanski | c69138f | 2008-12-17 15:44:22 +0000 | [diff] [blame] | 323 | current_status = status_lib.statuses[-1] |
| 324 | current_reason = None |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 325 | started_time_stack = [None] |
| 326 | subdir_stack = [None] |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 327 | testname_stack = [None] |
jadmanski | 74eebf3 | 2008-07-15 20:04:42 +0000 | [diff] [blame] | 328 | running_test = None |
jadmanski | aaac45e | 2009-05-06 20:25:46 +0000 | [diff] [blame] | 329 | running_reasons = set() |
Luigi Semenzato | e706481 | 2017-02-03 14:47:59 -0800 | [diff] [blame] | 330 | ignored_lines = [] |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 331 | yield [] # We're ready to start running. |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 332 | |
Luigi Semenzato | 9aa4a03 | 2017-02-17 08:52:40 -0800 | [diff] [blame] | 333 | def print_ignored_lines(): |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 334 | """ |
| 335 | Prints the ignored_lines using tko_utils.dprint method. |
| 336 | """ |
Luigi Semenzato | e706481 | 2017-02-03 14:47:59 -0800 | [diff] [blame] | 337 | tko_utils.dprint('The following lines were ignored:') |
| 338 | for line in ignored_lines: |
| 339 | tko_utils.dprint(line) |
| 340 | tko_utils.dprint('---------------------------------') |
Luigi Semenzato | e706481 | 2017-02-03 14:47:59 -0800 | [diff] [blame] | 341 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 342 | # Create a RUNNING SERVER_JOB entry to represent the entire test. |
| 343 | running_job = test.parse_partial_test(self.job, '----', 'SERVER_JOB', |
| 344 | '', current_kernel, |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 345 | self.job.started_time) |
| 346 | new_tests.append(running_job) |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 347 | |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 348 | while True: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 349 | # Are we finished with parsing? |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 350 | if buffer.size() == 0 and self.finished: |
Luigi Semenzato | e706481 | 2017-02-03 14:47:59 -0800 | [diff] [blame] | 351 | if ignored_lines: |
Luigi Semenzato | 9aa4a03 | 2017-02-17 08:52:40 -0800 | [diff] [blame] | 352 | print_ignored_lines() |
| 353 | ignored_lines = [] |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 354 | if stack.size() == 0: |
| 355 | break |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 356 | # We have status lines left on the stack; |
| 357 | # we need to implicitly abort them first. |
jadmanski | fd3ba2b | 2008-07-28 19:30:54 +0000 | [diff] [blame] | 358 | tko_utils.dprint('\nUnexpected end of job, aborting') |
| 359 | abort_subdir_stack = list(subdir_stack) |
jadmanski | f7fa2cc | 2008-10-01 14:13:23 +0000 | [diff] [blame] | 360 | if self.job.aborted_by: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 361 | reason = 'Job aborted by %s' % self.job.aborted_by |
jadmanski | f7fa2cc | 2008-10-01 14:13:23 +0000 | [diff] [blame] | 362 | reason += self.job.aborted_on.strftime( |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 363 | ' at %b %d %H:%M:%S') |
jadmanski | f7fa2cc | 2008-10-01 14:13:23 +0000 | [diff] [blame] | 364 | else: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 365 | reason = 'Job aborted unexpectedly' |
mbligh | b22c21f | 2008-11-27 00:40:38 +0000 | [diff] [blame] | 366 | |
| 367 | timestamp = line.optional_fields.get('timestamp') |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 368 | for i in reversed(xrange(stack.size())): |
jadmanski | fd3ba2b | 2008-07-28 19:30:54 +0000 | [diff] [blame] | 369 | if abort_subdir_stack: |
| 370 | subdir = abort_subdir_stack.pop() |
| 371 | else: |
| 372 | subdir = None |
mbligh | b22c21f | 2008-11-27 00:40:38 +0000 | [diff] [blame] | 373 | abort = self.make_dummy_abort( |
| 374 | i, subdir, subdir, timestamp, reason) |
jadmanski | fd3ba2b | 2008-07-28 19:30:54 +0000 | [diff] [blame] | 375 | buffer.put(abort) |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 376 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 377 | # Stop processing once the buffer is empty. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 378 | if buffer.size() == 0: |
| 379 | yield new_tests |
| 380 | new_tests = [] |
| 381 | continue |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 382 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 383 | # Reinitialize the per-iteration state. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 384 | started_time = None |
| 385 | finished_time = None |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 386 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 387 | # Get the next line. |
mbligh | 51ee7c7 | 2008-11-24 17:10:14 +0000 | [diff] [blame] | 388 | raw_line = status_lib.clean_raw_line(buffer.get()) |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 389 | line = status_line.parse_line(raw_line) |
| 390 | if line is None: |
Luigi Semenzato | e706481 | 2017-02-03 14:47:59 -0800 | [diff] [blame] | 391 | ignored_lines.append(raw_line) |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 392 | continue |
Luigi Semenzato | e706481 | 2017-02-03 14:47:59 -0800 | [diff] [blame] | 393 | elif ignored_lines: |
Luigi Semenzato | 9aa4a03 | 2017-02-17 08:52:40 -0800 | [diff] [blame] | 394 | print_ignored_lines() |
| 395 | ignored_lines = [] |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 396 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 397 | # Do an initial sanity check of the indentation. |
jadmanski | b82cb14 | 2009-02-04 18:33:08 +0000 | [diff] [blame] | 398 | expected_indent = stack.size() |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 399 | if line.type == 'END': |
jadmanski | b82cb14 | 2009-02-04 18:33:08 +0000 | [diff] [blame] | 400 | expected_indent -= 1 |
| 401 | if line.indent < expected_indent: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 402 | # ABORT the current level if indentation was unexpectedly low. |
jadmanski | b82cb14 | 2009-02-04 18:33:08 +0000 | [diff] [blame] | 403 | self.put_back_line_and_abort( |
| 404 | buffer, raw_line, stack.size() - 1, subdir_stack[-1], |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 405 | testname_stack[-1], line.optional_fields.get('timestamp'), |
| 406 | line.reason) |
jadmanski | b82cb14 | 2009-02-04 18:33:08 +0000 | [diff] [blame] | 407 | continue |
| 408 | elif line.indent > expected_indent: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 409 | # Ignore the log if the indent was unexpectedly high. |
Luigi Semenzato | e706481 | 2017-02-03 14:47:59 -0800 | [diff] [blame] | 410 | tko_utils.dprint('ignoring line because of extra indentation') |
jadmanski | b82cb14 | 2009-02-04 18:33:08 +0000 | [diff] [blame] | 411 | continue |
| 412 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 413 | # Initial line processing. |
| 414 | if line.type == 'START': |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 415 | stack.start() |
jadmanski | 74eebf3 | 2008-07-15 20:04:42 +0000 | [diff] [blame] | 416 | started_time = line.get_timestamp() |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 417 | testname = None |
jadmanski | 717bb99 | 2008-10-08 14:29:23 +0000 | [diff] [blame] | 418 | if (line.testname is None and line.subdir is None |
| 419 | and not running_test): |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 420 | # We just started a client; all tests are relative to here. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 421 | min_stack_size = stack.size() |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 422 | # Start a "RUNNING" CLIENT_JOB entry. |
| 423 | job_name = 'CLIENT_JOB.%d' % job_count |
jadmanski | d1b0a13 | 2010-05-04 19:50:30 +0000 | [diff] [blame] | 424 | running_client = test.parse_partial_test(self.job, None, |
| 425 | job_name, |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 426 | '', current_kernel, |
jadmanski | d1b0a13 | 2010-05-04 19:50:30 +0000 | [diff] [blame] | 427 | started_time) |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 428 | msg = 'RUNNING: %s\n%s\n' |
jadmanski | d1b0a13 | 2010-05-04 19:50:30 +0000 | [diff] [blame] | 429 | msg %= (running_client.status, running_client.testname) |
jadmanski | 43b7210 | 2010-04-30 21:22:28 +0000 | [diff] [blame] | 430 | tko_utils.dprint(msg) |
jadmanski | d1b0a13 | 2010-05-04 19:50:30 +0000 | [diff] [blame] | 431 | new_tests.append(running_client) |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 432 | testname = running_client.testname |
jadmanski | 717bb99 | 2008-10-08 14:29:23 +0000 | [diff] [blame] | 433 | elif stack.size() == min_stack_size + 1 and not running_test: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 434 | # We just started a new test; insert a running record. |
jadmanski | aaac45e | 2009-05-06 20:25:46 +0000 | [diff] [blame] | 435 | running_reasons = set() |
jadmanski | 7839548 | 2009-03-10 04:21:03 +0000 | [diff] [blame] | 436 | if line.reason: |
jadmanski | aaac45e | 2009-05-06 20:25:46 +0000 | [diff] [blame] | 437 | running_reasons.add(line.reason) |
jadmanski | 74eebf3 | 2008-07-15 20:04:42 +0000 | [diff] [blame] | 438 | running_test = test.parse_partial_test(self.job, |
| 439 | line.subdir, |
| 440 | line.testname, |
| 441 | line.reason, |
| 442 | current_kernel, |
| 443 | started_time) |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 444 | msg = 'RUNNING: %s\nSubdir: %s\nTestname: %s\n%s' |
jadmanski | 74eebf3 | 2008-07-15 20:04:42 +0000 | [diff] [blame] | 445 | msg %= (running_test.status, running_test.subdir, |
| 446 | running_test.testname, running_test.reason) |
| 447 | tko_utils.dprint(msg) |
| 448 | new_tests.append(running_test) |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 449 | testname = running_test.testname |
jadmanski | 74eebf3 | 2008-07-15 20:04:42 +0000 | [diff] [blame] | 450 | started_time_stack.append(started_time) |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 451 | subdir_stack.append(line.subdir) |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 452 | testname_stack.append(testname) |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 453 | continue |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 454 | elif line.type == 'INFO': |
Eric Li | 6f27d4f | 2010-09-29 10:55:17 -0700 | [diff] [blame] | 455 | fields = line.optional_fields |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 456 | # Update the current kernel if one is defined in the info. |
| 457 | if 'kernel' in fields: |
jadmanski | 807490c | 2008-09-15 19:15:02 +0000 | [diff] [blame] | 458 | current_kernel = line.get_kernel() |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 459 | # Update the SERVER_JOB reason if one was logged for an abort. |
| 460 | if 'job_abort_reason' in fields: |
| 461 | running_job.reason = fields['job_abort_reason'] |
Eric Li | 6f27d4f | 2010-09-29 10:55:17 -0700 | [diff] [blame] | 462 | new_tests.append(running_job) |
jadmanski | 807490c | 2008-09-15 19:15:02 +0000 | [diff] [blame] | 463 | continue |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 464 | elif line.type == 'STATUS': |
| 465 | # Update the stacks. |
jadmanski | b69f250 | 2008-08-27 19:49:30 +0000 | [diff] [blame] | 466 | if line.subdir and stack.size() > min_stack_size: |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 467 | subdir_stack[-1] = line.subdir |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 468 | testname_stack[-1] = line.testname |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 469 | # Update the status, start and finished times. |
jadmanski | c66e93c | 2008-07-29 21:25:22 +0000 | [diff] [blame] | 470 | stack.update(line.status) |
jadmanski | b683796 | 2009-04-21 14:21:00 +0000 | [diff] [blame] | 471 | if status_lib.is_worse_than_or_equal_to(line.status, |
jadmanski | 262e1ab | 2009-04-01 18:27:38 +0000 | [diff] [blame] | 472 | current_status): |
jadmanski | c69138f | 2008-12-17 15:44:22 +0000 | [diff] [blame] | 473 | if line.reason: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 474 | # Update the status of a currently running test. |
jadmanski | 7839548 | 2009-03-10 04:21:03 +0000 | [diff] [blame] | 475 | if running_test: |
jadmanski | aaac45e | 2009-05-06 20:25:46 +0000 | [diff] [blame] | 476 | running_reasons.add(line.reason) |
jadmanski | 1f99f67 | 2009-07-01 16:23:09 +0000 | [diff] [blame] | 477 | running_reasons = tko_utils.drop_redundant_messages( |
| 478 | running_reasons) |
jadmanski | aaac45e | 2009-05-06 20:25:46 +0000 | [diff] [blame] | 479 | sorted_reasons = sorted(running_reasons) |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 480 | running_test.reason = ', '.join(sorted_reasons) |
jadmanski | b683796 | 2009-04-21 14:21:00 +0000 | [diff] [blame] | 481 | current_reason = running_test.reason |
jadmanski | 7839548 | 2009-03-10 04:21:03 +0000 | [diff] [blame] | 482 | new_tests.append(running_test) |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 483 | msg = 'update RUNNING reason: %s' % line.reason |
jadmanski | 7839548 | 2009-03-10 04:21:03 +0000 | [diff] [blame] | 484 | tko_utils.dprint(msg) |
jadmanski | b683796 | 2009-04-21 14:21:00 +0000 | [diff] [blame] | 485 | else: |
| 486 | current_reason = line.reason |
jadmanski | c69138f | 2008-12-17 15:44:22 +0000 | [diff] [blame] | 487 | current_status = stack.current_status() |
jadmanski | c66e93c | 2008-07-29 21:25:22 +0000 | [diff] [blame] | 488 | started_time = None |
| 489 | finished_time = line.get_timestamp() |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 490 | # If this is a non-test entry there's nothing else to do. |
jadmanski | 0986b25 | 2009-04-01 18:26:59 +0000 | [diff] [blame] | 491 | if line.testname is None and line.subdir is None: |
| 492 | continue |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 493 | elif line.type == 'END': |
| 494 | # Grab the current subdir off of the subdir stack, or, if this |
| 495 | # is the end of a job, just pop it off. |
jadmanski | 717bb99 | 2008-10-08 14:29:23 +0000 | [diff] [blame] | 496 | if (line.testname is None and line.subdir is None |
| 497 | and not running_test): |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 498 | min_stack_size = stack.size() - 1 |
| 499 | subdir_stack.pop() |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 500 | testname_stack.pop() |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 501 | else: |
| 502 | line.subdir = subdir_stack.pop() |
Sida Liu | afe550a | 2017-09-03 19:03:40 -0700 | [diff] [blame] | 503 | testname_stack.pop() |
jadmanski | 64e6345 | 2009-06-10 17:22:01 +0000 | [diff] [blame] | 504 | if not subdir_stack[-1] and stack.size() > min_stack_size: |
| 505 | subdir_stack[-1] = line.subdir |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 506 | # Update the status, start and finished times. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 507 | stack.update(line.status) |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 508 | current_status = stack.end() |
jadmanski | 29e61ce | 2008-08-22 17:38:28 +0000 | [diff] [blame] | 509 | if stack.size() > min_stack_size: |
| 510 | stack.update(current_status) |
jadmanski | c69138f | 2008-12-17 15:44:22 +0000 | [diff] [blame] | 511 | current_status = stack.current_status() |
jadmanski | c66e93c | 2008-07-29 21:25:22 +0000 | [diff] [blame] | 512 | started_time = started_time_stack.pop() |
| 513 | finished_time = line.get_timestamp() |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 514 | # Update the current kernel. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 515 | if line.is_successful_reboot(current_status): |
| 516 | current_kernel = line.get_kernel() |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 517 | # Adjust the testname if this is a reboot. |
| 518 | if line.testname == 'reboot' and line.subdir is None: |
| 519 | line.testname = 'boot.%d' % boot_count |
jadmanski | c66e93c | 2008-07-29 21:25:22 +0000 | [diff] [blame] | 520 | else: |
| 521 | assert False |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 522 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 523 | # Have we just finished a test? |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 524 | if stack.size() <= min_stack_size: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 525 | # If there was no testname, just use the subdir. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 526 | if line.testname is None: |
| 527 | line.testname = line.subdir |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 528 | # If there was no testname or subdir, use 'CLIENT_JOB'. |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 529 | if line.testname is None: |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 530 | line.testname = 'CLIENT_JOB.%d' % job_count |
jadmanski | d1b0a13 | 2010-05-04 19:50:30 +0000 | [diff] [blame] | 531 | running_test = running_client |
jadmanski | ba1fa66 | 2008-07-11 21:18:30 +0000 | [diff] [blame] | 532 | job_count += 1 |
| 533 | if not status_lib.is_worse_than_or_equal_to( |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 534 | current_status, 'ABORT'): |
| 535 | # A job hasn't really failed just because some of the |
| 536 | # tests it ran have. |
| 537 | current_status = 'GOOD' |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 538 | |
jadmanski | c69138f | 2008-12-17 15:44:22 +0000 | [diff] [blame] | 539 | if not current_reason: |
| 540 | current_reason = line.reason |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 541 | new_test = test.parse_test(self.job, |
| 542 | line.subdir, |
| 543 | line.testname, |
| 544 | current_status, |
jadmanski | c69138f | 2008-12-17 15:44:22 +0000 | [diff] [blame] | 545 | current_reason, |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 546 | current_kernel, |
| 547 | started_time, |
jadmanski | 74eebf3 | 2008-07-15 20:04:42 +0000 | [diff] [blame] | 548 | finished_time, |
| 549 | running_test) |
| 550 | running_test = None |
jadmanski | d6f5c59 | 2009-01-10 00:26:21 +0000 | [diff] [blame] | 551 | current_status = status_lib.statuses[-1] |
jadmanski | c69138f | 2008-12-17 15:44:22 +0000 | [diff] [blame] | 552 | current_reason = None |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 553 | if new_test.testname == ('boot.%d' % boot_count): |
jadmanski | 1ce9fbb | 2008-10-21 16:25:05 +0000 | [diff] [blame] | 554 | boot_count += 1 |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 555 | msg = 'ADD: %s\nSubdir: %s\nTestname: %s\n%s' |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 556 | msg %= (new_test.status, new_test.subdir, |
| 557 | new_test.testname, new_test.reason) |
| 558 | tko_utils.dprint(msg) |
| 559 | new_tests.append(new_test) |
jadmanski | 6e8bf75 | 2008-05-14 00:17:48 +0000 | [diff] [blame] | 560 | |
Dennis Jeffrey | ccbc9d4 | 2013-07-23 12:16:45 -0700 | [diff] [blame] | 561 | # The job is finished; produce the final SERVER_JOB entry and exit. |
| 562 | final_job = test.parse_test(self.job, '----', 'SERVER_JOB', |
Eric Li | 6f27d4f | 2010-09-29 10:55:17 -0700 | [diff] [blame] | 563 | self.job.exit_status(), running_job.reason, |
jadmanski | 6f6299a | 2008-12-02 15:22:21 +0000 | [diff] [blame] | 564 | current_kernel, |
| 565 | self.job.started_time, |
| 566 | self.job.finished_time, |
| 567 | running_job) |
| 568 | new_tests.append(final_job) |
jadmanski | 0afbb63 | 2008-06-06 21:10:57 +0000 | [diff] [blame] | 569 | yield new_tests |