The reparse of existing job is done by a delete and then an insert, this
introduces a new job_idx/test_idx for the same job and voids the old ones,
so users won't be able to use job_idx/test_idx to refer to job/test as their
index might change.
This cl makes reparse to keep the same job_idx and test_idx for existing
jobs.
Also fixes a bug where user created test attributes are being deleted
inadvertently during reparse.
Signed-off-by: Jiqing Tang <jiqingtang@google.com>
git-svn-id: http://test.kernel.org/svn/autotest/trunk@3992 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/tko/parse.py b/tko/parse.py
index 67f76a5..a82ab0a 100755
--- a/tko/parse.py
+++ b/tko/parse.py
@@ -71,48 +71,24 @@
mail.send("", job.user, "", subject, message_header + message)
-def find_old_tests(db, job_idx):
- """
- Given a job index, return a list of all the test objects associated with
- it in the database, including labels, but excluding other "complex"
- data (attributes, iteration data, kernels).
- """
- raw_tests = db.select("test_idx,subdir,test,started_time,finished_time",
- "tests", {"job_idx": job_idx})
- if not raw_tests:
- return []
-
- test_ids = ", ".join(str(raw_test[0]) for raw_test in raw_tests)
-
- labels = db.select("test_id, testlabel_id", "test_labels_tests",
- "test_id in (%s)" % test_ids)
- label_map = {}
- for test_id, testlabel_id in labels:
- label_map.setdefault(test_id, []).append(testlabel_id)
-
- tests = []
- for raw_test in raw_tests:
- tests.append(models.test(raw_test[1], raw_test[2], None, None, None,
- None, raw_test[3], raw_test[4],
- [], {}, label_map.get(raw_test[0], [])))
- return tests
-
-
def parse_one(db, jobname, path, reparse, mail_on_failure):
"""
Parse a single job. Optionally send email on failure.
"""
tko_utils.dprint("\nScanning %s (%s)" % (jobname, path))
old_job_idx = db.find_job(jobname)
- old_tests = []
- if reparse and old_job_idx:
- tko_utils.dprint("! Deleting old copy of job results to "
- "reparse it")
- old_tests = find_old_tests(db, old_job_idx)
- db.delete_job(jobname)
- if db.find_job(jobname):
- tko_utils.dprint("! Job is already parsed, done")
- return
+ # old tests is a dict from tuple (test_name, subdir) to test_idx
+ old_tests = {}
+ if old_job_idx is not None:
+ if not reparse:
+ tko_utils.dprint("! Job is already parsed, done")
+ return
+
+ raw_old_tests = db.select("test_idx,subdir,test", "tests",
+ {"job_idx": old_job_idx})
+ if raw_old_tests:
+ old_tests = dict(((test, subdir), test_idx)
+ for test_idx, subdir, test in raw_old_tests)
# look up the status version
job_keyval = models.job.read_keyval(path)
@@ -142,19 +118,25 @@
already_added.add(test)
job.tests.append(test)
- # try and port labels over from the old tests, but if old tests stop
+ # try and port test_idx over from the old tests, but if old tests stop
# matching up with new ones just give up
- for test, old_test in zip(job.tests, old_tests):
- tests_are_the_same = (test.testname == old_test.testname and
- test.subdir == old_test.subdir and
- test.started_time == old_test.started_time and
- (test.finished_time == old_test.finished_time or
- old_test.finished_time is None))
- if tests_are_the_same:
- test.labels = old_test.labels
- else:
- tko_utils.dprint("! Reparse returned new tests, "
- "dropping old test labels")
+ if reparse and old_job_idx is not None:
+ job.index = old_job_idx
+ for test in job.tests:
+ test_idx = old_tests.pop((test.testname, test.subdir), None)
+ if test_idx is not None:
+ test.test_idx = test_idx
+ else:
+ tko_utils.dprint("! Reparse returned new test "
+ "testname=%r subdir=%r" %
+ (test.testname, test.subdir))
+ for test_idx in old_tests.itervalues():
+ where = {'test_idx' : test_idx}
+ db.delete('iteration_result', where)
+ db.delete('iteration_attributes', where)
+ db.delete('test_attributes', where)
+ db.delete('test_labels_tests', {'test_id': test_idx})
+ db.delete('tests', where)
# check for failures
message_lines = [""]