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

Side by Side Diff: appengine/findit/crash/crash_pipeline.py

Issue 2455053004: Moving ScheduleNewAnalysis to break the cycle (Closed)
Patch Set: Created 4 years, 1 month 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 import copy 5 import copy
6 import json 6 import json
7 import logging 7 import logging
8 8
9 from common import appengine_util 9 from common import appengine_util
10 from common import git_repository 10 from common import git_repository
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 if client_id == CrashClient.FRACAS: 42 if client_id == CrashClient.FRACAS:
43 cls = findit_for_chromecrash.FinditForFracas 43 cls = findit_for_chromecrash.FinditForFracas
44 elif client_id == CrashClient.CRACAS: 44 elif client_id == CrashClient.CRACAS:
45 cls = findit_for_chromecrash.FinditForCracas 45 cls = findit_for_chromecrash.FinditForCracas
46 elif client_id == CrashClient.CLUSTERFUZZ: 46 elif client_id == CrashClient.CLUSTERFUZZ:
47 cls = findit_for_clusterfuzz.FinditForClusterfuzz 47 cls = findit_for_clusterfuzz.FinditForClusterfuzz
48 else: 48 else:
49 raise ValueError('FinditForClientID: ' 49 raise ValueError('FinditForClientID: '
50 'unknown or unsupported client %s' % client_id) 50 'unknown or unsupported client %s' % client_id)
51 51
52 return cls( 52 return cls(git_repository.GitRepository(http_client=HttpClientAppengine()))
53 git_repository.GitRepository(http_client=HttpClientAppengine()),
54 CrashWrapperPipeline)
55 53
56 54
57 # Some notes about the classes below, for people who are not 55 # Some notes about the classes below, for people who are not
58 # familiar with AppEngine. The thing that really kicks everything off 56 # familiar with AppEngine. The thing that really kicks everything off
59 # is |CrashWrapperPipeline.run|. However, an important thing to bear in 57 # is |CrashWrapperPipeline.run|. However, an important thing to bear in
60 # mind is that whatever arguments are passed to that method will also 58 # mind is that whatever arguments are passed to that method will also
61 # be passed to the |run| method on whatever objects it yields. Thus, 59 # be passed to the |run| method on whatever objects it yields. Thus,
62 # all the |run| methods across these different classes must have the same 60 # all the |run| methods across these different classes must have the same
63 # type. In practice, we end up passing all the arguments to the 61 # type. In practice, we end up passing all the arguments to the
64 # constructors, because we need to have the fields around for logging 62 # constructors, because we need to have the fields around for logging
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 # can't be altered directly. 97 # can't be altered directly.
100 def _PutAbortedError(self): 98 def _PutAbortedError(self):
101 """Update the ndb.Model to indicate that this pipeline was aborted.""" 99 """Update the ndb.Model to indicate that this pipeline was aborted."""
102 logging.error('Aborted analysis for %s', repr(self._crash_identifiers)) 100 logging.error('Aborted analysis for %s', repr(self._crash_identifiers))
103 analysis = self._findit.GetAnalysis(self._crash_identifiers) 101 analysis = self._findit.GetAnalysis(self._crash_identifiers)
104 analysis.status = analysis_status.ERROR 102 analysis.status = analysis_status.ERROR
105 analysis.put() 103 analysis.put()
106 104
107 # TODO(http://crbug.com/659346): we misplaced the coverage test; find it! 105 # TODO(http://crbug.com/659346): we misplaced the coverage test; find it!
108 # Arguments number differs from overridden method - pylint: disable=W0221 106 # Arguments number differs from overridden method - pylint: disable=W0221
109 def run(self): 107 def run(self): # pragma: no cover
Sharu Jiang 2016/10/27 23:55:33 This is wrong... I didn't notice that in your last
wrengr 2016/10/28 18:10:59 This is what I was hoping you'd've set up the mock
Sharu Jiang 2016/11/01 23:03:24 This has been walked around by calling pipeline.ru
wrengr 2016/11/03 18:20:20 Right. Can you adjust the unittests so that they w
110 # TODO(wrengr): shouldn't this method somehow call _NeedsNewAnalysis 108 # TODO(wrengr): shouldn't this method somehow call _NeedsNewAnalysis
111 # to guard against race conditions? 109 # to guard against race conditions?
112 analysis = self._findit.GetAnalysis(self._crash_identifiers) 110 analysis = self._findit.GetAnalysis(self._crash_identifiers)
113 111
114 # Update the model's status to say we're in the process of doing analysis. 112 # Update the model's status to say we're in the process of doing analysis.
115 analysis.pipeline_status_path = self.pipeline_status_path() 113 analysis.pipeline_status_path = self.pipeline_status_path()
116 analysis.status = analysis_status.RUNNING 114 analysis.status = analysis_status.RUNNING
117 analysis.started_time = time_util.GetUTCNow() 115 analysis.started_time = time_util.GetUTCNow()
118 analysis.findit_version = appengine_util.GetCurrentVersion() 116 analysis.findit_version = appengine_util.GetCurrentVersion()
119 analysis.put() 117 analysis.put()
(...skipping 12 matching lines...) Expand all
132 analysis.put() 130 analysis.put()
133 131
134 132
135 class PublishResultPipeline(CrashBasePipeline): 133 class PublishResultPipeline(CrashBasePipeline):
136 # TODO(http://crbug.com/659346): we misplaced the coverage test; find it! 134 # TODO(http://crbug.com/659346): we misplaced the coverage test; find it!
137 def finalized(self): 135 def finalized(self):
138 if self.was_aborted: # pragma: no cover. 136 if self.was_aborted: # pragma: no cover.
139 logging.error('Failed to publish %s analysis result for %s', 137 logging.error('Failed to publish %s analysis result for %s',
140 repr(self._crash_identifiers), self.client_id) 138 repr(self._crash_identifiers), self.client_id)
141 139
140 # TODO(http://crbug.com/659346): we misplaced the coverage test; find it!
142 # Arguments number differs from overridden method - pylint: disable=W0221 141 # Arguments number differs from overridden method - pylint: disable=W0221
143 def run(self): 142 def run(self): # pragma: no cover
Sharu Jiang 2016/10/27 23:55:33 We'd better avoid "pragma: no cover" big block of
wrengr 2016/10/28 18:10:59 I agree. Alas, this was necessary for CQ to accept
Sharu Jiang 2016/11/01 23:03:24 For a better testing, we should cover this code in
wrengr 2016/11/03 18:20:20 I agree. You know more about how to mock pipeline
144 analysis = self._findit.GetAnalysis(self._crash_identifiers) 143 analysis = self._findit.GetAnalysis(self._crash_identifiers)
145 result = analysis.ToPublishableResult(self._crash_identifiers) 144 result = analysis.ToPublishableResult(self._crash_identifiers)
146 messages_data = [json.dumps(result, sort_keys=True)] 145 messages_data = [json.dumps(result, sort_keys=True)]
147 146
148 # TODO(http://crbug.com/659354): remove Findit's dependency on CrashConfig. 147 # TODO(http://crbug.com/659354): remove Findit's dependency on CrashConfig.
149 client_config = self._findit.config 148 client_config = self._findit.config
150 # TODO(katesonia): Clean string uses in config. 149 # TODO(katesonia): Clean string uses in config.
151 topic = client_config['analysis_result_pubsub_topic'] 150 topic = client_config['analysis_result_pubsub_topic']
152 pubsub_util.PublishMessagesToTopic(messages_data, topic) 151 pubsub_util.PublishMessagesToTopic(messages_data, topic)
153 logging.info('Published %s analysis result for %s', self.client_id, 152 logging.info('Published %s analysis result for %s', self.client_id,
154 repr(self._crash_identifiers)) 153 repr(self._crash_identifiers))
155 154
156 155
157 class CrashWrapperPipeline(BasePipeline): 156 class CrashWrapperPipeline(BasePipeline):
158 """Fire off pipelines to (1) do the analysis and (2) publish results. 157 """Fire off pipelines to (1) do the analysis and (2) publish results.
159 158
160 The reason we have analysis and publishing as separate pipelines is 159 The reason we have analysis and publishing as separate pipelines is
161 because each of them can fail for independent reasons. E.g., if we 160 because each of them can fail for independent reasons. E.g., if we
162 successfully finish the analysis, but then the publishing fails due to 161 successfully finish the analysis, but then the publishing fails due to
163 network errors, we don't want to have to redo the analysis in order 162 network errors, we don't want to have to redo the analysis in order
164 to redo the publishing. We could try to cache the fact that analysis 163 to redo the publishing. We could try to cache the fact that analysis
165 succeeded in the pipeline object itself, but we'd have to be careful 164 succeeded in the pipeline object itself, but we'd have to be careful
166 because the |run| and |finalized| methods are executed in different 165 because the |run| and |finalized| methods are executed in different
167 processes. 166 processes.
168 """ 167 """
169 def __init__(self, client_id, crash_identifiers): 168 # TODO(http://crbug.com/659346): we misplaced the coverage test; find it!
169 def __init__(self, client_id, crash_identifiers): # pragma: no cover
170 super(CrashWrapperPipeline, self).__init__(client_id, crash_identifiers) 170 super(CrashWrapperPipeline, self).__init__(client_id, crash_identifiers)
171 self._crash_identifiers = crash_identifiers 171 self._crash_identifiers = crash_identifiers
172 self._client_id = client_id 172 self._client_id = client_id
173 173
174 # TODO(http://crbug.com/659346): write coverage tests. 174 # TODO(http://crbug.com/659346): write coverage tests.
175 # Arguments number differs from overridden method - pylint: disable=W0221 175 # Arguments number differs from overridden method - pylint: disable=W0221
176 def run(self): # pragma: no cover 176 def run(self): # pragma: no cover
177 run_analysis = yield CrashAnalysisPipeline( 177 run_analysis = yield CrashAnalysisPipeline(
178 self._client_id, self._crash_identifiers) 178 self._client_id, self._crash_identifiers)
179 with pipeline.After(run_analysis): 179 with pipeline.After(run_analysis):
180 yield PublishResultPipeline(self._client_id, self._crash_identifiers) 180 yield PublishResultPipeline(self._client_id, self._crash_identifiers)
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/crash/findit.py » ('j') | appengine/findit/crash/test/crash_pipeline_test.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698