1# Copyright 2015 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5"""A Model that represents one bisect or perf test try job.
6
7TryJob entities are checked in /update_bug_with_results to check completed
8bisect jobs and update bugs with results.
9
10They are also used in /auto_bisect to restart unsuccessful bisect jobs.
11"""
12
13import datetime
14import json
15
16from google.appengine.ext import ndb
17
18from dashboard import bisect_stats
19from dashboard.models import bug_data
20from dashboard.models import internal_only_model
21
22
23class TryJob(internal_only_model.InternalOnlyModel):
24  """Stores config and tracking info about a single try job."""
25  bot = ndb.StringProperty()
26  config = ndb.TextProperty()
27  bug_id = ndb.IntegerProperty()
28  email = ndb.StringProperty()
29  rietveld_issue_id = ndb.IntegerProperty()
30  rietveld_patchset_id = ndb.IntegerProperty()
31  master_name = ndb.StringProperty(default='ChromiumPerf', indexed=False)
32  buildbucket_job_id = ndb.StringProperty()
33  use_buildbucket = ndb.BooleanProperty(default=False, indexed=True)
34  internal_only = ndb.BooleanProperty(default=False, indexed=True)
35
36  # Bisect run status (e.g., started, failed).
37  status = ndb.StringProperty(
38      default='pending',
39      choices=[
40          'pending',  # Created, but job start has not been confirmed.
41          'started',  # Job is confirmed started.
42          'failed',   # Job terminated, red build.
43          'staled',   # No updates from bots.
44          'completed',  # Job terminated, green build.
45          'aborted',  # Job terminated with abort (purple, early abort).
46      ],
47      indexed=True)
48
49  # Number of times this job has been tried.
50  run_count = ndb.IntegerProperty(default=0)
51
52  # Last time this job was started.
53  last_ran_timestamp = ndb.DateTimeProperty()
54
55  job_type = ndb.StringProperty(
56      default='bisect',
57      choices=['bisect', 'bisect-fyi', 'perf-try'])
58
59  # job_name attribute is used by try jobs of bisect FYI.
60  job_name = ndb.StringProperty(default=None)
61
62  # Results data coming from bisect bots.
63  results_data = ndb.JsonProperty(indexed=False)
64
65  log_record_id = ndb.StringProperty(indexed=False)
66
67  # Sets of emails of users who has confirmed this TryJob result is bad.
68  bad_result_emails = ndb.PickleProperty()
69
70  def SetStarted(self):
71    self.status = 'started'
72    self.run_count += 1
73    self.last_ran_timestamp = datetime.datetime.now()
74    self.put()
75    if self.bug_id:
76      bug_data.SetBisectStatus(self.bug_id, 'started')
77
78  def SetFailed(self):
79    self.status = 'failed'
80    self.put()
81    if self.bug_id:
82      bug_data.SetBisectStatus(self.bug_id, 'failed')
83    bisect_stats.UpdateBisectStats(self.bot, 'failed')
84
85  def SetStaled(self):
86    self.status = 'staled'
87    self.put()
88    # TODO(chrisphan): Add 'staled' state to bug_data and bisect_stats.
89    if self.bug_id:
90      bug_data.SetBisectStatus(self.bug_id, 'failed')
91    bisect_stats.UpdateBisectStats(self.bot, 'failed')
92
93  def SetCompleted(self):
94    self.status = 'completed'
95    self.put()
96    if self.bug_id:
97      bug_data.SetBisectStatus(self.bug_id, 'completed')
98    bisect_stats.UpdateBisectStats(self.bot, 'completed')
99
100  def GetConfigDict(self):
101    return json.loads(self.config.split('=', 1)[1])
102