def TriggerSwarmingTask(run_swarming_task_parameters, runner_id): """Triggers a swarming rerun for the given tests in a given build.""" master_name, builder_name, build_number = ( run_swarming_task_parameters.build_key.GetParts()) step_name = run_swarming_task_parameters.step_name tests = run_swarming_task_parameters.tests assert tests, 'No tests to trigger swarming task for.' http_client = FinditHttpClient() # 1. Retrieve Swarming task parameters from a given Swarming task id. ref_task_id, ref_request = swarming.GetReferredSwarmingTaskRequestInfo( master_name, builder_name, build_number, step_name, http_client) # 2. Update/Overwrite parameters for the re-run. iterations_to_rerun = waterfall_config.GetSwarmingSettings().get( 'iterations_to_rerun') new_request = CreateNewSwarmingTaskRequest(runner_id, ref_task_id, ref_request, master_name, builder_name, build_number, step_name, tests, iterations_to_rerun) # 3. Trigger a new Swarming task to re-run the failed tests. task_id, _ = swarming_util.TriggerSwarmingTask(swarming.SwarmingHost(), new_request, http_client) if task_id: # pragma: no branch. # 4. Update swarming task. OnSwarmingTaskTriggered(master_name, builder_name, build_number, step_name, tests, task_id, iterations_to_rerun, new_request) return task_id
def _BotsAvailableForTask(step_metadata): """Check if there are available bots for a swarming task's dimensions. Args: step_metadata (dict): Info about a step to determine the bot's dimensions to query Swarming with about bot availability. Returns: (bool): Whether or not there are enough bots available to trigger the task immediately. """ if not step_metadata: return False minimum_number_of_available_bots = ( waterfall_config.GetSwarmingSettings().get( 'minimum_number_of_available_bots', flake_constants.DEFAULT_MINIMUM_NUMBER_AVAILABLE_BOTS)) minimum_percentage_of_available_bots = ( waterfall_config.GetSwarmingSettings().get( 'minimum_percentage_of_available_bots', flake_constants.DEFAULT_MINIMUM_PERCENTAGE_AVAILABLE_BOTS)) dimensions = step_metadata.get('dimensions') bot_counts = swarming_util.GetBotCounts(swarming.SwarmingHost(), dimensions, FinditHttpClient) total_count = bot_counts.count or -1 available_count = bot_counts.available or 0 available_rate = float(available_count) / total_count return (available_count > minimum_number_of_available_bots and available_rate > minimum_percentage_of_available_bots)
def ListTasks(experiment_id, isolate_hash): tag_filter = {'experiment_id': experiment_id + isolate_hash[:4]} return [ i.task_id for i in swarming_util.ListTasks(swarming.SwarmingHost(), tag_filter, FinditHttpClient()) ]
def TriggerSwarmingTask(master_name, builder_name, reference_build_number, step_name, test_name, isolate_sha, iterations, timeout_seconds, runner_id): """Triggers a flake swarming rerun of a test against a given isolate sha. Args: master_name (str): The name of the master to find a reference task. builder_name (str): The name of the builder to find a reference task. reference_build_number (int): A representative build number to find a reference build. step_name (str): The name of the step on which the flaky test lives. test_name (str): The name of the test to trigger the swarming task against. isolate_sha (str): The location of the compiled binares to trigger a task against. timeout_seconds (int): The maximum allotted time for the task to complete. runner_id (str): The identifier for the caller of this function to post pubsub notifications to about task state changes. Returns: task_id (str): The resulting task id that is triggered on Swarming. """ # 1. Retrieve the reference swarming task with matching configuration of the # build that flakiness was first identified in. ref_task_id, ref_request = swarming.GetReferredSwarmingTaskRequestInfo( master_name, builder_name, reference_build_number, step_name, _FINDIT_HTTP_CLIENT) # 2. Create a swarming task request from the reference request with desired # fields updated. new_request = CreateNewSwarmingTaskRequest(runner_id, ref_task_id, ref_request, master_name, builder_name, step_name, test_name, isolate_sha, iterations, timeout_seconds) # 3. Trigger a new swarming task. task_id, _ = swarming_util.TriggerSwarmingTask(swarming.SwarmingHost(), new_request, _FINDIT_HTTP_CLIENT) # Monitoring. monitoring.OnSwarmingTaskStatusChange('trigger', 'identify-regression-range') return task_id
def GetBotsByDimension(dimensions, http_client): url = BOT_LIST_URL % (swarming.SwarmingHost(), swarming_util.ParametersToQueryString( dimensions, 'dimensions')) content, error = http_client_util.SendRequestToServer(url, http_client) if error: logging.error( 'failed to list bots by dimension with %s, falling back to ' 'any selecting any bot', error) return [] if not content: logging.warning('got blank response from %s', url) return [] content_data = json.loads(content) return content_data.get('items', [])
def GetSwarmingTaskDataAndResult(task_id, http_client=_FINDIT_HTTP_CLIENT): """Gets information about a swarming task. Returns: (str, dict, dict): The state, test result and error for a swarming task. """ data, error = swarming_util.GetSwarmingTaskResultById(swarming.SwarmingHost(), task_id, http_client) error = SwarmingTaskError.FromSerializable(error) if not data: return None, None, error task_state = data['state'] output_json = None if task_state not in constants.STATE_NOT_STOP: if task_state == constants.STATE_COMPLETED: outputs_ref = data.get('outputs_ref') # If swarming task aborted because of errors in request arguments, # it's possible that there is no outputs_ref. if not outputs_ref: error = error or SwarmingTaskError.GenerateError( swarming_task_error.NO_TASK_OUTPUTS) else: output_json, error = GetOutputJsonByOutputsRef(outputs_ref, http_client) if not output_json: error = error or SwarmingTaskError.GenerateError( swarming_task_error.NO_OUTPUT_JSON) else: # The swarming task did not complete successfully. logging.error('Swarming task %s stopped with status: %s', task_id, task_state) error = SwarmingTaskError.GenerateError( swarming_task_error.STATES_NOT_RUNNING_TO_ERROR_CODES[task_state]) return data, output_json, error