Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(185)

Unified Diff: frontend/planner/rpc_interface.py

Issue 1595019: Merge remote branch 'origin/upstream' into tempbranch (Closed)
Patch Set: Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « frontend/planner/models.py ('k') | frontend/planner/rpc_interface_unittest.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: frontend/planner/rpc_interface.py
diff --git a/frontend/planner/rpc_interface.py b/frontend/planner/rpc_interface.py
index 219436f7fd7be8809ab57161fb08dea6337c1697..a974b9f13f70e389fa63b64cc42e6afb6a6b74af 100644
--- a/frontend/planner/rpc_interface.py
+++ b/frontend/planner/rpc_interface.py
@@ -12,7 +12,8 @@ from autotest_lib.frontend import thread_local
from autotest_lib.frontend.afe import model_logic, models as afe_models
from autotest_lib.frontend.afe import rpc_utils as afe_rpc_utils
from autotest_lib.frontend.tko import models as tko_models
-from autotest_lib.frontend.planner import models, rpc_utils
+from autotest_lib.frontend.planner import models, rpc_utils, model_attributes
+from autotest_lib.frontend.planner import failure_actions
from autotest_lib.client.common_lib import utils
# basic getter/setter calls
@@ -27,12 +28,6 @@ def modify_plan(id, **data):
models.Plan.smart_get(id).update_object(data)
-def get_test_runs(**filter_data):
- return afe_rpc_utils.prepare_for_serialization(
- [test_run.get_object_dict() for test_run
- in models.TestRun.objects.filter(**filter_data)])
-
-
def modify_test_run(id, **data):
models.TestRun.objects.get(id=id).update_object(data)
@@ -70,7 +65,7 @@ def submit_plan(name, hosts, host_labels, tests,
is_server: True if is a server-side control file
estimated_runtime: estimated number of hours this test
will run
- @param support: the global support object
+ @param support: the global support script
@param label_override: label to prepend to all AFE jobs for this test plan.
Defaults to the plan name.
"""
@@ -185,9 +180,10 @@ def get_next_test_configs(plan_id):
rpc_utils.update_hosts_table(plan)
for host in models.Host.objects.filter(plan=plan):
- next_test_config_id = rpc_utils.compute_next_test_config(plan, host)
- if next_test_config_id:
- config = {'next_test_config_id': next_test_config_id,
+ next_test_config = rpc_utils.compute_next_test_config(plan, host)
+ if next_test_config:
+ config = {'next_test_config_id': next_test_config.id,
+ 'next_test_config_alias': next_test_config.alias,
'host': host.host.hostname}
result['next_configs'].append(config)
@@ -212,7 +208,7 @@ def update_test_runs(plan_id):
tko_test_idx: the ID of the TKO test added
hostname: the host added
"""
- plan = models.Plan.objects.get(id=plan_id)
+ plan = models.Plan.smart_get(plan_id)
updated = []
for planner_job in plan.job_set.all():
@@ -235,3 +231,158 @@ def update_test_runs(plan_id):
'hostname': hostname})
return updated
+
+
+def get_failures(plan_id):
+ """
+ Gets a list of the untriaged failures associated with this plan
+
+ @return a list of dictionaries:
+ id: the failure ID, for passing back to triage the failure
+ group: the group for the failure. Normally the same as the
+ reason, but can be different for custom queries
+ machine: the failed machine
+ blocked: True if the failure caused the machine to block
+ test_name: Concatenation of the Planner alias and the TKO test
+ name for the failed test
+ reason: test failure reason
+ seen: True if the failure is marked as "seen"
+ """
+ plan = models.Plan.smart_get(plan_id)
+ result = {}
+
+ failures = plan.testrun_set.filter(
+ finalized=True, triaged=False,
+ status=model_attributes.TestRunStatus.FAILED)
+ failures = failures.select_related('test_job__test', 'host__host',
+ 'tko_test')
+ for failure in failures:
+ test_name = '%s:%s' % (
+ failure.test_job.test_config.alias, failure.tko_test.test)
+
+ group_failures = result.setdefault(failure.tko_test.reason, [])
+ failure_dict = {'id': failure.id,
+ 'machine': failure.host.host.hostname,
+ 'blocked': bool(failure.host.blocked),
+ 'test_name': test_name,
+ 'reason': failure.tko_test.reason,
+ 'seen': bool(failure.seen)}
+ group_failures.append(failure_dict)
+
+ return result
+
+
+def get_test_runs(**filter_data):
+ """
+ Gets a list of test runs that match the filter data.
+
+ Returns a list of expanded TestRun object dictionaries. Specifically, the
+ "host" and "test_job" fields are expanded. Additionally, the "test_config"
+ field of the "test_job" expansion is also expanded.
+ """
+ result = []
+ for test_run in models.TestRun.objects.filter(**filter_data):
+ test_run_dict = test_run.get_object_dict()
+ test_run_dict['host'] = test_run.host.get_object_dict()
+ test_run_dict['test_job'] = test_run.test_job.get_object_dict()
+ test_run_dict['test_job']['test_config'] = (
+ test_run.test_job.test_config.get_object_dict())
+ result.append(test_run_dict)
+ return result
+
+
+def skip_test(test_config_id, hostname):
+ """
+ Marks a test config as "skipped" for a given host
+ """
+ config = models.TestConfig.objects.get(id=test_config_id)
+ config.skipped_hosts.add(afe_models.Host.objects.get(hostname=hostname))
+
+
+def mark_failures_as_seen(failure_ids):
+ """
+ Marks a set of failures as 'seen'
+
+ @param failure_ids: A list of failure IDs, as returned by get_failures(), to
+ mark as seen
+ """
+ models.TestRun.objects.filter(id__in=failure_ids).update(seen=True)
+
+
+def process_failure(failure_id, host_action, test_action, labels=(),
+ keyvals=None, bugs=(), reason=None, invalidate=False):
+ """
+ Triage a failure
+
+ @param failure_id: The failure ID, as returned by get_failures()
+ @param host_action: One of 'Block', 'Unblock', 'Reinstall'
+ @param test_action: One of 'Skip', 'Rerun'
+
+ @param labels: Test labels to apply, by name
+ @param keyvals: Dictionary of job keyvals to add (or replace)
+ @param bugs: List of bug IDs to associate with this failure
+ @param reason: An override for the test failure reason
+ @param invalidate: True if failure should be invalidated for the purposes of
+ reporting. Defaults to False.
+ """
+ if keyvals is None:
+ keyvals = {}
+
+ host_choices = failure_actions.HostAction.values
+ test_choices = failure_actions.TestAction.values
+ if host_action not in host_choices:
+ raise model_logic.ValidationError(
+ {'host_action': ('host action %s not valid; must be one of %s'
+ % (host_action, ', '.join(host_choices)))})
+ if test_action not in test_choices:
+ raise model_logic.ValidationError(
+ {'test_action': ('test action %s not valid; must be one of %s'
+ % (test_action, ', '.join(test_choices)))})
+
+ failure = models.TestRun.objects.get(id=failure_id)
+
+ rpc_utils.process_host_action(failure.host, host_action)
+ rpc_utils.process_test_action(failure.test_job, test_action)
+
+ # Add the test labels
+ for label in labels:
+ tko_test_label, _ = (
+ tko_models.TestLabel.objects.get_or_create(name=label))
+ failure.tko_test.testlabel_set.add(tko_test_label)
+
+ # Set the job keyvals
+ for key, value in keyvals.iteritems():
+ keyval, created = tko_models.JobKeyval.objects.get_or_create(
+ job=failure.tko_test.job, key=key)
+ if not created:
+ tko_models.JobKeyval.objects.create(job=failure.tko_test.job,
+ key='original_' + key,
+ value=keyval.value)
+ keyval.value = value
+ keyval.save()
+
+ # Add the bugs
+ for bug_id in bugs:
+ bug, _ = models.Bug.objects.get_or_create(external_uid=bug_id)
+ failure.bugs.add(bug)
+
+ # Set the failure reason
+ if reason is not None:
+ tko_models.TestAttribute.objects.create(test=failure.tko_test,
+ attribute='original_reason',
+ value=failure.tko_test.reason)
+ failure.tko_test.reason = reason
+ failure.tko_test.save()
+
+ # Set 'invalidated', 'seen', and 'triaged'
+ failure.invalidated = invalidate
+ failure.seen = True
+ failure.triaged = True
+ failure.save()
+
+
+def get_static_data():
+ result = {'motd': afe_rpc_utils.get_motd(),
+ 'host_actions': sorted(failure_actions.HostAction.values),
+ 'test_actions': sorted(failure_actions.TestAction.values)}
+ return result
« no previous file with comments | « frontend/planner/models.py ('k') | frontend/planner/rpc_interface_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698