| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 """URL endpoint to add new graph data to the datastore.""" | 5 """URL endpoint to add new graph data to the datastore.""" |
| 6 | 6 |
| 7 import datetime | 7 import datetime |
| 8 import json | 8 import json |
| 9 import logging | 9 import logging |
| 10 | 10 |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 | 171 |
| 172 Raises: | 172 Raises: |
| 173 RuntimeError: Something went wrong when trying to get the parent test. | 173 RuntimeError: Something went wrong when trying to get the parent test. |
| 174 """ | 174 """ |
| 175 master_name = row_dict.get('master') | 175 master_name = row_dict.get('master') |
| 176 bot_name = row_dict.get('bot') | 176 bot_name = row_dict.get('bot') |
| 177 test_name = row_dict.get('test').strip('/') | 177 test_name = row_dict.get('test').strip('/') |
| 178 units = row_dict.get('units') | 178 units = row_dict.get('units') |
| 179 higher_is_better = row_dict.get('higher_is_better') | 179 higher_is_better = row_dict.get('higher_is_better') |
| 180 improvement_direction = _ImprovementDirection(higher_is_better) | 180 improvement_direction = _ImprovementDirection(higher_is_better) |
| 181 internal_only = _BotInternalOnly(bot_name, bot_whitelist) | 181 internal_only = BotInternalOnly(bot_name, bot_whitelist) |
| 182 benchmark_description = row_dict.get('benchmark_description') | 182 benchmark_description = row_dict.get('benchmark_description') |
| 183 | 183 |
| 184 parent_test = _GetOrCreateAncestors( | 184 parent_test = GetOrCreateAncestors( |
| 185 master_name, bot_name, test_name, units=units, | 185 master_name, bot_name, test_name, internal_only=internal_only, |
| 186 improvement_direction=improvement_direction, | 186 benchmark_description=benchmark_description, units=units, |
| 187 internal_only=internal_only, | 187 improvement_direction=improvement_direction) |
| 188 benchmark_description=benchmark_description) | |
| 189 | 188 |
| 190 return parent_test | 189 return parent_test |
| 191 | 190 |
| 192 | 191 |
| 193 def _ImprovementDirection(higher_is_better): | 192 def _ImprovementDirection(higher_is_better): |
| 194 """Returns an improvement direction (constant from alerts_data) or None.""" | 193 """Returns an improvement direction (constant from alerts_data) or None.""" |
| 195 if higher_is_better is None: | 194 if higher_is_better is None: |
| 196 return None | 195 return None |
| 197 return anomaly.UP if higher_is_better else anomaly.DOWN | 196 return anomaly.UP if higher_is_better else anomaly.DOWN |
| 198 | 197 |
| 199 | 198 |
| 200 def _BotInternalOnly(bot_name, bot_whitelist): | 199 def BotInternalOnly(bot_name, bot_whitelist): |
| 201 """Checks whether a given bot name is internal-only. | 200 """Checks whether a given bot name is internal-only. |
| 202 | 201 |
| 203 If a bot name is internal only, then new data for that bot should be marked | 202 If a bot name is internal only, then new data for that bot should be marked |
| 204 as internal-only. | 203 as internal-only. |
| 205 """ | 204 """ |
| 206 if not bot_whitelist: | 205 if not bot_whitelist: |
| 207 logging.warning( | 206 logging.warning( |
| 208 'No bot whitelist available. All data will be internal-only. If this ' | 207 'No bot whitelist available. All data will be internal-only. If this ' |
| 209 'is not intended, please add a bot whitelist using /edit_site_config.') | 208 'is not intended, please add a bot whitelist using /edit_site_config.') |
| 210 return True | 209 return True |
| 211 return bot_name not in bot_whitelist | 210 return bot_name not in bot_whitelist |
| 212 | 211 |
| 213 | 212 |
| 214 def _GetOrCreateAncestors( | 213 def GetOrCreateAncestors( |
| 215 master_name, bot_name, test_name, units=None, | 214 master_name, bot_name, test_name, internal_only=True, |
| 216 improvement_direction=None, internal_only=True, benchmark_description=''): | 215 benchmark_description='', units=None, improvement_direction=None): |
| 217 """Gets or creates all parent Master, Bot, TestMetadata entities for a Row.""" | 216 """Gets or creates all parent Master, Bot, TestMetadata entities for a Row.""" |
| 218 | 217 |
| 219 master_entity = _GetOrCreateMaster(master_name) | 218 master_entity = _GetOrCreateMaster(master_name) |
| 220 _GetOrCreateBot(bot_name, master_entity.key, internal_only) | 219 _GetOrCreateBot(bot_name, master_entity.key, internal_only) |
| 221 | 220 |
| 222 # Add all ancestor tests to the datastore in order. | 221 # Add all ancestor tests to the datastore in order. |
| 223 ancestor_test_parts = test_name.split('/') | 222 ancestor_test_parts = test_name.split('/') |
| 224 | 223 |
| 225 test_path = '%s/%s' % (master_name, bot_name) | 224 test_path = '%s/%s' % (master_name, bot_name) |
| 226 suite = None | 225 suite = None |
| 227 for index, ancestor_test_name in enumerate(ancestor_test_parts): | 226 for index, ancestor_test_name in enumerate(ancestor_test_parts): |
| 228 # Certain properties should only be updated if the TestMetadata is for a | 227 # Certain properties should only be updated if the TestMetadata is for a |
| 229 # leaf test. | 228 # leaf test. |
| 230 is_leaf_test = (index == len(ancestor_test_parts) - 1) | 229 is_leaf_test = (index == len(ancestor_test_parts) - 1) |
| 231 test_properties = { | 230 test_properties = { |
| 232 'units': units if is_leaf_test else None, | 231 'units': units if is_leaf_test else None, |
| 233 'improvement_direction': (improvement_direction | |
| 234 if is_leaf_test else None), | |
| 235 'internal_only': internal_only, | 232 'internal_only': internal_only, |
| 236 } | 233 } |
| 234 if is_leaf_test and improvement_direction is not None: |
| 235 test_properties['improvement_direction'] = improvement_direction |
| 237 ancestor_test = _GetOrCreateTest( | 236 ancestor_test = _GetOrCreateTest( |
| 238 ancestor_test_name, test_path, test_properties) | 237 ancestor_test_name, test_path, test_properties) |
| 239 if index == 0: | 238 if index == 0: |
| 240 suite = ancestor_test | 239 suite = ancestor_test |
| 241 test_path = ancestor_test.test_path | 240 test_path = ancestor_test.test_path |
| 242 if benchmark_description and suite.description != benchmark_description: | 241 if benchmark_description and suite.description != benchmark_description: |
| 243 suite.description = benchmark_description | 242 suite.description = benchmark_description |
| 244 return ancestor_test | 243 return ancestor_test |
| 245 | 244 |
| 246 | 245 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 290 An entity (which has already been put). | 289 An entity (which has already been put). |
| 291 | 290 |
| 292 Raises: | 291 Raises: |
| 293 datastore_errors.BadRequestError: Something went wrong getting the entity. | 292 datastore_errors.BadRequestError: Something went wrong getting the entity. |
| 294 """ | 293 """ |
| 295 test_path = '%s/%s' % (parent_test_path, name) | 294 test_path = '%s/%s' % (parent_test_path, name) |
| 296 existing = graph_data.TestMetadata.get_by_id(test_path) | 295 existing = graph_data.TestMetadata.get_by_id(test_path) |
| 297 | 296 |
| 298 if not existing: | 297 if not existing: |
| 299 # Add improvement direction if this is a new test. | 298 # Add improvement direction if this is a new test. |
| 300 if 'units' in properties: | 299 if 'units' in properties and 'improvement_direction' not in properties: |
| 301 units = properties['units'] | 300 units = properties['units'] |
| 302 direction = units_to_direction.GetImprovementDirection(units) | 301 direction = units_to_direction.GetImprovementDirection(units) |
| 303 properties['improvement_direction'] = direction | 302 properties['improvement_direction'] = direction |
| 303 elif 'units' not in properties or properties['units'] is None: |
| 304 properties['improvement_direction'] = anomaly.UNKNOWN |
| 305 else: |
| 306 print properties |
| 304 new_entity = graph_data.TestMetadata(id=test_path, **properties) | 307 new_entity = graph_data.TestMetadata(id=test_path, **properties) |
| 305 new_entity.put() | 308 new_entity.put() |
| 306 # TODO(sullivan): Consider putting back Test entity in a scoped down | 309 # TODO(sullivan): Consider putting back Test entity in a scoped down |
| 307 # form so we can check if it exists here. | 310 # form so we can check if it exists here. |
| 308 return new_entity | 311 return new_entity |
| 309 | 312 |
| 310 # Flag indicating whether we want to re-put the entity before returning. | 313 # Flag indicating whether we want to re-put the entity before returning. |
| 311 properties_changed = False | 314 properties_changed = False |
| 312 | 315 |
| 313 if existing.deprecated: | 316 if existing.deprecated: |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 | 349 |
| 347 if properties_changed: | 350 if properties_changed: |
| 348 existing.put() | 351 existing.put() |
| 349 return existing | 352 return existing |
| 350 | 353 |
| 351 | 354 |
| 352 def _IsRefBuild(test_key): | 355 def _IsRefBuild(test_key): |
| 353 """Checks whether a TestMetadata is for a reference build test run.""" | 356 """Checks whether a TestMetadata is for a reference build test run.""" |
| 354 test_parts = test_key.id().split('/') | 357 test_parts = test_key.id().split('/') |
| 355 return test_parts[-1] == 'ref' or test_parts[-1].endswith('_ref') | 358 return test_parts[-1] == 'ref' or test_parts[-1].endswith('_ref') |
| OLD | NEW |