[Ezbench-dev] [PATCH 3/3] smartezbench: allow specifying if a task is user- or auto-requested
Martin Peres
martin.peres at linux.intel.com
Wed Mar 15 13:44:48 UTC 2017
We will first run user-requested tasks, then handle auto-requested
ones. We also reset the auto tasks after every call to run(), to
make sure the decision to run something is always up to date!
---
python-modules/ezbench/smartezbench.py | 127 ++++++++++++++++++++++-----------
1 file changed, 85 insertions(+), 42 deletions(-)
diff --git a/python-modules/ezbench/smartezbench.py b/python-modules/ezbench/smartezbench.py
index aea406a..466079d 100644
--- a/python-modules/ezbench/smartezbench.py
+++ b/python-modules/ezbench/smartezbench.py
@@ -92,7 +92,8 @@ def list_smart_ezbench_report_names(ezbench_dir, updatedSince = 0):
return reports
class TaskEntry:
- def __init__(self, commit, test, rounds, resumeResultFile = None):
+ def __init__(self, commit, test, rounds, resumeResultFile = None,
+ user_requested = True):
self.commit = commit
self.test = test
self.rounds = rounds
@@ -100,6 +101,7 @@ class TaskEntry:
self.start_date = None
self.exec_time = None
self.build_time = None
+ self.user_requested = user_requested
self.cur_round = 1
self.last_round_completed_date = None
@@ -186,6 +188,9 @@ class TaskEntry:
else:
string += "(no estimation available)"
+ if not self.user_requested:
+ string += " (autogenerated)"
+
return string
GitCommit = namedtuple('GitCommit', 'sha1 timestamp')
@@ -311,6 +316,13 @@ class SmartEzbench:
del self.state['commits']
upgraded = True
+ if version == 2:
+ self.__log(Criticality.II, "state: v2 -> v3: create a new 'auto' sections for tasks")
+ self.state['version'] = 3
+ self.state['tasks']['auto'] = dict()
+ self.state['tasks']['auto']['commits'] = dict()
+ upgraded = True
+
if upgraded:
self.__save_state()
@@ -523,12 +535,16 @@ class SmartEzbench:
return total_rounds
- def __add_test_unlocked__(self, commit, test, rounds):
+ def __add_test_unlocked__(self, commit, test, rounds, user_requested=True):
scm = self.repo()
if scm is not None:
commit = scm.full_version_name(commit)
- commits = self.state['tasks']['user']['commits']
+ if user_requested:
+ commits = self.state['tasks']['user']['commits']
+ else:
+ commits = self.state['tasks']['auto']['commits']
+
if rounds is None:
return commits[commit]['tests'][test]['rounds']
@@ -538,14 +554,14 @@ class SmartEzbench:
if self.__running_mode_unlocked__(check_running=False) == RunningMode.DONE:
self.__set_running_mode_unlocked__(RunningMode.RUN)
- def add_test(self, commit, test, rounds = None):
+ def add_test(self, commit, test, rounds = None, user_requested=True):
self.__reload_state(keep_lock=True)
total_rounds = self.__add_test_unlocked__(commit, test, rounds)
self.__save_state()
self.__release_lock()
return total_rounds
- def add_testset(self, commit, testset, rounds = 1, ensure=False):
+ def add_testset(self, commit, testset, rounds = 1, ensure=False, user_requested=True):
self.__reload_state(keep_lock=True)
self.__log(Criticality.II, "Add the testset {} ({} tests)".format(testset.name,
@@ -553,14 +569,14 @@ class SmartEzbench:
for test in sorted(testset.keys()):
if not ensure:
- self.__add_test_unlocked__(commit, test, testset[test] * rounds)
+ self.__add_test_unlocked__(commit, test, testset[test] * rounds, user_requested)
else:
- self.__force_test_rounds_unlocked__(commit, test, testset[test] * rounds)
+ self.__force_test_rounds_unlocked__(commit, test, testset[test] * rounds, user_requested)
self.__save_state()
self.__release_lock()
- def __force_test_rounds_unlocked__(self, commit, test, at_least):
+ def __force_test_rounds_unlocked__(self, commit, test, at_least, user_requested=True):
scm = self.repo()
if scm is not None:
commit = scm.full_version_name(commit)
@@ -570,7 +586,11 @@ class SmartEzbench:
else:
at_least = int(at_least)
- commits = self.state['tasks']['user']['commits']
+ if user_requested:
+ commits = self.state['tasks']['user']['commits']
+ else:
+ commits = self.state['tasks']['auto']['commits']
+
if commit not in commits:
commits[commit] = dict()
commits[commit]["tests"] = dict()
@@ -587,9 +607,9 @@ class SmartEzbench:
else:
return 0
- def force_test_rounds(self, commit, test, at_least):
+ def force_test_rounds(self, commit, test, at_least, user_requested=True):
self.__reload_state(keep_lock=True)
- ret = self.__force_test_rounds_unlocked__(commit, test, at_least)
+ ret = self.__force_test_rounds_unlocked__(commit, test, at_least, user_requested)
self.__save_state()
self.__release_lock()
@@ -622,10 +642,7 @@ class SmartEzbench:
return c, tl, self._events_str
- def __prioritize_runs(self, task_tree, deployed_version, resumable_tasks):
- task_list = deque()
-
- # Aggregate all the subtests
+ def __aggregate_subtests__(self, task_tree):
for commit in task_tree:
test_subtests = dict()
test_rounds = dict()
@@ -646,6 +663,20 @@ class SmartEzbench:
task_tree[commit]["tests"][full_name] = dict()
task_tree[commit]["tests"][full_name]["rounds"] = test_rounds[basename]
+ def __prioritize_runs_add_by_commit__(self, task_list, task_tree, user_requested=True):
+ # Add all the remaining tasks in whatever order!
+ for commit in task_tree:
+ for test in task_tree[commit]["tests"]:
+ rounds = task_tree[commit]["tests"][test]["rounds"]
+ task_list.append(TaskEntry(commit, test, rounds, user_requested))
+
+ def __prioritize_runs(self, task_tree_user, task_tree_auto, deployed_version, resumable_tasks):
+ task_list = deque()
+
+ # Aggregate all the subtests
+ self.__aggregate_subtests__(task_tree_user)
+ self.__aggregate_subtests__(task_tree_auto)
+
# Schedule resumable tasks. First the already-deployed
# versions, other versions later
for task in resumable_tasks:
@@ -663,19 +694,19 @@ class SmartEzbench:
# Get rid of the task
self.__task_tree_add_test__(task_tree, entry.commit, entry.test, -1)
- # Schedule the tests using the already-deployed version after
- # all resumable tasks
- if deployed_version is not None and deployed_version in task_tree:
- for test in task_tree[deployed_version]["tests"]:
- rounds = task_tree[deployed_version]["tests"][test]["rounds"]
- task_list.append(TaskEntry(deployed_version, test, rounds))
- del task_tree[deployed_version]
+ # Add all the task wanted by the user that can be run on the
+ # currently-deployed component
+ if deployed_version is not None and deployed_version in task_tree_user:
+ for test in task_tree_user[deployed_version]["tests"]:
+ rounds = task_tree_user[deployed_version]["tests"][test]["rounds"]
+ task_list.append(TaskEntry(deployed_version, test, rounds,
+ user_requested=True))
+ del task_tree_user[deployed_version]
- # Add all the remaining tasks in whatever order!
- for commit in task_tree:
- for test in task_tree[commit]["tests"]:
- rounds = task_tree[commit]["tests"][test]["rounds"]
- task_list.append(TaskEntry(commit, test, rounds))
+ # Schedule the user-requested tests first, then the automatic. Add them
+ # in whatever order
+ self.__prioritize_runs_add_by_commit__(task_list, task_tree_user, user_requested=True)
+ self.__prioritize_runs_add_by_commit__(task_list, task_tree_auto, user_requested=False)
return task_list
@@ -726,6 +757,14 @@ class SmartEzbench:
return True
@classmethod
+ def __remove_existing_tasks_from_tree(cls, report, task_tree):
+ for commit in report.commits:
+ for result in commit.results.values():
+ for key in result.results():
+ full_name = Test.partial_name(result.test.full_name, [key])
+ SmartEzbench.__remove_task_from_tasktree__(task_tree, commit.full_sha1, full_name, len(result.result(key)))
+
+ @classmethod
def __generate_task_and_events_list__(cls, q, state, log_folder, scm):
exit_code = 1
task_tree = list()
@@ -748,13 +787,11 @@ class SmartEzbench:
events_str.append(str(event))
# Walk down the report and get rid of every run that has already been made!
- task_tree = copy.deepcopy(self.state['tasks']['user']['commits'])
+ task_tree_user = copy.deepcopy(state['tasks']['user']['commits'])
+ cls.__remove_existing_tasks_from_tree(report, task_tree_user)
- for commit in report.commits:
- for result in commit.results.values():
- for key in result.results():
- full_name = Test.partial_name(result.test.full_name, [key])
- SmartEzbench.__remove_task_from_tasktree__(task_tree, commit.full_sha1, full_name, len(result.result(key)))
+ task_tree_auto = copy.deepcopy(state['tasks']['auto']['commits'])
+ cls.__remove_existing_tasks_from_tree(report, task_tree_user)
resumable_tasks = report.journal.incomplete_tests()
@@ -773,7 +810,7 @@ class SmartEzbench:
pass
# Return the result
- q.put((exit_code, task_tree, events_str, resumable_tasks))
+ q.put((exit_code, task_tree_user, task_tree_auto, events_str, resumable_tasks))
def run(self):
self.__log(Criticality.II, "----------------------")
@@ -808,23 +845,29 @@ class SmartEzbench:
p = multiprocessing.Process(target=SmartEzbench.__generate_task_and_events_list__,
args=(q, self.state, self.log_folder, self.repo()))
p.start()
- exit_code, task_tree, self._events_str, resumable_tasks = q.get()
+ exit_code, task_tree_user, task_tree_auto, self._events_str, resumable_tasks = q.get()
p.join()
- if len(task_tree) == 0:
+ if len(task_tree_user) == 0 and len(task_tree_auto) == 0:
self.__log(Criticality.II, "Nothing left to do, exit")
return False
- task_tree_str = pprint.pformat(task_tree)
- self.__log(Criticality.II, "Task list: {tsk_str}".format(tsk_str=task_tree_str))
+ task_tree_user_str = pprint.pformat(task_tree_user)
+ task_tree_auto_str = pprint.pformat(task_tree_auto)
+ self.__log(Criticality.II, "Task list (user): {tsk_str}".format(tsk_str=task_tree_user_str))
+ self.__log(Criticality.II, "Task list (auto): {tsk_str}".format(tsk_str=task_tree_auto_str))
self.__log(Criticality.II, "Incomplete runs: {}".format([r['result_file'] for r in resumable_tasks]))
- # Lock the report for further changes (like for profiles)
- self.__write_attribute__('beenRunBefore', True)
+ # Write all the changes to the state
+ self.__reload_state(keep_lock=True)
+ self.state['tasks']['auto']['commits'] = dict()
+ self.__write_attribute_unlocked__('beenRunBefore', True)
+ self.__save_state()
+ self.__release_lock()
# Prioritize --> return a list of commits to do in order
self._task_lock.acquire()
- self._task_list = self.__prioritize_runs(task_tree, deployed_commit, resumable_tasks)
+ self._task_list = self.__prioritize_runs(task_tree_user, task_tree_auto, deployed_commit, resumable_tasks)
# Call the hook file, telling we started running
self.__call_hook__('start_running_tests')
@@ -1127,7 +1170,7 @@ class SmartEzbench:
self.__log(Criticality.DD, "Add all the tasks using commit {}".format(commit))
for t in tasks_sorted:
if t[1] == commit:
- added = self.__force_test_rounds_unlocked__(t[1], t[2], t[3])
+ added = self.__force_test_rounds_unlocked__(t[1], t[2], t[3], user_requested=False)
if added > 0:
self.__log(Criticality.II,
"Scheduled {} more runs for the test {} on commit {}".format(added, t[2], commit))
--
2.11.1
More information about the Ezbench-dev
mailing list