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