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

Side by Side Diff: appengine/findit/handlers/flake/check_flake.py

Issue 2438673004: [Findit] Post analysis results of flakes to bug filed by chromium-try-flakes. (Closed)
Patch Set: Created 4 years, 2 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 unified diff | Download patch
OLDNEW
1 # Copyright 2016 The Chromium Authors. All rights reserved. 1 # Copyright 2016 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 google.appengine.api import users 5 from google.appengine.api import users
6 from google.appengine.ext import ndb
6 7
7 from common import auth_util 8 from common import auth_util
8 from common import constants 9 from common import constants
9 from common import time_util 10 from common import time_util
10 from common.base_handler import BaseHandler 11 from common.base_handler import BaseHandler
11 from common.base_handler import Permission 12 from common.base_handler import Permission
12 from model import analysis_status 13 from model import analysis_status
13 from waterfall.flake import initialize_flake_pipeline 14 from waterfall.flake import initialize_flake_pipeline
15 from waterfall.test_info import TestInfo
14 16
15 17
16 class CheckFlake(BaseHandler): 18 class CheckFlake(BaseHandler):
17 PERMISSION_LEVEL = Permission.ANYONE 19 PERMISSION_LEVEL = Permission.ANYONE
18 20
19 def HandleGet(self): 21 def HandleGet(self):
20 master_name = self.request.get('master_name').strip() 22 key = self.request.get('key')
21 builder_name = self.request.get('builder_name').strip() 23 if key:
22 build_number = int(self.request.get('build_number', '0').strip()) 24 analysis = ndb.Key(urlsafe=key).get()
23 step_name = self.request.get('step_name').strip() 25 if not analysis: # pragma: no cover
24 test_name = self.request.get('test_name').strip() 26 return self.CreateError('Analysis of flake is not found', 404)
27 else:
28 master_name = self.request.get('master_name').strip()
29 builder_name = self.request.get('builder_name').strip()
30 build_number = int(self.request.get('build_number', '0').strip())
31 step_name = self.request.get('step_name').strip()
32 test_name = self.request.get('test_name').strip()
25 33
26 if not (master_name and builder_name and build_number and 34 if not (master_name and builder_name and build_number and
27 step_name and test_name): # pragma: no cover. 35 step_name and test_name): # pragma: no cover.
28 return self.CreateError( 36 return self.CreateError(
29 'Invalid value of master/builder/build_number/step/test', 400) 37 'Invalid value of master/builder/build_number/step/test', 400)
30 38
31 force = (auth_util.IsCurrentUserAdmin() and 39 force = (auth_util.IsCurrentUserAdmin() and
32 self.request.get('force') == '1') 40 self.request.get('force') == '1')
33 allow_new_analysis = self.IsCorpUserOrAdmin() 41 allow_new_analysis = self.IsCorpUserOrAdmin()
34 42
35 analysis = initialize_flake_pipeline.ScheduleAnalysisIfNeeded( 43 test = TestInfo(
36 master_name, builder_name, build_number, step_name, test_name, 44 master_name, builder_name, build_number, step_name, test_name)
37 allow_new_analysis, force=force, manually_triggered=True, 45 analysis = initialize_flake_pipeline.ScheduleAnalysisIfNeeded(
38 queue_name=constants.WATERFALL_ANALYSIS_QUEUE) 46 test, test, allow_new_analysis=allow_new_analysis, force=force,
lijeffrey 2016/10/21 17:10:27 nit: Just so this doesn't look like a typo (becaus
stgao 2016/10/21 22:42:33 Done.
chanli 2016/10/21 23:23:08 So when does the normalization happen? For example
stgao 2016/10/22 00:15:09 The "PRE_" is a TODO on your end; it's up to you w
47 manually_triggered=True,
48 queue_name=constants.WATERFALL_ANALYSIS_QUEUE)
39 49
40 if not analysis: # pragma: no cover. 50 if not analysis: # pragma: no cover.
41 return { 51 return {
42 'template': 'error.html', 52 'template': 'error.html',
43 'data': { 53 'data': {
44 'error_message': 54 'error_message':
45 ('You could schedule an analysis for flaky test only after ' 55 ('You could schedule an analysis for flaky test only after '
46 'you login with google.com account.'), 56 'you login with google.com account.'),
47 'login_url': self.GetLoginUrl(), 57 'login_url': self.GetLoginUrl(),
48 }, 58 },
49 'return_code': 401, 59 'return_code': 401,
50 } 60 }
51 61
52 data = { 62 data = {
53 'pass_rates': [], 63 'pass_rates': [],
54 'analysis_status': analysis.status_description, 64 'analysis_status': analysis.status_description,
55 'suspected_flake_build_number': ( 65 'suspected_flake_build_number': (
56 analysis.suspected_flake_build_number), 66 analysis.suspected_flake_build_number),
57 'master_name': master_name, 67 'master_name': analysis.master_name,
58 'builder_name': builder_name, 68 'builder_name': analysis.builder_name,
59 'build_number': build_number, 69 'build_number': analysis.build_number,
60 'step_name': step_name, 70 'step_name': analysis.step_name,
61 'test_name': test_name, 71 'test_name': analysis.test_name,
62 'request_time': time_util.FormatDatetime( 72 'request_time': time_util.FormatDatetime(
63 analysis.request_time), 73 analysis.request_time),
64 'task_number': len(analysis.data_points), 74 'task_number': len(analysis.data_points),
65 'error': analysis.error_message, 75 'error': analysis.error_message,
66 'iterations_to_rerun': analysis.iterations_to_rerun, 76 'iterations_to_rerun': analysis.iterations_to_rerun,
67 } 77 }
68 78
69 data['pending_time'] = time_util.FormatDuration( 79 data['pending_time'] = time_util.FormatDuration(
70 analysis.request_time, 80 analysis.request_time,
71 analysis.start_time or time_util.GetUTCNow()) 81 analysis.start_time or time_util.GetUTCNow())
72 if analysis.status != analysis_status.PENDING: 82 if analysis.status != analysis_status.PENDING:
73 data['duration'] = time_util.FormatDuration( 83 data['duration'] = time_util.FormatDuration(
74 analysis.start_time, 84 analysis.start_time,
75 analysis.end_time or time_util.GetUTCNow()) 85 analysis.end_time or time_util.GetUTCNow())
76 86
77 coordinates = [] 87 coordinates = []
78 for data_point in analysis.data_points: 88 for data_point in analysis.data_points:
79 coordinates.append([data_point.build_number, data_point.pass_rate]) 89 coordinates.append([data_point.build_number, data_point.pass_rate])
80 90
81 # Order by build number from earliest to latest. 91 # Order by build number from earliest to latest.
82 coordinates.sort(key=lambda x: x[0]) 92 coordinates.sort(key=lambda x: x[0])
83 93
84 data['pass_rates'] = coordinates 94 data['pass_rates'] = coordinates
85 return { 95 return {
86 'template': 'flake/result.html', 96 'template': 'flake/result.html',
87 'data': data 97 'data': data
88 } 98 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698