| OLD | NEW |
| (Empty) | |
| 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 |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import mock |
| 6 |
| 7 from gae_libs.gitiles.cached_gitiles_repository import CachedGitilesRepository |
| 8 from libs.gitiles.change_log import ChangeLog |
| 9 |
| 10 from common import constants |
| 11 from common.pipeline_wrapper import pipeline_handlers |
| 12 from common.waterfall import failure_type |
| 13 from model import analysis_status |
| 14 from model import result_status |
| 15 from model.flake.flake_culprit import FlakeCulprit |
| 16 from model.flake.flake_try_job import FlakeTryJob |
| 17 from model.flake.master_flake_analysis import DataPoint |
| 18 from model.flake.master_flake_analysis import MasterFlakeAnalysis |
| 19 from waterfall.flake import recursive_flake_try_job_pipeline |
| 20 from waterfall.flake.recursive_flake_try_job_pipeline import _CreateCulprit |
| 21 from waterfall.flake.recursive_flake_try_job_pipeline import ( |
| 22 _GetNextCommitPosition) |
| 23 from waterfall.flake.recursive_flake_try_job_pipeline import ( |
| 24 _GetTryJobDataPoints) |
| 25 from waterfall.flake.recursive_flake_try_job_pipeline import ( |
| 26 _UpdateAnalysisTryJobStatusUponCompletion) |
| 27 from waterfall.flake.recursive_flake_try_job_pipeline import ( |
| 28 NextCommitPositionPipeline) |
| 29 from waterfall.flake.recursive_flake_try_job_pipeline import ( |
| 30 RecursiveFlakeTryJobPipeline) |
| 31 from waterfall.test import wf_testcase |
| 32 from waterfall.test.wf_testcase import DEFAULT_CONFIG_DATA |
| 33 |
| 34 |
| 35 def _GenerateDataPoint( |
| 36 pass_rate=None, build_number=None, task_id=None, try_job_id=None, |
| 37 try_job_url=None, commit_position=None, git_hash=None, |
| 38 previous_build_commit_position=None, previous_build_git_hash=None, |
| 39 blame_list=None): |
| 40 data_point = DataPoint() |
| 41 data_point.pass_rate = pass_rate |
| 42 data_point.build_number = build_number |
| 43 data_point.task_id = task_id |
| 44 data_point.try_job_id = try_job_id |
| 45 data_point.try_job_url = try_job_url |
| 46 data_point.commit_position = commit_position |
| 47 data_point.git_hash = git_hash |
| 48 data_point.previous_build_commit_position = previous_build_commit_position |
| 49 data_point.previous_build_git_hash = previous_build_git_hash |
| 50 data_point.blame_list = blame_list if blame_list else [] |
| 51 return data_point |
| 52 |
| 53 |
| 54 class RecursiveFlakeTryJobPipelineTest(wf_testcase.WaterfallTestCase): |
| 55 app_module = pipeline_handlers._APP |
| 56 |
| 57 def testRecursiveFlakeTryJobPipeline(self): |
| 58 master_name = 'm' |
| 59 builder_name = 'b' |
| 60 build_number = 100 |
| 61 step_name = 's' |
| 62 test_name = 't' |
| 63 commit_position = 1000 |
| 64 revision = 'r1000' |
| 65 try_job_id = 'try_job_id' |
| 66 |
| 67 analysis = MasterFlakeAnalysis.Create( |
| 68 master_name, builder_name, build_number, step_name, test_name) |
| 69 analysis.status = analysis_status.COMPLETED |
| 70 analysis.Save() |
| 71 |
| 72 try_job = FlakeTryJob.Create( |
| 73 master_name, builder_name, step_name, test_name, revision) |
| 74 |
| 75 try_job_result = { |
| 76 revision: { |
| 77 step_name: { |
| 78 'status': 'failed', |
| 79 'failures': [test_name], |
| 80 'valid': True, |
| 81 'pass_fail_counts': { |
| 82 'test_name': { |
| 83 'pass_count': 28, |
| 84 'fail_count': 72 |
| 85 } |
| 86 } |
| 87 } |
| 88 } |
| 89 } |
| 90 |
| 91 self.MockPipeline( |
| 92 recursive_flake_try_job_pipeline.ScheduleFlakeTryJobPipeline, |
| 93 try_job_id, |
| 94 expected_args=[master_name, builder_name, step_name, test_name, |
| 95 revision]) |
| 96 self.MockPipeline( |
| 97 recursive_flake_try_job_pipeline.MonitorTryJobPipeline, |
| 98 try_job_result, |
| 99 expected_args=[try_job.key.urlsafe(), failure_type.FLAKY_TEST, |
| 100 try_job_id]) |
| 101 self.MockPipeline( |
| 102 recursive_flake_try_job_pipeline.ProcessFlakeTryJobResultPipeline, |
| 103 None, |
| 104 expected_args=[revision, commit_position, try_job_result, |
| 105 try_job.key.urlsafe(), analysis.key.urlsafe()]) |
| 106 self.MockPipeline( |
| 107 recursive_flake_try_job_pipeline.NextCommitPositionPipeline, |
| 108 '', |
| 109 expected_args=[analysis.key.urlsafe(), try_job.key.urlsafe()]) |
| 110 |
| 111 pipeline = RecursiveFlakeTryJobPipeline( |
| 112 analysis.key.urlsafe(), commit_position, revision) |
| 113 |
| 114 pipeline.start(queue_name=constants.DEFAULT_QUEUE) |
| 115 self.execute_queued_tasks() |
| 116 self.assertIsNotNone( |
| 117 FlakeTryJob.Get(master_name, builder_name, step_name, test_name, |
| 118 revision)) |
| 119 |
| 120 def testRecursiveFlakeTryJobPipelineDoNotStartIfError(self): |
| 121 master_name = 'm' |
| 122 builder_name = 'b' |
| 123 build_number = 100 |
| 124 step_name = 's' |
| 125 test_name = 't' |
| 126 commit_position = 1000 |
| 127 revision = 'r1000' |
| 128 |
| 129 analysis = MasterFlakeAnalysis.Create( |
| 130 master_name, builder_name, build_number, step_name, test_name) |
| 131 analysis.status = analysis_status.ERROR |
| 132 analysis.Save() |
| 133 |
| 134 pipeline = RecursiveFlakeTryJobPipeline( |
| 135 analysis.key.urlsafe(), commit_position, revision) |
| 136 |
| 137 pipeline.start(queue_name=constants.DEFAULT_QUEUE) |
| 138 self.execute_queued_tasks() |
| 139 self.assertIsNone(analysis.try_job_status) |
| 140 |
| 141 def testNextCommitPositionPipeline(self, *_): |
| 142 master_name = 'm' |
| 143 builder_name = 'b' |
| 144 build_number = 100 |
| 145 step_name = 's' |
| 146 test_name = 't' |
| 147 git_hash = 'r99' |
| 148 |
| 149 try_job = FlakeTryJob.Create( |
| 150 master_name, builder_name, step_name, test_name, git_hash) |
| 151 try_job.status = analysis_status.COMPLETED |
| 152 try_job.put() |
| 153 |
| 154 analysis = MasterFlakeAnalysis.Create( |
| 155 master_name, builder_name, build_number, step_name, test_name) |
| 156 analysis.status = analysis_status.COMPLETED |
| 157 analysis.try_job_status = analysis_status.RUNNING |
| 158 analysis.data_points = [ |
| 159 _GenerateDataPoint( |
| 160 pass_rate=0.9, commit_position=100, build_number=12345, |
| 161 previous_build_commit_position=90, blame_list=[ |
| 162 'r91', 'r92', 'r93', 'r94', 'r95', 'r96', 'r97', 'r98', 'r99', |
| 163 'r100']), |
| 164 _GenerateDataPoint(pass_rate=0.9, commit_position=99, try_job_id='id')] |
| 165 analysis.suspected_flake_build_number = 12345 |
| 166 analysis.Save() |
| 167 |
| 168 queue_name = {'x': False} |
| 169 def MockedRun(*_): |
| 170 queue_name['x'] = True # pragma: no cover |
| 171 |
| 172 self.mock( |
| 173 recursive_flake_try_job_pipeline.RecursiveFlakeTryJobPipeline, 'start', |
| 174 MockedRun) |
| 175 |
| 176 NextCommitPositionPipeline().run( |
| 177 analysis.key.urlsafe(), try_job.key.urlsafe()) |
| 178 self.assertTrue(queue_name['x']) |
| 179 |
| 180 def testNextCommitPositionPipelineCompleted(self, *_): |
| 181 master_name = 'm' |
| 182 builder_name = 'b' |
| 183 build_number = 100 |
| 184 step_name = 's' |
| 185 test_name = 't' |
| 186 git_hash = 'r95' |
| 187 |
| 188 try_job = FlakeTryJob.Create( |
| 189 master_name, builder_name, step_name, test_name, git_hash) |
| 190 try_job.status = analysis_status.COMPLETED |
| 191 try_job.put() |
| 192 |
| 193 analysis = MasterFlakeAnalysis.Create( |
| 194 master_name, builder_name, build_number, step_name, test_name) |
| 195 analysis.status = analysis_status.COMPLETED |
| 196 analysis.try_job_status = analysis_status.RUNNING |
| 197 analysis.data_points = [ |
| 198 _GenerateDataPoint( |
| 199 pass_rate=0.9, commit_position=100, build_number=12345, |
| 200 previous_build_commit_position=90, blame_list=[ |
| 201 'r91', 'r92', 'r93', 'r94', 'r95', 'r96', 'r97', 'r98', 'r99', |
| 202 'r100']), |
| 203 _GenerateDataPoint(pass_rate=0.9, commit_position=99, try_job_id='id1'), |
| 204 _GenerateDataPoint(pass_rate=0.9, commit_position=97, try_job_id='id2'), |
| 205 _GenerateDataPoint(pass_rate=0.9, commit_position=95, try_job_id='id4'), |
| 206 _GenerateDataPoint(pass_rate=1.0, commit_position=94, try_job_id='id3')] |
| 207 analysis.suspected_flake_build_number = 12345 |
| 208 analysis.Save() |
| 209 |
| 210 NextCommitPositionPipeline().run( |
| 211 analysis.key.urlsafe(), try_job.key.urlsafe()) |
| 212 |
| 213 culprit = analysis.culprit |
| 214 self.assertEqual(git_hash, culprit.revision) |
| 215 self.assertEqual(95, culprit.commit_position) |
| 216 |
| 217 def testNextCommitPositionNewlyAddedFlakyTest(self, *_): |
| 218 master_name = 'm' |
| 219 builder_name = 'b' |
| 220 build_number = 100 |
| 221 step_name = 's' |
| 222 test_name = 't' |
| 223 git_hash = 'r100' |
| 224 |
| 225 try_job = FlakeTryJob.Create( |
| 226 master_name, builder_name, step_name, test_name, git_hash) |
| 227 try_job.status = analysis_status.COMPLETED |
| 228 try_job.put() |
| 229 |
| 230 analysis = MasterFlakeAnalysis.Create( |
| 231 master_name, builder_name, build_number, step_name, test_name) |
| 232 analysis.status = analysis_status.COMPLETED |
| 233 analysis.try_job_status = analysis_status.RUNNING |
| 234 analysis.data_points = [ |
| 235 _GenerateDataPoint( |
| 236 pass_rate=0.9, commit_position=100, build_number=12345, |
| 237 previous_build_commit_position=98, blame_list=['r99', 'r100']), |
| 238 _GenerateDataPoint(pass_rate=-1, commit_position=99, try_job_id='id1')] |
| 239 analysis.suspected_flake_build_number = 12345 |
| 240 analysis.Save() |
| 241 |
| 242 NextCommitPositionPipeline().run( |
| 243 analysis.key.urlsafe(), try_job.key.urlsafe()) |
| 244 |
| 245 culprit = analysis.culprit |
| 246 self.assertEqual(git_hash, culprit.revision) |
| 247 self.assertEqual(100, culprit.commit_position) |
| 248 |
| 249 @mock.patch( |
| 250 ('waterfall.flake.recursive_flake_try_job_pipeline.' |
| 251 'RecursiveFlakeTryJobPipeline')) |
| 252 def testNextCommitPositionPipelineForFailedTryJob(self, mocked_pipeline): |
| 253 master_name = 'm' |
| 254 builder_name = 'b' |
| 255 build_number = 100 |
| 256 step_name = 's' |
| 257 test_name = 't' |
| 258 revision = 'r97' |
| 259 error = { |
| 260 'code': 1, |
| 261 'message': 'some failure message', |
| 262 } |
| 263 |
| 264 try_job = FlakeTryJob.Create( |
| 265 master_name, builder_name, step_name, test_name, revision) |
| 266 try_job.status = analysis_status.ERROR |
| 267 try_job.error = error |
| 268 try_job.put() |
| 269 |
| 270 analysis = MasterFlakeAnalysis.Create( |
| 271 master_name, builder_name, build_number, step_name, test_name) |
| 272 analysis.put() |
| 273 |
| 274 NextCommitPositionPipeline().run( |
| 275 analysis.key.urlsafe(), try_job.key.urlsafe()) |
| 276 mocked_pipeline.assert_not_called() |
| 277 self.assertEqual(error, analysis.error) |
| 278 |
| 279 @mock.patch.object(CachedGitilesRepository, 'GetChangeLog') |
| 280 def testCreateCulprit(self, mocked_module): |
| 281 revision = 'a1b2c3d4' |
| 282 commit_position = 12345 |
| 283 url = 'url' |
| 284 repo_name = 'repo_name' |
| 285 change_log = ChangeLog(None, None, None, None, None, None, revision, |
| 286 commit_position, None, None, url, None) |
| 287 mocked_module.return_value = change_log |
| 288 culprit = _CreateCulprit(revision, commit_position, repo_name) |
| 289 |
| 290 self.assertEqual(commit_position, culprit.commit_position) |
| 291 self.assertEqual(revision, culprit.revision) |
| 292 self.assertEqual(url, culprit.url) |
| 293 self.assertEqual(repo_name, culprit.repo_name) |
| 294 |
| 295 @mock.patch.object(CachedGitilesRepository, 'GetChangeLog', return_value=None) |
| 296 def testCreateCulpritNoLogs(self, _): |
| 297 revision = 'a1b2c3d4' |
| 298 commit_position = 12345 |
| 299 repo_name = 'repo_name' |
| 300 culprit = _CreateCulprit(revision, commit_position, repo_name) |
| 301 |
| 302 self.assertEqual(commit_position, culprit.commit_position) |
| 303 self.assertEqual(revision, culprit.revision) |
| 304 self.assertIsNone(culprit.url) |
| 305 self.assertEqual(repo_name, culprit.repo_name) |
| 306 |
| 307 def testUpdateAnalysisTryJobStatusUponCompletionFound(self): |
| 308 analysis = MasterFlakeAnalysis.Create('m', 'b', 123, 's', 't') |
| 309 culprit = FlakeCulprit.Create('repo_name', 'a1b2c3d4', 12345, 'url') |
| 310 _UpdateAnalysisTryJobStatusUponCompletion( |
| 311 analysis, culprit, analysis_status.COMPLETED, None) |
| 312 self.assertIsNone(analysis.error) |
| 313 self.assertEqual(culprit.revision, analysis.culprit.revision) |
| 314 self.assertEqual(analysis_status.COMPLETED, analysis.try_job_status) |
| 315 self.assertEqual(result_status.FOUND_UNTRIAGED, analysis.result_status) |
| 316 |
| 317 def testUpdateAnalysisTryJobStatusUponCompletionNotFound(self): |
| 318 analysis = MasterFlakeAnalysis.Create('m', 'b', 123, 's', 't') |
| 319 _UpdateAnalysisTryJobStatusUponCompletion( |
| 320 analysis, None, analysis_status.COMPLETED, None) |
| 321 self.assertIsNone(analysis.error) |
| 322 self.assertIsNone(analysis.culprit) |
| 323 self.assertEqual(analysis_status.COMPLETED, analysis.try_job_status) |
| 324 self.assertEqual(result_status.NOT_FOUND_UNTRIAGED, analysis.result_status) |
| 325 |
| 326 def testUpdateAnalysisTryJobStatusError(self): |
| 327 analysis = MasterFlakeAnalysis.Create('m', 'b', 123, 's', 't') |
| 328 _UpdateAnalysisTryJobStatusUponCompletion( |
| 329 analysis, None, analysis_status.ERROR, {'error': 'errror'}) |
| 330 self.assertIsNotNone(analysis.error) |
| 331 self.assertIsNone(analysis.culprit) |
| 332 self.assertEqual(analysis_status.ERROR, analysis.try_job_status) |
| 333 self.assertIsNone(analysis.result_status) |
| 334 |
| 335 def testGetTryJobDataPointsNoTryJobsYet(self): |
| 336 suspected_flake_build_number = 12345 |
| 337 data_points = [ |
| 338 _GenerateDataPoint(pass_rate=0.8, commit_position=100, |
| 339 build_number=suspected_flake_build_number)] |
| 340 analysis = MasterFlakeAnalysis.Create('m', 'b', 123, 's', 't') |
| 341 analysis.suspected_flake_build_number = suspected_flake_build_number |
| 342 analysis.data_points = data_points |
| 343 |
| 344 self.assertEqual(data_points, _GetTryJobDataPoints(analysis)) |
| 345 |
| 346 def testGetTryJobDataPointsWithTryJobs(self): |
| 347 suspected_flake_build_number = 12345 |
| 348 all_data_points = [ |
| 349 _GenerateDataPoint(pass_rate=0.8, commit_position=100, |
| 350 build_number=suspected_flake_build_number), |
| 351 _GenerateDataPoint(pass_rate=1.0, commit_position=90, |
| 352 build_number=suspected_flake_build_number - 1), |
| 353 _GenerateDataPoint(pass_rate=0.8, commit_position=99, |
| 354 try_job_id='try_job_id')] |
| 355 expected_data_points = [all_data_points[0], all_data_points[2]] |
| 356 |
| 357 analysis = MasterFlakeAnalysis.Create('m', 'b', 123, 's', 't') |
| 358 analysis.suspected_flake_build_number = suspected_flake_build_number |
| 359 analysis.data_points = all_data_points |
| 360 |
| 361 self.assertEqual(expected_data_points, _GetTryJobDataPoints(analysis)) |
| 362 |
| 363 def testGetNextFlakySingleFlakyDataPoint(self): |
| 364 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=100)] |
| 365 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 366 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 367 self.assertEqual(99, next_commit_position) |
| 368 self.assertIsNone(suspected_commit_position) |
| 369 |
| 370 def testGetNextMultipleFlakyDataPoints(self): |
| 371 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=100), |
| 372 _GenerateDataPoint(pass_rate=0.8, commit_position=99), |
| 373 _GenerateDataPoint(pass_rate=0.8, commit_position=97), |
| 374 _GenerateDataPoint(pass_rate=0.8, commit_position=94)] |
| 375 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 376 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 377 self.assertEqual(90, next_commit_position) |
| 378 self.assertIsNone(suspected_commit_position) |
| 379 |
| 380 def testGetNextLowerBoundary(self): |
| 381 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=2), |
| 382 _GenerateDataPoint(pass_rate=0.8, commit_position=1)] |
| 383 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 384 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 385 |
| 386 self.assertEqual(0, next_commit_position) |
| 387 self.assertIsNone(suspected_commit_position) |
| 388 |
| 389 def testSequentialSearchAtLowerBoundaryStable(self): |
| 390 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=8), |
| 391 _GenerateDataPoint(pass_rate=0.8, commit_position=3), |
| 392 _GenerateDataPoint(pass_rate=1.0, commit_position=0)] |
| 393 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 394 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 395 self.assertEqual(1, next_commit_position) |
| 396 self.assertIsNone(suspected_commit_position) |
| 397 |
| 398 def testSequentialSearchAtLowerBoundaryFlaky(self): |
| 399 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=8), |
| 400 _GenerateDataPoint(pass_rate=0.8, commit_position=3), |
| 401 _GenerateDataPoint(pass_rate=0.8, commit_position=0)] |
| 402 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 403 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 404 |
| 405 self.assertIsNone(next_commit_position) |
| 406 self.assertEqual(0, suspected_commit_position) |
| 407 |
| 408 def testReadyForSequential(self): |
| 409 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=100), |
| 410 _GenerateDataPoint(pass_rate=0.8, commit_position=99), |
| 411 _GenerateDataPoint(pass_rate=0.8, commit_position=97), |
| 412 _GenerateDataPoint(pass_rate=0.8, commit_position=94), |
| 413 _GenerateDataPoint(pass_rate=1.0, commit_position=90)] |
| 414 |
| 415 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 416 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 417 |
| 418 self.assertIsNone(suspected_commit_position) |
| 419 self.assertEqual(next_commit_position, 91) |
| 420 |
| 421 def testSequentialSearch(self): |
| 422 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=100), |
| 423 _GenerateDataPoint(pass_rate=0.8, commit_position=99), |
| 424 _GenerateDataPoint(pass_rate=0.8, commit_position=97), |
| 425 _GenerateDataPoint(pass_rate=0.8, commit_position=94), |
| 426 _GenerateDataPoint(pass_rate=1.0, commit_position=92), |
| 427 _GenerateDataPoint(pass_rate=1.0, commit_position=91), |
| 428 _GenerateDataPoint(pass_rate=1.0, commit_position=90)] |
| 429 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 430 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 431 |
| 432 self.assertIsNone(suspected_commit_position) |
| 433 self.assertEqual(next_commit_position, 93) |
| 434 |
| 435 def testSuspectedCommitPosition(self): |
| 436 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=100), |
| 437 _GenerateDataPoint(pass_rate=1.0, commit_position=99)] |
| 438 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 439 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 440 |
| 441 self.assertIsNone(next_commit_position) |
| 442 self.assertEqual(suspected_commit_position, 100) |
| 443 |
| 444 def testSuspectedCommitPositionAfterSequentialSearch(self): |
| 445 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=100), |
| 446 _GenerateDataPoint(pass_rate=0.8, commit_position=99), |
| 447 _GenerateDataPoint(pass_rate=0.8, commit_position=97), |
| 448 _GenerateDataPoint(pass_rate=0.8, commit_position=94), |
| 449 _GenerateDataPoint(pass_rate=1.0, commit_position=93), |
| 450 _GenerateDataPoint(pass_rate=1.0, commit_position=92), |
| 451 _GenerateDataPoint(pass_rate=1.0, commit_position=91), |
| 452 _GenerateDataPoint(pass_rate=1.0, commit_position=90)] |
| 453 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 454 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 455 |
| 456 self.assertEqual(94, suspected_commit_position) |
| 457 self.assertIsNone(next_commit_position) |
| 458 |
| 459 def testRiseAfterDive(self): |
| 460 data_points = [_GenerateDataPoint(pass_rate=0.3, commit_position=100), |
| 461 _GenerateDataPoint(pass_rate=0.8, commit_position=99), |
| 462 _GenerateDataPoint(pass_rate=0.3, commit_position=97)] |
| 463 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 464 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 465 self.assertIsNone(suspected_commit_position) |
| 466 self.assertEqual(94, next_commit_position) |
| 467 |
| 468 def testNextCommitPositionWhenDivedOut(self): |
| 469 data_points = [_GenerateDataPoint(pass_rate=0.3, commit_position=100), |
| 470 _GenerateDataPoint(pass_rate=0.8, commit_position=99), |
| 471 _GenerateDataPoint(pass_rate=0.8, commit_position=98), |
| 472 _GenerateDataPoint(pass_rate=0.7, commit_position=97), |
| 473 _GenerateDataPoint(pass_rate=0.7, commit_position=96), |
| 474 _GenerateDataPoint(pass_rate=0.9, commit_position=95)] |
| 475 |
| 476 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 477 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 478 self.assertEquals(100, suspected_commit_position) |
| 479 self.assertIsNone(next_commit_position) |
| 480 |
| 481 def testNextCommitPositionDivedOutSequence(self): |
| 482 data_points = [_GenerateDataPoint(pass_rate=0.3, commit_position=100), |
| 483 _GenerateDataPoint(pass_rate=0.2, commit_position=99), |
| 484 _GenerateDataPoint(pass_rate=0.8, commit_position=97), |
| 485 _GenerateDataPoint(pass_rate=0.7, commit_position=96), |
| 486 _GenerateDataPoint(pass_rate=0.8, commit_position=95), |
| 487 _GenerateDataPoint(pass_rate=0.9, commit_position=94), |
| 488 _GenerateDataPoint(pass_rate=0.8, commit_position=93)] |
| 489 |
| 490 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 491 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 492 self.assertIsNone(suspected_commit_position) |
| 493 self.assertEqual(98, next_commit_position) |
| 494 |
| 495 def testCommitIntroducedFlakiness(self): |
| 496 data_points = [_GenerateDataPoint(pass_rate=0.8, commit_position=100), |
| 497 _GenerateDataPoint(pass_rate=-1, commit_position=99)] |
| 498 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 499 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 500 |
| 501 # This case should be handled by the caller of _GetNextCommitPosition |
| 502 self.assertIsNone(suspected_commit_position) |
| 503 self.assertEqual(100, next_commit_position) |
| 504 |
| 505 def testTestDoesNotExist(self): |
| 506 # This case should not be valid, since suspected flake build number would |
| 507 # not have been None and not triggered try jobs to begin with. |
| 508 data_points = [_GenerateDataPoint(pass_rate=-1, commit_position=100)] |
| 509 next_commit_position, suspected_commit_position = _GetNextCommitPosition( |
| 510 data_points, DEFAULT_CONFIG_DATA['check_flake_try_job_settings'], 0) |
| 511 |
| 512 self.assertIsNone(suspected_commit_position) |
| 513 self.assertIsNone(next_commit_position) |
| OLD | NEW |