diff options
-rw-r--r-- | client/common_lib/logging.py | 2 | ||||
-rw-r--r-- | tko/db.py | 31 | ||||
-rw-r--r-- | tko/migrations/012_add_running_status.py | 6 | ||||
-rw-r--r-- | tko/models.py | 27 | ||||
-rw-r--r-- | tko/parsers/version_1.py | 25 |
5 files changed, 72 insertions, 19 deletions
diff --git a/client/common_lib/logging.py b/client/common_lib/logging.py index 4f15a62e..5f6f6200 100644 --- a/client/common_lib/logging.py +++ b/client/common_lib/logging.py @@ -8,7 +8,7 @@ __author__ = 'jadmanski@google.com (John Admanski)' job_statuses = ["TEST_NA", "ABORT", "ERROR", "FAIL", "WARN", "GOOD", "ALERT", - "NOSTATUS"] + "RUNNING", "NOSTATUS"] def is_valid_status(status): if not re.match(r'(START|(END )?('+'|'.join(job_statuses)+'))$', @@ -164,10 +164,14 @@ class db_sql(object): values = [] if where and isinstance(where, types.DictionaryType): - # key/value pairs (which should be equal) - keys = [field + '=%s' for field in where.keys()] - values = [where[field] for field in where.keys()] - + # key/value pairs (which should be equal, or None for null) + keys, values = [], [] + for field, value in where.iteritems(): + if value is None: + keys.append(field + ' is null') + else: + keys.append(field + '=%s') + values.append(value) cmd.append(' where ' + ' and '.join(keys)) elif where and isinstance(where, types.StringTypes): # the exact string @@ -282,14 +286,14 @@ class db_sql(object): fields = data.keys() data_refs = [field + '=%s' for field in fields] data_values = [data[field] for field in fields] - cmd += ' set ' + ' and '.join(data_refs) + cmd += ' set ' + ', '.join(data_refs) where_keys = [field + '=%s' for field in where.keys()] where_values = [where[field] for field in where.keys()] cmd += ' where ' + ' and '.join(where_keys) values = data_values + where_values - print '%s %s' % (cmd, values) + self.dprint('%s %s' % (cmd, values)) self._exec_sql_with_commit(cmd, values, commit) @@ -299,6 +303,7 @@ class db_sql(object): for test_idx in self.find_tests(job_idx): where = {'test_idx' : test_idx} self.delete('iteration_result', where) + self.delete('iteration_attributes', where) self.delete('test_attributes', where) where = {'job_idx' : job_idx} self.delete('tests', where) @@ -331,9 +336,13 @@ class db_sql(object): 'reason':test.reason, 'machine_idx':job.machine_idx, 'started_time': test.started_time, 'finished_time':test.finished_time} - self.insert('tests', data, commit=commit) - test_idx = self.get_last_autonumber_value() - data = { 'test_idx':test_idx } + if hasattr(test, "test_idx"): + test_idx = test.test_idx + self.update('tests', data, {'test_idx': test_idx}, commit=commit) + else: + self.insert('tests', data, commit=commit) + test_idx = test.test_idx = self.get_last_autonumber_value() + data = {'test_idx': test_idx} for i in test.iterations: data['iteration'] = i.index @@ -441,8 +450,8 @@ class db_sql(object): commit=commit) - def find_test(self, job_idx, subdir): - where = { 'job_idx':job_idx , 'subdir':subdir } + def find_test(self, job_idx, testname, subdir): + where = {'job_idx': job_idx , 'test': testname, 'subdir': subdir} rows = self.select('test_idx', 'tests', where) if rows: return rows[0][0] diff --git a/tko/migrations/012_add_running_status.py b/tko/migrations/012_add_running_status.py new file mode 100644 index 00000000..db7db2ec --- /dev/null +++ b/tko/migrations/012_add_running_status.py @@ -0,0 +1,6 @@ +def migrate_up(manager): + manager.execute("INSERT INTO status (word) values ('RUNNING')") + + +def migrate_down(manager): + manager.execute("DELETE FROM status where word = 'RUNNING'") diff --git a/tko/models.py b/tko/models.py index a5e230b6..d754e9e7 100644 --- a/tko/models.py +++ b/tko/models.py @@ -56,7 +56,7 @@ class test(object): @classmethod def parse_test(cls, job, subdir, testname, status, reason, test_kernel, - started_time, finished_time): + started_time, finished_time, existing_instance=None): """Given a job and the basic metadata about the test that can be extracted from the status logs, parse the test keyval files and use it to construct a complete test @@ -76,9 +76,28 @@ class test(object): iterations = [] attributes = {} - return cls(subdir, testname, status, reason, test_kernel, - job.machine, started_time, finished_time, - iterations, attributes) + if existing_instance: + def constructor(*args, **dargs): + existing_instance.__init__(*args, **dargs) + return existing_instance + else: + constructor = cls + return constructor(subdir, testname, status, reason, test_kernel, + job.machine, started_time, finished_time, + iterations, attributes) + + + @classmethod + def parse_partial_test(cls, job, subdir, testname, reason, test_kernel, + started_time): + """Given a job and the basic metadata available when a test is + started, create a test instance representing the partial result. + Assume that since the test is not complete there are no results files + actually available for parsing.""" + tko_utils.dprint("parsing partial test %s %s" % (subdir, testname)) + + return cls(subdir, testname, "RUNNING", reason, test_kernel, + job.machine, started_time, None, [], {}) @staticmethod diff --git a/tko/parsers/version_1.py b/tko/parsers/version_1.py index 317a082c..95f608db 100644 --- a/tko/parsers/version_1.py +++ b/tko/parsers/version_1.py @@ -110,6 +110,7 @@ class parser(base.parser): current_kernel = kernel("", []) # UNKNOWN started_time_stack = [None] subdir_stack = [None] + running_test = None while True: # are we finished with parsing? @@ -142,9 +143,25 @@ class parser(base.parser): # initial line processing if line.type == "START": stack.start() - if (line.testname, line.subdir) == (None,) * 2: + started_time = line.get_timestamp() + if (line.testname, line.subdir) == (None, None): + # we just started a client, all tests are relative to here min_stack_size = stack.size() - started_time_stack.append(line.get_timestamp()) + elif stack.size() == min_stack_size + 1: + # we just started a new test, insert a running record + assert(running_test is None) + running_test = test.parse_partial_test(self.job, + line.subdir, + line.testname, + line.reason, + current_kernel, + started_time) + msg = "RUNNING: %s\nSubdir: %s\nTestname: %s\n%s" + msg %= (running_test.status, running_test.subdir, + running_test.testname, running_test.reason) + tko_utils.dprint(msg) + new_tests.append(running_test) + started_time_stack.append(started_time) subdir_stack.append(line.subdir) continue elif line.type == "STATUS": @@ -212,7 +229,9 @@ class parser(base.parser): line.reason, current_kernel, started_time, - finished_time) + finished_time, + running_test) + running_test = None msg = "ADD: %s\nSubdir: %s\nTestname: %s\n%s" msg %= (new_test.status, new_test.subdir, new_test.testname, new_test.reason) |