OLD | NEW |
1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 from datetime import datetime | 5 from datetime import datetime |
6 from itertools import chain | 6 from itertools import chain |
7 import logging | 7 import logging |
8 | 8 |
9 import webapp2 | 9 import webapp2 |
10 | 10 |
11 from model.record import Record | 11 from model.record import Record |
12 from shared.config import ( | 12 from shared.config import ( |
13 TAG_START, | 13 TAG_START, |
14 TAG_STOP, | 14 TAG_STOP, |
15 TAG_ISSUE, | 15 TAG_ISSUE, |
16 TAG_PATCHSET, | 16 TAG_PATCHSET, |
17 TAG_CODEREVIEW_HOSTNAME, | 17 TAG_CODEREVIEW_HOSTNAME, |
18 TRYJOBVERIFIER, | 18 TRYJOBVERIFIER, |
19 JOB_STATE, | 19 JOB_STATE, |
20 ) | 20 ) |
21 from shared.parsing import parse_rietveld_timestamp | 21 from shared.parsing import parse_rietveld_timestamp |
22 from shared.utils import ( | 22 from shared import utils |
23 cross_origin_json, | |
24 to_unix_timestamp, | |
25 guess_legacy_codereview_hostname, | |
26 ) | |
27 | 23 |
28 | 24 |
29 class PatchSummary(webapp2.RequestHandler): | 25 class PatchSummary(webapp2.RequestHandler): |
30 @cross_origin_json | 26 @utils.cross_origin_json |
| 27 @utils.read_access |
31 def get(self, issue, patch): # pylint: disable=W0221 | 28 def get(self, issue, patch): # pylint: disable=W0221 |
32 now = to_unix_timestamp(datetime.utcnow()) | 29 now = utils.to_unix_timestamp(datetime.utcnow()) |
33 codereview_hostname = guess_legacy_codereview_hostname(issue) | 30 codereview_hostname = utils.guess_legacy_codereview_hostname(issue) |
34 return summarize_patch(codereview_hostname, issue, patch, now) | 31 return summarize_patch(codereview_hostname, issue, patch, now) |
35 | 32 |
36 | 33 |
37 class PatchSummaryV2(webapp2.RequestHandler): | 34 class PatchSummaryV2(webapp2.RequestHandler): |
38 @cross_origin_json | 35 @utils.cross_origin_json |
| 36 @utils.read_access |
39 def get(self, codereview_hostname, issue, patch): # pylint: disable=W0221 | 37 def get(self, codereview_hostname, issue, patch): # pylint: disable=W0221 |
40 now = to_unix_timestamp(datetime.utcnow()) | 38 now = utils.to_unix_timestamp(datetime.utcnow()) |
41 return summarize_patch(codereview_hostname, issue, patch, now) | 39 return summarize_patch(codereview_hostname, issue, patch, now) |
42 | 40 |
43 | 41 |
44 def summarize_patch(codereview_hostname, issue, patch, now): | 42 def summarize_patch(codereview_hostname, issue, patch, now): |
45 attempts = [ | 43 attempts = [ |
46 summarize_attempt(raw_attempt, now) | 44 summarize_attempt(raw_attempt, now) |
47 for raw_attempt in get_raw_attempts(codereview_hostname, issue, patch) | 45 for raw_attempt in get_raw_attempts(codereview_hostname, issue, patch) |
48 ][::-1] | 46 ][::-1] |
49 return { | 47 return { |
50 'success': any(attempt['success'] for attempt in attempts), | 48 'success': any(attempt['success'] for attempt in attempts), |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 if TAG_STOP in record.tags: | 84 if TAG_STOP in record.tags: |
87 raw_attempts.append(raw_attempt) | 85 raw_attempts.append(raw_attempt) |
88 raw_attempt = None | 86 raw_attempt = None |
89 if raw_attempt != None and len(raw_attempt) > 0: # pragma: no cover | 87 if raw_attempt != None and len(raw_attempt) > 0: # pragma: no cover |
90 raw_attempts.append(raw_attempt) | 88 raw_attempts.append(raw_attempt) |
91 return raw_attempts | 89 return raw_attempts |
92 | 90 |
93 | 91 |
94 def summarize_attempt(raw_attempt, now): | 92 def summarize_attempt(raw_attempt, now): |
95 assert len(raw_attempt) > 0 | 93 assert len(raw_attempt) > 0 |
96 start_timestamp = to_unix_timestamp(raw_attempt[0].timestamp) | 94 start_timestamp = utils.to_unix_timestamp(raw_attempt[0].timestamp) |
97 summary = blank_attempt_summary() | 95 summary = blank_attempt_summary() |
98 job_tracker = AttemptJobTracker(start_timestamp) | 96 job_tracker = AttemptJobTracker(start_timestamp) |
99 durations = summary['durations'] | 97 durations = summary['durations'] |
100 last_patch_action = None | 98 last_patch_action = None |
101 last_patch_timestamp = None | 99 last_patch_timestamp = None |
102 verifier_start_timestamp = None | 100 verifier_start_timestamp = None |
103 for record in raw_attempt: | 101 for record in raw_attempt: |
104 action = record.fields.get('action') | 102 action = record.fields.get('action') |
105 # patch_ready_to_commit signals are noisy and not useful. | 103 # patch_ready_to_commit signals are noisy and not useful. |
106 if action == 'patch_ready_to_commit': | 104 if action == 'patch_ready_to_commit': |
107 continue | 105 continue |
108 verifier = record.fields.get('verifier') | 106 verifier = record.fields.get('verifier') |
109 timestamp = to_unix_timestamp(record.timestamp) | 107 timestamp = utils.to_unix_timestamp(record.timestamp) |
110 if last_patch_action: | 108 if last_patch_action: |
111 patch_state_duration = timestamp - last_patch_timestamp | 109 patch_state_duration = timestamp - last_patch_timestamp |
112 | 110 |
113 # Verifier job updates. | 111 # Verifier job updates. |
114 if verifier == TRYJOBVERIFIER: | 112 if verifier == TRYJOBVERIFIER: |
115 if action == 'verifier_start': | 113 if action == 'verifier_start': |
116 verifier_start_timestamp = timestamp | 114 verifier_start_timestamp = timestamp |
117 elif action == 'verifier_jobs_update': | 115 elif action == 'verifier_jobs_update': |
118 job_tracker.update_jobs(record) | 116 job_tracker.update_jobs(record) |
119 elif (action in ('verifier_pass', 'verifier_fail') and | 117 elif (action in ('verifier_pass', 'verifier_fail') and |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 return min(iterable) | 289 return min(iterable) |
292 except ValueError: # pragma: no cover | 290 except ValueError: # pragma: no cover |
293 return None | 291 return None |
294 | 292 |
295 | 293 |
296 def maybe_max(iterable): | 294 def maybe_max(iterable): |
297 try: | 295 try: |
298 return max(iterable) | 296 return max(iterable) |
299 except ValueError: # pragma: no cover | 297 except ValueError: # pragma: no cover |
300 return None | 298 return None |
OLD | NEW |