| 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 from datetime import datetime | 5 from datetime import datetime |
| 6 import json | 6 import json |
| 7 import mock | 7 import mock |
| 8 import time | 8 import time |
| 9 | 9 |
| 10 from common.waterfall import buildbucket_client | 10 from common.waterfall import buildbucket_client |
| 11 from common.waterfall import failure_type |
| 11 from common.waterfall import try_job_error | 12 from common.waterfall import try_job_error |
| 12 from common.waterfall import failure_type | |
| 13 from model import analysis_status | 13 from model import analysis_status |
| 14 from model.flake.flake_try_job import FlakeTryJob | 14 from model.flake.flake_try_job import FlakeTryJob |
| 15 from model.flake.flake_try_job_data import FlakeTryJobData |
| 15 from model.wf_try_job import WfTryJob | 16 from model.wf_try_job import WfTryJob |
| 16 from model.wf_try_job_data import WfTryJobData | 17 from model.wf_try_job_data import WfTryJobData |
| 17 from waterfall import monitor_try_job_pipeline | 18 from waterfall import monitor_try_job_pipeline |
| 18 from waterfall import waterfall_config | 19 from waterfall import waterfall_config |
| 19 from waterfall.monitor_try_job_pipeline import MonitorTryJobPipeline | 20 from waterfall.monitor_try_job_pipeline import MonitorTryJobPipeline |
| 20 from waterfall.test import wf_testcase | 21 from waterfall.test import wf_testcase |
| 21 | 22 |
| 22 | 23 |
| 23 class MonitorTryJobPipelineTest(wf_testcase.WaterfallTestCase): | 24 class MonitorTryJobPipelineTest(wf_testcase.WaterfallTestCase): |
| 24 | 25 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 52 {'a': 1}, | 53 {'a': 1}, |
| 53 {'a': 1, 'b': 2})) | 54 {'a': 1, 'b': 2})) |
| 54 | 55 |
| 55 def testUpdateTryJobMetadataForBuildError(self): | 56 def testUpdateTryJobMetadataForBuildError(self): |
| 56 error_data = { | 57 error_data = { |
| 57 'reason': 'BUILD_NOT_FOUND', | 58 'reason': 'BUILD_NOT_FOUND', |
| 58 'message': 'message' | 59 'message': 'message' |
| 59 } | 60 } |
| 60 error = buildbucket_client.BuildbucketError(error_data) | 61 error = buildbucket_client.BuildbucketError(error_data) |
| 61 try_job_data = WfTryJobData.Create('1') | 62 try_job_data = WfTryJobData.Create('1') |
| 63 try_job_data.try_job_key = WfTryJob.Create('m', 'b', 123).key |
| 62 | 64 |
| 63 monitor_try_job_pipeline._UpdateTryJobMetadata( | 65 monitor_try_job_pipeline._UpdateTryJobMetadata( |
| 64 try_job_data, None, None, error, False) | 66 try_job_data, failure_type.COMPILE, None, None, error, False) |
| 65 self.assertEqual(try_job_data.error, error_data) | 67 self.assertEqual(try_job_data.error, error_data) |
| 66 | 68 |
| 67 def testUpdateTryJobMetadata(self): | 69 def testUpdateTryJobMetadata(self): |
| 68 try_job_id = '1' | 70 try_job_id = '1' |
| 69 url = 'url' | 71 url = 'url' |
| 70 build_data = { | 72 build_data = { |
| 71 'id': try_job_id, | 73 'id': try_job_id, |
| 72 'url': url, | 74 'url': url, |
| 73 'status': 'COMPLETED', | 75 'status': 'COMPLETED', |
| 74 'completed_ts': '1454367574000000', | 76 'completed_ts': '1454367574000000', |
| (...skipping 13 matching lines...) Expand all Loading... |
| 88 }) | 90 }) |
| 89 } | 91 } |
| 90 build = buildbucket_client.BuildbucketBuild(build_data) | 92 build = buildbucket_client.BuildbucketBuild(build_data) |
| 91 expected_error_dict = { | 93 expected_error_dict = { |
| 92 'message': 'Try job monitoring was abandoned.', | 94 'message': 'Try job monitoring was abandoned.', |
| 93 'reason': ('Timeout after %s hours' % | 95 'reason': ('Timeout after %s hours' % |
| 94 waterfall_config.GetTryJobSettings().get( | 96 waterfall_config.GetTryJobSettings().get( |
| 95 'job_timeout_hours')) | 97 'job_timeout_hours')) |
| 96 } | 98 } |
| 97 try_job_data = WfTryJobData.Create(try_job_id) | 99 try_job_data = WfTryJobData.Create(try_job_id) |
| 100 try_job_data.try_job_key = WfTryJob.Create('m', 'b', 123).key |
| 98 | 101 |
| 99 monitor_try_job_pipeline._UpdateTryJobMetadata( | 102 monitor_try_job_pipeline._UpdateTryJobMetadata( |
| 100 try_job_data, None, build, None, False) | 103 try_job_data, failure_type.COMPILE, None, build, None, False) |
| 101 try_job_data = WfTryJobData.Get(try_job_id) | 104 try_job_data = WfTryJobData.Get(try_job_id) |
| 102 self.assertIsNone(try_job_data.error) | 105 self.assertIsNone(try_job_data.error) |
| 103 self.assertEqual(try_job_data.regression_range_size, 2) | 106 self.assertEqual(try_job_data.regression_range_size, 2) |
| 104 self.assertEqual(try_job_data.number_of_commits_analyzed, 2) | 107 self.assertEqual(try_job_data.number_of_commits_analyzed, 2) |
| 105 self.assertEqual(try_job_data.end_time, datetime(2016, 2, 1, 22, 59, 34)) | 108 self.assertEqual(try_job_data.end_time, datetime(2016, 2, 1, 22, 59, 34)) |
| 106 self.assertEqual(try_job_data.request_time, | 109 self.assertEqual(try_job_data.request_time, |
| 107 datetime(2016, 2, 1, 22, 59, 30)) | 110 datetime(2016, 2, 1, 22, 59, 30)) |
| 108 self.assertEqual(try_job_data.try_job_url, url) | 111 self.assertEqual(try_job_data.try_job_url, url) |
| 109 | 112 |
| 110 monitor_try_job_pipeline._UpdateTryJobMetadata( | 113 monitor_try_job_pipeline._UpdateTryJobMetadata( |
| 111 try_job_data, None, build, None, True) | 114 try_job_data, failure_type.COMPILE, None, build, None, True) |
| 112 self.assertEqual(try_job_data.error, expected_error_dict) | 115 self.assertEqual(try_job_data.error, expected_error_dict) |
| 113 self.assertEqual(try_job_data.error_code, try_job_error.TIMEOUT) | 116 self.assertEqual(try_job_data.error_code, try_job_error.TIMEOUT) |
| 114 | 117 |
| 115 @mock.patch.object(monitor_try_job_pipeline, 'buildbucket_client') | 118 @mock.patch.object(monitor_try_job_pipeline, 'buildbucket_client') |
| 116 def testGetTryJobsForCompileSuccess(self, mock_module): | 119 def testGetTryJobsForCompileSuccess(self, mock_module): |
| 117 master_name = 'm' | 120 master_name = 'm' |
| 118 builder_name = 'b' | 121 builder_name = 'b' |
| 119 build_number = 1 | 122 build_number = 1 |
| 120 try_job_id = '1' | 123 try_job_id = '1' |
| 121 regression_range_size = 2 | 124 regression_range_size = 2 |
| 122 | 125 |
| 123 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 126 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 124 try_job_data = WfTryJobData.Create(try_job_id) | 127 try_job_data = WfTryJobData.Create(try_job_id) |
| 128 try_job_data.try_job_key = try_job.key |
| 125 try_job_data.put() | 129 try_job_data.put() |
| 126 try_job.compile_results = [ | 130 try_job.compile_results = [ |
| 127 { | 131 { |
| 128 'report': None, | 132 'report': None, |
| 129 'url': 'url', | 133 'url': 'url', |
| 130 'try_job_id': '1', | 134 'try_job_id': '1', |
| 131 } | 135 } |
| 132 ] | 136 ] |
| 133 try_job.status = analysis_status.RUNNING | 137 try_job.status = analysis_status.RUNNING |
| 134 try_job.put() | 138 try_job.put() |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 { | 197 { |
| 194 'report': None, | 198 'report': None, |
| 195 'url': 'url', | 199 'url': 'url', |
| 196 'try_job_id': try_job_id, | 200 'try_job_id': try_job_id, |
| 197 } | 201 } |
| 198 ] | 202 ] |
| 199 try_job.status = analysis_status.RUNNING | 203 try_job.status = analysis_status.RUNNING |
| 200 try_job.put() | 204 try_job.put() |
| 201 | 205 |
| 202 try_job_data = WfTryJobData.Create(try_job_id) | 206 try_job_data = WfTryJobData.Create(try_job_id) |
| 207 try_job_data.try_job_key = try_job.key |
| 203 try_job_data.put() | 208 try_job_data.put() |
| 204 | 209 |
| 205 data = [ | 210 data = [ |
| 206 { | 211 { |
| 207 'build': { | 212 'build': { |
| 208 'id': '3', | 213 'id': '3', |
| 209 'url': 'url', | 214 'url': 'url', |
| 210 'status': 'STARTED' | 215 'status': 'STARTED' |
| 211 } | 216 } |
| 212 }, | 217 }, |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 291 }, | 296 }, |
| 292 'url': 'url', | 297 'url': 'url', |
| 293 'try_job_id': '3', | 298 'try_job_id': '3', |
| 294 } | 299 } |
| 295 self.assertEqual(expected_test_result, test_result) | 300 self.assertEqual(expected_test_result, test_result) |
| 296 | 301 |
| 297 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 302 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 298 self.assertEqual(expected_test_result, try_job.test_results[-1]) | 303 self.assertEqual(expected_test_result, try_job.test_results[-1]) |
| 299 self.assertEqual(analysis_status.RUNNING, try_job.status) | 304 self.assertEqual(analysis_status.RUNNING, try_job.status) |
| 300 | 305 |
| 306 @mock.patch.object(monitor_try_job_pipeline, 'buildbucket_client') |
| 307 def testGetTryJobsForFlakeSuccess(self, mock_module): |
| 308 master_name = 'm' |
| 309 builder_name = 'b' |
| 310 step_name = 's' |
| 311 test_name = 't' |
| 312 git_hash = 'a1b2c3d4' |
| 313 try_job_id = '1' |
| 314 |
| 315 try_job = FlakeTryJob.Create( |
| 316 master_name, builder_name, step_name, test_name, git_hash) |
| 317 try_job.flake_results = [ |
| 318 { |
| 319 'report': None, |
| 320 'url': 'url', |
| 321 'try_job_id': '1', |
| 322 } |
| 323 ] |
| 324 try_job.status = analysis_status.RUNNING |
| 325 try_job.put() |
| 326 |
| 327 try_job_data = FlakeTryJobData.Create(try_job_id) |
| 328 try_job_data.try_job_key = try_job.key |
| 329 try_job_data.put() |
| 330 |
| 331 build_response = { |
| 332 'id': '1', |
| 333 'url': 'url', |
| 334 'status': 'COMPLETED', |
| 335 'result_details_json': json.dumps({ |
| 336 'properties': { |
| 337 'report': { |
| 338 'result': { |
| 339 'r0': { |
| 340 'gl_tests': { |
| 341 'status': 'passed', |
| 342 'valid': True, |
| 343 'pass_fail_counts': { |
| 344 'Test.One': { |
| 345 'pass_count': 100, |
| 346 'fail_count': 0 |
| 347 } |
| 348 } |
| 349 } |
| 350 } |
| 351 } |
| 352 } |
| 353 } |
| 354 }) |
| 355 } |
| 356 |
| 357 mock_module.GetTryJobs.return_value = [ |
| 358 (None, buildbucket_client.BuildbucketBuild(build_response))] |
| 359 |
| 360 pipeline = MonitorTryJobPipeline() |
| 361 flake_result = pipeline.run( |
| 362 try_job.key.urlsafe(), failure_type.FLAKY_TEST, try_job_id) |
| 363 |
| 364 expected_flake_result = { |
| 365 'report': { |
| 366 'result': { |
| 367 'r0': { |
| 368 'gl_tests': { |
| 369 'status': 'passed', |
| 370 'valid': True, |
| 371 'pass_fail_counts': { |
| 372 'Test.One': { |
| 373 'pass_count': 100, |
| 374 'fail_count': 0 |
| 375 } |
| 376 } |
| 377 } |
| 378 } |
| 379 } |
| 380 }, |
| 381 'url': 'url', |
| 382 'try_job_id': '1', |
| 383 } |
| 384 |
| 385 self.assertEqual(expected_flake_result, flake_result) |
| 386 |
| 387 try_job = FlakeTryJob.Get( |
| 388 master_name, builder_name, step_name, test_name, git_hash) |
| 389 self.assertEqual(expected_flake_result, try_job.flake_results[-1]) |
| 390 self.assertEqual(analysis_status.RUNNING, try_job.status) |
| 391 |
| 392 try_job_data = FlakeTryJobData.Get(try_job_id) |
| 393 self.assertEqual(try_job_data.last_buildbucket_response, build_response) |
| 394 |
| 301 def testUpdateTryJobResultAnalyzing(self): | 395 def testUpdateTryJobResultAnalyzing(self): |
| 302 master_name = 'm' | 396 master_name = 'm' |
| 303 builder_name = 'b' | 397 builder_name = 'b' |
| 304 build_number = 1 | 398 build_number = 1 |
| 305 try_job_id = '3' | 399 try_job_id = '3' |
| 306 | 400 |
| 307 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 401 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 308 try_job.put() | 402 try_job.put() |
| 309 | 403 |
| 310 pipeline = MonitorTryJobPipeline() | 404 pipeline = MonitorTryJobPipeline() |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 (expected_error_dict, try_job_error.UNKNOWN)) | 587 (expected_error_dict, try_job_error.UNKNOWN)) |
| 494 | 588 |
| 495 def testReturnNoneIfNoTryJobId(self): | 589 def testReturnNoneIfNoTryJobId(self): |
| 496 master_name = 'm' | 590 master_name = 'm' |
| 497 builder_name = 'b' | 591 builder_name = 'b' |
| 498 build_number = 1 | 592 build_number = 1 |
| 499 pipeline = MonitorTryJobPipeline() | 593 pipeline = MonitorTryJobPipeline() |
| 500 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 594 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 501 test_result = pipeline.run(try_job.key.urlsafe(), failure_type.TEST, None) | 595 test_result = pipeline.run(try_job.key.urlsafe(), failure_type.TEST, None) |
| 502 self.assertIsNone(test_result) | 596 self.assertIsNone(test_result) |
| OLD | NEW |