| OLD | NEW |
| 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 from datetime import datetime |
| 6 |
| 7 import pytz |
| 8 |
| 5 from common import constants | 9 from common import constants |
| 6 from common.pipeline_wrapper import pipeline_handlers | 10 from common.pipeline_wrapper import pipeline_handlers |
| 7 from model import analysis_status | 11 from model import analysis_status |
| 8 from model.flake.flake_swarming_task import FlakeSwarmingTask | 12 from model.flake.flake_swarming_task import FlakeSwarmingTask |
| 9 from model.flake.master_flake_analysis import DataPoint | 13 from model.flake.master_flake_analysis import DataPoint |
| 10 from model.flake.master_flake_analysis import MasterFlakeAnalysis | 14 from model.flake.master_flake_analysis import MasterFlakeAnalysis |
| 11 from waterfall.flake import recursive_flake_pipeline | 15 from waterfall.flake import recursive_flake_pipeline |
| 12 from waterfall.flake.recursive_flake_pipeline import get_next_run | 16 from waterfall.flake.recursive_flake_pipeline import get_next_run |
| 13 from waterfall.flake.recursive_flake_pipeline import NextBuildNumberPipeline | 17 from waterfall.flake.recursive_flake_pipeline import NextBuildNumberPipeline |
| 14 from waterfall.flake.recursive_flake_pipeline import RecursiveFlakePipeline | 18 from waterfall.flake.recursive_flake_pipeline import RecursiveFlakePipeline |
| (...skipping 22 matching lines...) Expand all Loading... |
| 37 | 41 |
| 38 def _GenerateDataPoints(self, pass_rates, build_numbers): | 42 def _GenerateDataPoints(self, pass_rates, build_numbers): |
| 39 data_points = [] | 43 data_points = [] |
| 40 for i in range(0, len(pass_rates)): | 44 for i in range(0, len(pass_rates)): |
| 41 data_point = DataPoint() | 45 data_point = DataPoint() |
| 42 data_point.pass_rate = pass_rates[i] | 46 data_point.pass_rate = pass_rates[i] |
| 43 data_point.build_number = build_numbers[i] | 47 data_point.build_number = build_numbers[i] |
| 44 data_points.append(data_point) | 48 data_points.append(data_point) |
| 45 return data_points | 49 return data_points |
| 46 | 50 |
| 51 def testGetETAToStartAnalysisWhenManuallyTriggered(self): |
| 52 mocked_utcnow = datetime.utcnow() |
| 53 self.MockUTCNow(mocked_utcnow) |
| 54 self.assertEqual(mocked_utcnow, |
| 55 recursive_flake_pipeline._GetETAToStartAnalysis(True)) |
| 56 |
| 57 def testGetETAToStartAnalysisWhenTriggeredOnPSTWeekend(self): |
| 58 # Sunday 1pm in PST. |
| 59 mocked_utcnow = datetime(2016, 9, 04, 20, 0, 0, 0, pytz.utc) |
| 60 self.MockUTCNow(mocked_utcnow) |
| 61 self.MockUTCNowWithTimezone(mocked_utcnow) |
| 62 self.assertEqual(mocked_utcnow, |
| 63 recursive_flake_pipeline._GetETAToStartAnalysis(False)) |
| 64 |
| 65 def testGetETAToStartAnalysisWhenTriggeredOffPeakHoursOnPSTWeekday(self): |
| 66 # Tuesday 1am in PST. |
| 67 mocked_utcnow = datetime(2016, 9, 20, 8, 0, 0, 0, pytz.utc) |
| 68 self.MockUTCNow(mocked_utcnow) |
| 69 self.MockUTCNowWithTimezone(mocked_utcnow) |
| 70 self.assertEqual(mocked_utcnow, |
| 71 recursive_flake_pipeline._GetETAToStartAnalysis(False)) |
| 72 |
| 73 def testGetETAToStartAnalysisWhenTriggeredInPeakHoursOnPSTWeekday(self): |
| 74 # Tuesday 1pm in PST. |
| 75 mocked_utcnow = datetime(2016, 9, 20, 20, 0, 0, 0, pytz.utc) |
| 76 self.MockUTCNow(mocked_utcnow) |
| 77 self.MockUTCNowWithTimezone(mocked_utcnow) |
| 78 eta = recursive_flake_pipeline._GetETAToStartAnalysis(False) |
| 79 self.assertEqual(2016, eta.year) |
| 80 self.assertEqual(9, eta.month) |
| 81 self.assertEqual(21, eta.day) |
| 82 self.assertEqual(1, eta.hour) |
| 83 seconds = eta.minute * 60 + eta.second |
| 84 self.assertTrue(seconds >= 0 and seconds <= 30 * 60) |
| 85 |
| 47 def testRecursiveFlakePipeline(self): | 86 def testRecursiveFlakePipeline(self): |
| 48 master_name = 'm' | 87 master_name = 'm' |
| 49 builder_name = 'b' | 88 builder_name = 'b' |
| 50 master_build_number = 100 | 89 master_build_number = 100 |
| 51 build_number = 100 | 90 build_number = 100 |
| 52 run_build_number = 100 | 91 run_build_number = 100 |
| 53 step_name = 's' | 92 step_name = 's' |
| 54 test_name = 't' | 93 test_name = 't' |
| 55 test_result_future = 'test_result_future' | 94 test_result_future = 'test_result_future' |
| 56 queue_name = constants.DEFAULT_QUEUE | 95 queue_name = constants.DEFAULT_QUEUE |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 run_build_number, step_name, task_id, | 127 run_build_number, step_name, task_id, |
| 89 master_build_number, test_name, | 128 master_build_number, test_name, |
| 90 analysis.version_number], | 129 analysis.version_number], |
| 91 expected_kwargs={}) | 130 expected_kwargs={}) |
| 92 | 131 |
| 93 self.MockPipeline( | 132 self.MockPipeline( |
| 94 recursive_flake_pipeline.NextBuildNumberPipeline, | 133 recursive_flake_pipeline.NextBuildNumberPipeline, |
| 95 '', | 134 '', |
| 96 expected_args=[master_name, builder_name, master_build_number, | 135 expected_args=[master_name, builder_name, master_build_number, |
| 97 build_number, step_name, test_name, | 136 build_number, step_name, test_name, |
| 98 analysis.version_number, | 137 analysis.version_number, test_result_future, |
| 99 test_result_future, queue_name, | |
| 100 flakiness_algorithm_results_dict], | 138 flakiness_algorithm_results_dict], |
| 101 expected_kwargs={}) | 139 expected_kwargs={'manually_triggered': False}) |
| 102 | 140 |
| 103 rfp = RecursiveFlakePipeline( | 141 rfp = RecursiveFlakePipeline( |
| 104 master_name, builder_name, build_number, step_name, test_name, | 142 master_name, builder_name, build_number, step_name, test_name, |
| 105 analysis.version_number, master_build_number, | 143 analysis.version_number, master_build_number, |
| 106 flakiness_algorithm_results_dict=flakiness_algorithm_results_dict, | 144 flakiness_algorithm_results_dict=flakiness_algorithm_results_dict) |
| 107 queue_name=queue_name) | |
| 108 | 145 |
| 109 rfp.start(queue_name=queue_name) | 146 rfp.start(queue_name=queue_name) |
| 110 self.execute_queued_tasks() | 147 self.execute_queued_tasks() |
| 111 | 148 |
| 112 def testNextBuildPipelineForNewRecursionFirstFlake(self): | 149 def testNextBuildPipelineForNewRecursionFirstFlake(self): |
| 113 master_name = 'm' | 150 master_name = 'm' |
| 114 builder_name = 'b' | 151 builder_name = 'b' |
| 115 master_build_number = 100 | 152 master_build_number = 100 |
| 116 build_number = 100 | 153 build_number = 100 |
| 117 step_name = 's' | 154 step_name = 's' |
| 118 test_name = 't' | 155 test_name = 't' |
| 119 test_result_future = 'trf' | 156 test_result_future = 'trf' |
| 120 queue_name = constants.DEFAULT_QUEUE | |
| 121 flakiness_algorithm_results_dict = { | 157 flakiness_algorithm_results_dict = { |
| 122 'flakes_in_a_row': 0, | 158 'flakes_in_a_row': 0, |
| 123 'stable_in_a_row': 0, | 159 'stable_in_a_row': 0, |
| 124 'stabled_out': False, | 160 'stabled_out': False, |
| 125 'flaked_out': False, | 161 'flaked_out': False, |
| 126 'last_build_number': 0, | 162 'last_build_number': 0, |
| 127 'lower_boundary': None, | 163 'lower_boundary': None, |
| 128 'upper_boundary': None, | 164 'upper_boundary': None, |
| 129 'lower_boundary_result': None, | 165 'lower_boundary_result': None, |
| 130 'sequential_run_index': 0 | 166 'sequential_run_index': 0 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 143 | 179 |
| 144 data_point = DataPoint() | 180 data_point = DataPoint() |
| 145 data_point.pass_rate = .08 | 181 data_point.pass_rate = .08 |
| 146 data_point.build_number = 100 | 182 data_point.build_number = 100 |
| 147 analysis.data_points.append(data_point) | 183 analysis.data_points.append(data_point) |
| 148 analysis.put() | 184 analysis.put() |
| 149 | 185 |
| 150 NextBuildNumberPipeline.run( | 186 NextBuildNumberPipeline.run( |
| 151 NextBuildNumberPipeline(), master_name, builder_name, | 187 NextBuildNumberPipeline(), master_name, builder_name, |
| 152 master_build_number, build_number, step_name, test_name, | 188 master_build_number, build_number, step_name, test_name, |
| 153 analysis.version_number, test_result_future, queue_name, | 189 analysis.version_number, test_result_future, |
| 154 flakiness_algorithm_results_dict) | 190 flakiness_algorithm_results_dict) |
| 155 self.assertEquals(flakiness_algorithm_results_dict['flakes_in_a_row'], 1) | 191 self.assertEquals(flakiness_algorithm_results_dict['flakes_in_a_row'], 1) |
| 156 | 192 |
| 157 def testNextBuildPipelineForNewRecursionFirstStable(self): | 193 def testNextBuildPipelineForNewRecursionFirstStable(self): |
| 158 master_name = 'm' | 194 master_name = 'm' |
| 159 builder_name = 'b' | 195 builder_name = 'b' |
| 160 master_build_number = 100 | 196 master_build_number = 100 |
| 161 build_number = 100 | 197 build_number = 100 |
| 162 step_name = 's' | 198 step_name = 's' |
| 163 test_name = 't' | 199 test_name = 't' |
| 164 test_result_future = 'trf' | 200 test_result_future = 'trf' |
| 165 queue_name = constants.DEFAULT_QUEUE | |
| 166 flakiness_algorithm_results_dict = { | 201 flakiness_algorithm_results_dict = { |
| 167 'flakes_in_a_row': 0, | 202 'flakes_in_a_row': 0, |
| 168 'stable_in_a_row': 0, | 203 'stable_in_a_row': 0, |
| 169 'stabled_out': False, | 204 'stabled_out': False, |
| 170 'flaked_out': False, | 205 'flaked_out': False, |
| 171 'last_build_number': 0, | 206 'last_build_number': 0, |
| 172 'lower_boundary': None, | 207 'lower_boundary': None, |
| 173 'upper_boundary': None, | 208 'upper_boundary': None, |
| 174 'lower_boundary_result': None, | 209 'lower_boundary_result': None, |
| 175 'sequential_run_index': 0 | 210 'sequential_run_index': 0 |
| 176 | |
| 177 } | 211 } |
| 178 self._CreateAndSaveMasterFlakeAnalysis( | 212 self._CreateAndSaveMasterFlakeAnalysis( |
| 179 master_name, builder_name, build_number, step_name, | 213 master_name, builder_name, build_number, step_name, |
| 180 test_name, status=analysis_status.PENDING | 214 test_name, status=analysis_status.PENDING |
| 181 ) | 215 ) |
| 182 self._CreateAndSaveFlakeSwarmingTask( | 216 self._CreateAndSaveFlakeSwarmingTask( |
| 183 master_name, builder_name, build_number, step_name, | 217 master_name, builder_name, build_number, step_name, |
| 184 test_name, status=analysis_status.COMPLETED | 218 test_name, status=analysis_status.COMPLETED |
| 185 ) | 219 ) |
| 186 analysis = MasterFlakeAnalysis.GetVersion( | 220 analysis = MasterFlakeAnalysis.GetVersion( |
| 187 master_name, builder_name, build_number, step_name, test_name) | 221 master_name, builder_name, build_number, step_name, test_name) |
| 188 data_point = DataPoint() | 222 data_point = DataPoint() |
| 189 data_point.pass_rate = 0 | 223 data_point.pass_rate = 0 |
| 190 data_point.build_number = 100 | 224 data_point.build_number = 100 |
| 191 analysis.data_points.append(data_point) | 225 analysis.data_points.append(data_point) |
| 192 analysis.put() | 226 analysis.put() |
| 193 | 227 |
| 194 NextBuildNumberPipeline.run( | 228 NextBuildNumberPipeline.run( |
| 195 NextBuildNumberPipeline(), master_name, builder_name, | 229 NextBuildNumberPipeline(), master_name, builder_name, |
| 196 master_build_number, build_number, step_name, | 230 master_build_number, build_number, step_name, |
| 197 test_name, analysis.version_number, test_result_future, queue_name, | 231 test_name, analysis.version_number, test_result_future, |
| 198 flakiness_algorithm_results_dict) | 232 flakiness_algorithm_results_dict) |
| 199 self.assertEquals(flakiness_algorithm_results_dict['stable_in_a_row'], 1) | 233 self.assertEquals(flakiness_algorithm_results_dict['stable_in_a_row'], 1) |
| 200 | 234 |
| 201 def testNextBuildPipelineForNewRecursionFlakeInARow(self): | 235 def testNextBuildPipelineForNewRecursionFlakeInARow(self): |
| 202 master_name = 'm' | 236 master_name = 'm' |
| 203 builder_name = 'b' | 237 builder_name = 'b' |
| 204 master_build_number = 100 | 238 master_build_number = 100 |
| 205 build_number = 100 | 239 build_number = 100 |
| 206 step_name = 's' | 240 step_name = 's' |
| 207 test_name = 't' | 241 test_name = 't' |
| 208 test_result_future = 'trf' | 242 test_result_future = 'trf' |
| 209 queue_name = constants.DEFAULT_QUEUE | |
| 210 flakiness_algorithm_results_dict = { | 243 flakiness_algorithm_results_dict = { |
| 211 'flakes_in_a_row': 0, | 244 'flakes_in_a_row': 0, |
| 212 'stable_in_a_row': 4, | 245 'stable_in_a_row': 4, |
| 213 'stabled_out': False, | 246 'stabled_out': False, |
| 214 'flaked_out': False, | 247 'flaked_out': False, |
| 215 'last_build_number': 0, | 248 'last_build_number': 0, |
| 216 'lower_boundary': None, | 249 'lower_boundary': None, |
| 217 'upper_boundary': None, | 250 'upper_boundary': None, |
| 218 'lower_boundary_result': None, | 251 'lower_boundary_result': None, |
| 219 'sequential_run_index': 0 | 252 'sequential_run_index': 0 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 231 master_name, builder_name, build_number, step_name, test_name) | 264 master_name, builder_name, build_number, step_name, test_name) |
| 232 data_point = DataPoint() | 265 data_point = DataPoint() |
| 233 data_point.pass_rate = 0 | 266 data_point.pass_rate = 0 |
| 234 data_point.build_number = 100 | 267 data_point.build_number = 100 |
| 235 analysis.data_points.append(data_point) | 268 analysis.data_points.append(data_point) |
| 236 analysis.put() | 269 analysis.put() |
| 237 | 270 |
| 238 NextBuildNumberPipeline.run( | 271 NextBuildNumberPipeline.run( |
| 239 NextBuildNumberPipeline(), master_name, builder_name, | 272 NextBuildNumberPipeline(), master_name, builder_name, |
| 240 master_build_number, build_number, step_name, | 273 master_build_number, build_number, step_name, |
| 241 test_name, analysis.version_number, test_result_future, queue_name, | 274 test_name, analysis.version_number, test_result_future, |
| 242 flakiness_algorithm_results_dict) | 275 flakiness_algorithm_results_dict) |
| 243 self.assertEquals(flakiness_algorithm_results_dict['stabled_out'], True) | 276 self.assertEquals(flakiness_algorithm_results_dict['stabled_out'], True) |
| 244 | 277 |
| 245 def testNextBuildPipelineForNewRecursionStableInARow(self): | 278 def testNextBuildPipelineForNewRecursionStableInARow(self): |
| 246 master_name = 'm' | 279 master_name = 'm' |
| 247 builder_name = 'b' | 280 builder_name = 'b' |
| 248 master_build_number = 100 | 281 master_build_number = 100 |
| 249 build_number = 100 | 282 build_number = 100 |
| 250 step_name = 's' | 283 step_name = 's' |
| 251 test_name = 't' | 284 test_name = 't' |
| 252 test_result_future = 'trf' | 285 test_result_future = 'trf' |
| 253 queue_name = constants.DEFAULT_QUEUE | |
| 254 flakiness_algorithm_results_dict = { | 286 flakiness_algorithm_results_dict = { |
| 255 'flakes_in_a_row': 4, | 287 'flakes_in_a_row': 4, |
| 256 'stable_in_a_row': 0, | 288 'stable_in_a_row': 0, |
| 257 'stabled_out': False, | 289 'stabled_out': False, |
| 258 'flaked_out': False, | 290 'flaked_out': False, |
| 259 'last_build_number': 0, | 291 'last_build_number': 0, |
| 260 'lower_boundary': None, | 292 'lower_boundary': None, |
| 261 'upper_boundary': None, | 293 'upper_boundary': None, |
| 262 'lower_boundary_result': None, | 294 'lower_boundary_result': None, |
| 263 'sequential_run_index': 0 | 295 'sequential_run_index': 0 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 275 master_name, builder_name, build_number, step_name, test_name) | 307 master_name, builder_name, build_number, step_name, test_name) |
| 276 data_point = DataPoint() | 308 data_point = DataPoint() |
| 277 data_point.pass_rate = .5 | 309 data_point.pass_rate = .5 |
| 278 data_point.build_number = 100 | 310 data_point.build_number = 100 |
| 279 analysis.data_points.append(data_point) | 311 analysis.data_points.append(data_point) |
| 280 analysis.put() | 312 analysis.put() |
| 281 | 313 |
| 282 NextBuildNumberPipeline.run( | 314 NextBuildNumberPipeline.run( |
| 283 NextBuildNumberPipeline(), master_name, builder_name, | 315 NextBuildNumberPipeline(), master_name, builder_name, |
| 284 master_build_number, build_number, step_name, | 316 master_build_number, build_number, step_name, |
| 285 test_name, analysis.version_number, test_result_future, queue_name, | 317 test_name, analysis.version_number, test_result_future, |
| 286 flakiness_algorithm_results_dict) | 318 flakiness_algorithm_results_dict) |
| 287 self.assertEquals(flakiness_algorithm_results_dict['flaked_out'], True) | 319 self.assertEquals(flakiness_algorithm_results_dict['flaked_out'], True) |
| 288 | 320 |
| 289 def testNextBuildPipelineForNewRecursionLessThanLastBuildNumber(self): | 321 def testNextBuildPipelineForNewRecursionLessThanLastBuildNumber(self): |
| 290 master_name = 'm' | 322 master_name = 'm' |
| 291 builder_name = 'b' | 323 builder_name = 'b' |
| 292 master_build_number = 100 | 324 master_build_number = 100 |
| 293 build_number = 100 | 325 build_number = 100 |
| 294 step_name = 's' | 326 step_name = 's' |
| 295 test_name = 't' | 327 test_name = 't' |
| 296 test_result_future = 'trf' | 328 test_result_future = 'trf' |
| 297 queue_name = constants.DEFAULT_QUEUE | |
| 298 flakiness_algorithm_results_dict = { | 329 flakiness_algorithm_results_dict = { |
| 299 'flakes_in_a_row': 0, | 330 'flakes_in_a_row': 0, |
| 300 'stable_in_a_row': 0, | 331 'stable_in_a_row': 0, |
| 301 'stabled_out': False, | 332 'stabled_out': False, |
| 302 'flaked_out': False, | 333 'flaked_out': False, |
| 303 'last_build_number': 200, | 334 'last_build_number': 200, |
| 304 'lower_boundary': None, | 335 'lower_boundary': None, |
| 305 'upper_boundary': None, | 336 'upper_boundary': None, |
| 306 'lower_boundary_result': None, | 337 'lower_boundary_result': None, |
| 307 'sequential_run_index': 0 | 338 'sequential_run_index': 0 |
| 308 } | 339 } |
| 309 self._CreateAndSaveMasterFlakeAnalysis( | 340 self._CreateAndSaveMasterFlakeAnalysis( |
| 310 master_name, builder_name, build_number, step_name, | 341 master_name, builder_name, build_number, step_name, |
| 311 test_name, status=analysis_status.PENDING | 342 test_name, status=analysis_status.PENDING |
| 312 ) | 343 ) |
| 313 self._CreateAndSaveFlakeSwarmingTask( | 344 self._CreateAndSaveFlakeSwarmingTask( |
| 314 master_name, builder_name, build_number, step_name, | 345 master_name, builder_name, build_number, step_name, |
| 315 test_name, status=analysis_status.COMPLETED | 346 test_name, status=analysis_status.COMPLETED |
| 316 ) | 347 ) |
| 317 analysis = MasterFlakeAnalysis.GetVersion( | 348 analysis = MasterFlakeAnalysis.GetVersion( |
| 318 master_name, builder_name, build_number, step_name, test_name) | 349 master_name, builder_name, build_number, step_name, test_name) |
| 319 data_point = DataPoint() | 350 data_point = DataPoint() |
| 320 data_point.pass_rate = .5 | 351 data_point.pass_rate = .5 |
| 321 data_point.build_number = 100 | 352 data_point.build_number = 100 |
| 322 analysis.data_points.append(data_point) | 353 analysis.data_points.append(data_point) |
| 323 analysis.put() | 354 analysis.put() |
| 324 | 355 |
| 325 queue_name = {'x': False} | 356 queue_name = {'x': False} |
| 326 def my_mocked_run(arg1, queue_name): # pylint: disable=unused-argument | 357 def my_mocked_run(*_, **__): |
| 327 queue_name['x'] = True # pragma: no cover | 358 queue_name['x'] = True # pragma: no cover |
| 328 | 359 |
| 329 self.mock( | 360 self.mock( |
| 330 recursive_flake_pipeline.RecursiveFlakePipeline, 'start', my_mocked_run) | 361 recursive_flake_pipeline.RecursiveFlakePipeline, 'start', my_mocked_run) |
| 331 NextBuildNumberPipeline.run( | 362 NextBuildNumberPipeline.run( |
| 332 NextBuildNumberPipeline(), master_name, builder_name, | 363 NextBuildNumberPipeline(), master_name, builder_name, |
| 333 master_build_number, build_number, step_name, test_name, | 364 master_build_number, build_number, step_name, test_name, |
| 334 analysis.version_number, test_result_future, queue_name, | 365 analysis.version_number, test_result_future, |
| 335 flakiness_algorithm_results_dict) | 366 flakiness_algorithm_results_dict) |
| 336 self.assertFalse(queue_name['x']) | 367 self.assertFalse(queue_name['x']) |
| 337 | 368 |
| 338 def testNextBuildPipelineForFailedSwarmingTask(self): | 369 def testNextBuildPipelineForFailedSwarmingTask(self): |
| 339 master_name = 'm' | 370 master_name = 'm' |
| 340 builder_name = 'b' | 371 builder_name = 'b' |
| 341 master_build_number = 100 | 372 master_build_number = 100 |
| 342 build_number = 100 | 373 build_number = 100 |
| 343 step_name = 's' | 374 step_name = 's' |
| 344 test_name = 't' | 375 test_name = 't' |
| 345 test_result_future = 'trf' | 376 test_result_future = 'trf' |
| 346 queue_name = constants.DEFAULT_QUEUE | |
| 347 flakiness_algorithm_results_dict = { | 377 flakiness_algorithm_results_dict = { |
| 348 'flakes_in_a_row': 0, | 378 'flakes_in_a_row': 0, |
| 349 'stable_in_a_row': 0, | 379 'stable_in_a_row': 0, |
| 350 'stabled_out': False, | 380 'stabled_out': False, |
| 351 'flaked_out': False, | 381 'flaked_out': False, |
| 352 'last_build_number': 0, | 382 'last_build_number': 0, |
| 353 'lower_boundary': None, | 383 'lower_boundary': None, |
| 354 'upper_boundary': None, | 384 'upper_boundary': None, |
| 355 'lower_boundary_result': None, | 385 'lower_boundary_result': None, |
| 356 'sequential_run_index': 0 | 386 'sequential_run_index': 0 |
| 357 | 387 |
| 358 } | 388 } |
| 359 self._CreateAndSaveMasterFlakeAnalysis( | 389 self._CreateAndSaveMasterFlakeAnalysis( |
| 360 master_name, builder_name, build_number, step_name, | 390 master_name, builder_name, build_number, step_name, |
| 361 test_name, status=analysis_status.PENDING | 391 test_name, status=analysis_status.PENDING |
| 362 ) | 392 ) |
| 363 self._CreateAndSaveFlakeSwarmingTask( | 393 self._CreateAndSaveFlakeSwarmingTask( |
| 364 master_name, builder_name, build_number, step_name, | 394 master_name, builder_name, build_number, step_name, |
| 365 test_name, status=analysis_status.ERROR | 395 test_name, status=analysis_status.ERROR |
| 366 ) | 396 ) |
| 367 analysis = MasterFlakeAnalysis.GetVersion( | 397 analysis = MasterFlakeAnalysis.GetVersion( |
| 368 master_name, builder_name, build_number, step_name, test_name) | 398 master_name, builder_name, build_number, step_name, test_name) |
| 369 data_point = DataPoint() | 399 data_point = DataPoint() |
| 370 data_point.pass_rate = .5 | 400 data_point.pass_rate = .5 |
| 371 data_point.build_number = 100 | 401 data_point.build_number = 100 |
| 372 analysis.data_points.append(data_point) | 402 analysis.data_points.append(data_point) |
| 373 analysis.put() | 403 analysis.put() |
| 374 | 404 |
| 375 queue_name = {'x': False} | 405 queue_name = {'x': False} |
| 376 def my_mocked_run(arg1, queue_name): # pylint: disable=unused-argument | 406 def my_mocked_run(*_, **__): |
| 377 queue_name['x'] = True # pragma: no cover | 407 queue_name['x'] = True # pragma: no cover |
| 378 | 408 |
| 379 self.mock( | 409 self.mock( |
| 380 recursive_flake_pipeline.RecursiveFlakePipeline, 'start', my_mocked_run) | 410 recursive_flake_pipeline.RecursiveFlakePipeline, 'start', my_mocked_run) |
| 381 NextBuildNumberPipeline.run( | 411 NextBuildNumberPipeline.run( |
| 382 NextBuildNumberPipeline(), master_name, builder_name, | 412 NextBuildNumberPipeline(), master_name, builder_name, |
| 383 master_build_number, build_number, step_name, test_name, 1, | 413 master_build_number, build_number, step_name, test_name, 1, |
| 384 test_result_future, queue_name, flakiness_algorithm_results_dict) | 414 test_result_future, flakiness_algorithm_results_dict) |
| 385 self.assertFalse(queue_name['x']) | 415 self.assertFalse(queue_name['x']) |
| 386 | 416 |
| 387 def testNextBuildPipelineForNewRecursionStabledFlakedOut(self): | 417 def testNextBuildPipelineForNewRecursionStabledFlakedOut(self): |
| 388 master_name = 'm' | 418 master_name = 'm' |
| 389 builder_name = 'b' | 419 builder_name = 'b' |
| 390 master_build_number = 100 | 420 master_build_number = 100 |
| 391 build_number = 100 | 421 build_number = 100 |
| 392 step_name = 's' | 422 step_name = 's' |
| 393 test_name = 't' | 423 test_name = 't' |
| 394 test_result_future = 'trf' | 424 test_result_future = 'trf' |
| (...skipping 19 matching lines...) Expand all Loading... |
| 414 ) | 444 ) |
| 415 analysis = MasterFlakeAnalysis.GetVersion( | 445 analysis = MasterFlakeAnalysis.GetVersion( |
| 416 master_name, builder_name, build_number, step_name, test_name) | 446 master_name, builder_name, build_number, step_name, test_name) |
| 417 data_point = DataPoint() | 447 data_point = DataPoint() |
| 418 data_point.pass_rate = .5 | 448 data_point.pass_rate = .5 |
| 419 data_point.build_number = 100 | 449 data_point.build_number = 100 |
| 420 analysis.data_points.append(data_point) | 450 analysis.data_points.append(data_point) |
| 421 analysis.put() | 451 analysis.put() |
| 422 | 452 |
| 423 queue_name = {'x': False} | 453 queue_name = {'x': False} |
| 424 def my_mocked_run(arg1, queue_name): # pylint: disable=unused-argument | 454 def my_mocked_run(*_, **__): |
| 425 queue_name['x'] = True # pragma: no cover | 455 queue_name['x'] = True # pragma: no cover |
| 426 | 456 |
| 427 self.mock( | 457 self.mock( |
| 428 recursive_flake_pipeline.RecursiveFlakePipeline, 'start', my_mocked_run) | 458 recursive_flake_pipeline.RecursiveFlakePipeline, 'start', my_mocked_run) |
| 429 NextBuildNumberPipeline.run( | 459 NextBuildNumberPipeline.run( |
| 430 NextBuildNumberPipeline(), master_name, builder_name, | 460 NextBuildNumberPipeline(), master_name, builder_name, |
| 431 master_build_number, build_number, step_name, test_name, | 461 master_build_number, build_number, step_name, test_name, |
| 432 analysis.version_number, test_result_future, queue_name, | 462 analysis.version_number, test_result_future, |
| 433 flakiness_algorithm_results_dict) | 463 flakiness_algorithm_results_dict) |
| 434 self.assertTrue(queue_name['x']) | 464 self.assertTrue(queue_name['x']) |
| 435 | 465 |
| 436 def testGetNextRunSetStableLowerBoundary(self): | 466 def testGetNextRunSetStableLowerBoundary(self): |
| 437 master_name = 'm' | 467 master_name = 'm' |
| 438 builder_name = 'b' | 468 builder_name = 'b' |
| 439 build_number = 100 | 469 build_number = 100 |
| 440 step_name = 's' | 470 step_name = 's' |
| 441 test_name = 't' | 471 test_name = 't' |
| 442 self._CreateAndSaveMasterFlakeAnalysis( | 472 self._CreateAndSaveMasterFlakeAnalysis( |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 self.assertEqual(analysis.suspected_flake_build_number, None) | 666 self.assertEqual(analysis.suspected_flake_build_number, None) |
| 637 | 667 |
| 638 def testNextBuildPipelineStabledOutFlakedOutFirstTime(self): | 668 def testNextBuildPipelineStabledOutFlakedOutFirstTime(self): |
| 639 master_name = 'm' | 669 master_name = 'm' |
| 640 builder_name = 'b' | 670 builder_name = 'b' |
| 641 master_build_number = 100 | 671 master_build_number = 100 |
| 642 build_number = 100 | 672 build_number = 100 |
| 643 step_name = 's' | 673 step_name = 's' |
| 644 test_name = 't' | 674 test_name = 't' |
| 645 test_result_future = 'trf' | 675 test_result_future = 'trf' |
| 646 queue_name = constants.DEFAULT_QUEUE | |
| 647 flakiness_algorithm_results_dict = { | 676 flakiness_algorithm_results_dict = { |
| 648 'flakes_in_a_row': 0, | 677 'flakes_in_a_row': 0, |
| 649 'stable_in_a_row': 0, | 678 'stable_in_a_row': 0, |
| 650 'stabled_out': True, | 679 'stabled_out': True, |
| 651 'flaked_out': True, | 680 'flaked_out': True, |
| 652 'last_build_number': 0, | 681 'last_build_number': 0, |
| 653 'lower_boundary': 100, | 682 'lower_boundary': 100, |
| 654 'upper_boundary': 110, | 683 'upper_boundary': 110, |
| 655 'lower_boundary_result': None, | 684 'lower_boundary_result': None, |
| 656 'sequential_run_index': 0 | 685 'sequential_run_index': 0 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 668 master_name, builder_name, build_number, step_name, test_name) | 697 master_name, builder_name, build_number, step_name, test_name) |
| 669 data_point = DataPoint() | 698 data_point = DataPoint() |
| 670 data_point.pass_rate = 1 | 699 data_point.pass_rate = 1 |
| 671 data_point.build_number = 100 | 700 data_point.build_number = 100 |
| 672 analysis.data_points.append(data_point) | 701 analysis.data_points.append(data_point) |
| 673 analysis.put() | 702 analysis.put() |
| 674 | 703 |
| 675 NextBuildNumberPipeline.run( | 704 NextBuildNumberPipeline.run( |
| 676 NextBuildNumberPipeline(), master_name, builder_name, | 705 NextBuildNumberPipeline(), master_name, builder_name, |
| 677 master_build_number, build_number, step_name, test_name, | 706 master_build_number, build_number, step_name, test_name, |
| 678 analysis.version_number, test_result_future, queue_name, | 707 analysis.version_number, test_result_future, |
| 679 flakiness_algorithm_results_dict) | 708 flakiness_algorithm_results_dict) |
| 680 self.assertEquals( | 709 self.assertEquals( |
| 681 flakiness_algorithm_results_dict['sequential_run_index'], 1) | 710 flakiness_algorithm_results_dict['sequential_run_index'], 1) |
| 682 | 711 |
| 683 def testNextBuildWhenTestNotExistingAfterStableInARow(self): | 712 def testNextBuildWhenTestNotExistingAfterStableInARow(self): |
| 684 master = MasterFlakeAnalysis.Create('m', 'b', 100, 's', 't') | 713 master = MasterFlakeAnalysis.Create('m', 'b', 100, 's', 't') |
| 685 master.data_points = self._GenerateDataPoints( | 714 master.data_points = self._GenerateDataPoints( |
| 686 pass_rates=[0.8, 1.0, 1.0, -1], build_numbers=[100, 80, 70, 60]) | 715 pass_rates=[0.8, 1.0, 1.0, -1], build_numbers=[100, 80, 70, 60]) |
| 687 | 716 |
| 688 flakiness_algorithm_results_dict = { | 717 flakiness_algorithm_results_dict = { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 730 flakiness_algorithm_results_dict['lower_boundary_result']) | 759 flakiness_algorithm_results_dict['lower_boundary_result']) |
| 731 | 760 |
| 732 def testNextBuildNumberIsLargerThanStartingBuildNumber(self): | 761 def testNextBuildNumberIsLargerThanStartingBuildNumber(self): |
| 733 master_name = 'm' | 762 master_name = 'm' |
| 734 builder_name = 'b' | 763 builder_name = 'b' |
| 735 master_build_number = 100 | 764 master_build_number = 100 |
| 736 build_number = 60 | 765 build_number = 60 |
| 737 step_name = 's' | 766 step_name = 's' |
| 738 test_name = 't' | 767 test_name = 't' |
| 739 test_result_future = 'trf' | 768 test_result_future = 'trf' |
| 740 queue_name = constants.DEFAULT_QUEUE | |
| 741 flakiness_algorithm_results_dict = { | 769 flakiness_algorithm_results_dict = { |
| 742 'flakes_in_a_row': 0, | 770 'flakes_in_a_row': 0, |
| 743 'stable_in_a_row': 3, | 771 'stable_in_a_row': 3, |
| 744 'stabled_out': False, | 772 'stabled_out': False, |
| 745 'flaked_out': False, | 773 'flaked_out': False, |
| 746 'last_build_number': 0, | 774 'last_build_number': 0, |
| 747 'lower_boundary': None, | 775 'lower_boundary': None, |
| 748 'upper_boundary': None, | 776 'upper_boundary': None, |
| 749 'lower_boundary_result': None, | 777 'lower_boundary_result': None, |
| 750 'sequential_run_index': 0 | 778 'sequential_run_index': 0 |
| 751 } | 779 } |
| 752 self._CreateAndSaveMasterFlakeAnalysis( | 780 self._CreateAndSaveMasterFlakeAnalysis( |
| 753 master_name, builder_name, master_build_number, step_name, | 781 master_name, builder_name, master_build_number, step_name, |
| 754 test_name, status=analysis_status.RUNNING) | 782 test_name, status=analysis_status.RUNNING) |
| 755 self._CreateAndSaveFlakeSwarmingTask( | 783 self._CreateAndSaveFlakeSwarmingTask( |
| 756 master_name, builder_name, build_number, step_name, | 784 master_name, builder_name, build_number, step_name, |
| 757 test_name, status=analysis_status.COMPLETED) | 785 test_name, status=analysis_status.COMPLETED) |
| 758 | 786 |
| 759 analysis = MasterFlakeAnalysis.GetVersion( | 787 analysis = MasterFlakeAnalysis.GetVersion( |
| 760 master_name, builder_name, master_build_number, step_name, test_name) | 788 master_name, builder_name, master_build_number, step_name, test_name) |
| 761 analysis.data_points = self._GenerateDataPoints( | 789 analysis.data_points = self._GenerateDataPoints( |
| 762 pass_rates=[1.0, 1.0, 1.0, -1], build_numbers=[100, 80, 70, 60]) | 790 pass_rates=[1.0, 1.0, 1.0, -1], build_numbers=[100, 80, 70, 60]) |
| 763 analysis.put() | 791 analysis.put() |
| 764 | 792 |
| 765 pipeline = NextBuildNumberPipeline() | 793 pipeline = NextBuildNumberPipeline() |
| 766 pipeline.run( | 794 pipeline.run( |
| 767 master_name, builder_name, | 795 master_name, builder_name, |
| 768 master_build_number, build_number, step_name, test_name, | 796 master_build_number, build_number, step_name, test_name, |
| 769 analysis.version_number, test_result_future, queue_name, | 797 analysis.version_number, test_result_future, |
| 770 flakiness_algorithm_results_dict) | 798 flakiness_algorithm_results_dict) |
| 771 | 799 |
| 772 analysis = MasterFlakeAnalysis.GetVersion( | 800 analysis = MasterFlakeAnalysis.GetVersion( |
| 773 master_name, builder_name, master_build_number, step_name, test_name) | 801 master_name, builder_name, master_build_number, step_name, test_name) |
| 774 self.assertEqual(analysis_status.COMPLETED, analysis.status) | 802 self.assertEqual(analysis_status.COMPLETED, analysis.status) |
| 775 | 803 |
| 776 def testNextBuildNumberIsSmallerThanLastBuildNumber(self): | 804 def testNextBuildNumberIsSmallerThanLastBuildNumber(self): |
| 777 master_name = 'm' | 805 master_name = 'm' |
| 778 builder_name = 'b' | 806 builder_name = 'b' |
| 779 master_build_number = 100 | 807 master_build_number = 100 |
| 780 build_number = 60 | 808 build_number = 60 |
| 781 step_name = 's' | 809 step_name = 's' |
| 782 test_name = 't' | 810 test_name = 't' |
| 783 test_result_future = 'trf' | 811 test_result_future = 'trf' |
| 784 queue_name = constants.DEFAULT_QUEUE | |
| 785 flakiness_algorithm_results_dict = { | 812 flakiness_algorithm_results_dict = { |
| 786 'flakes_in_a_row': 0, | 813 'flakes_in_a_row': 0, |
| 787 'stable_in_a_row': 3, | 814 'stable_in_a_row': 3, |
| 788 'stabled_out': False, | 815 'stabled_out': False, |
| 789 'flaked_out': False, | 816 'flaked_out': False, |
| 790 'last_build_number': 59, | 817 'last_build_number': 59, |
| 791 'lower_boundary': None, | 818 'lower_boundary': None, |
| 792 'upper_boundary': None, | 819 'upper_boundary': None, |
| 793 'lower_boundary_result': None, | 820 'lower_boundary_result': None, |
| 794 'sequential_run_index': 0 | 821 'sequential_run_index': 0 |
| 795 } | 822 } |
| 796 analysis = MasterFlakeAnalysis.Create( | 823 analysis = MasterFlakeAnalysis.Create( |
| 797 master_name, builder_name, master_build_number, step_name, test_name) | 824 master_name, builder_name, master_build_number, step_name, test_name) |
| 798 analysis.data_points = self._GenerateDataPoints( | 825 analysis.data_points = self._GenerateDataPoints( |
| 799 pass_rates=[1.0, 1.0, 1.0, 1.0], build_numbers=[100, 80, 70, 60]) | 826 pass_rates=[1.0, 1.0, 1.0, 1.0], build_numbers=[100, 80, 70, 60]) |
| 800 analysis.status = analysis_status.RUNNING | 827 analysis.status = analysis_status.RUNNING |
| 801 analysis.Save() | 828 analysis.Save() |
| 802 | 829 |
| 803 self._CreateAndSaveFlakeSwarmingTask( | 830 self._CreateAndSaveFlakeSwarmingTask( |
| 804 master_name, builder_name, build_number, step_name, | 831 master_name, builder_name, build_number, step_name, |
| 805 test_name, status=analysis_status.COMPLETED) | 832 test_name, status=analysis_status.COMPLETED) |
| 806 | 833 |
| 807 pipeline = NextBuildNumberPipeline() | 834 pipeline = NextBuildNumberPipeline() |
| 808 pipeline.run( | 835 pipeline.run( |
| 809 master_name, builder_name, | 836 master_name, builder_name, |
| 810 master_build_number, build_number, step_name, test_name, | 837 master_build_number, build_number, step_name, test_name, |
| 811 analysis.version_number, test_result_future, queue_name, | 838 analysis.version_number, test_result_future, |
| 812 flakiness_algorithm_results_dict) | 839 flakiness_algorithm_results_dict) |
| 813 | 840 |
| 814 analysis = MasterFlakeAnalysis.GetVersion( | 841 analysis = MasterFlakeAnalysis.GetVersion( |
| 815 master_name, builder_name, master_build_number, step_name, test_name) | 842 master_name, builder_name, master_build_number, step_name, test_name) |
| 816 self.assertEqual(analysis_status.COMPLETED, analysis.status) | 843 self.assertEqual(analysis_status.COMPLETED, analysis.status) |
| OLD | NEW |