コード例 #1
0
    def testGetValidBoundingBuildsForStepCommitRightAtUpperBound(self, *_):
        upper_bound_build_number = 4
        lower_bound, upper_bound = step_util.GetValidBoundingBuildsForStep(
            'm', 'b', 's', None, upper_bound_build_number, 50)

        self.assertEqual(50, lower_bound.commit_position)
        self.assertEqual(50, upper_bound.commit_position)
コード例 #2
0
    def testGetValidBoundingBuildsForStepCommitBeforeEarliestBuild(self, *_):
        lower_bound_build_number = 3
        lower_bound, upper_bound = step_util.GetValidBoundingBuildsForStep(
            'm', 'b', 's', lower_bound_build_number, 100, 10)

        self.assertIsNone(lower_bound)
        self.assertEqual(lower_bound_build_number, upper_bound.build_number)
コード例 #3
0
  def testGetValidBoundingBuildsForStepCommitAfterLatestBuildInvalid(self, *_):
    upper_bound_build_number = 5
    lower_bound, upper_bound = step_util.GetValidBoundingBuildsForStep(
        'm', 'b', 's', None, upper_bound_build_number, 10000)

    self.assertIsNone(lower_bound)
    self.assertIsNone(upper_bound)
コード例 #4
0
 def testGetValidBoundingBuildsForStepExactMatch(self, *_):
     lower_bound, upper_bound = step_util.GetValidBoundingBuildsForStep(
         'm', 'b', 's', 0, 100, 30)
     self.assertEqual(1, lower_bound.build_number)
     self.assertEqual(2, upper_bound.build_number)
コード例 #5
0
    def RunImpl(self, parameters):
        """Determines the Isolated sha to run in swarming given a commit position.

    If the requested commit position maps directly to a  build, simply get that
    existing build's isolated sha. Otherwise, trigger a try job to compile and
    isolate at that revision and return the resulting sha.
    """
        analysis = ndb.Key(urlsafe=parameters.analysis_urlsafe_key).get()
        assert analysis

        master_name = analysis.master_name
        builder_name = analysis.builder_name
        commit_position = parameters.commit_position
        step_name = analysis.step_name
        isolate_target_name = parameters.step_metadata.isolate_target_name

        reference_build_info = build_util.GetBuildInfo(master_name,
                                                       builder_name,
                                                       analysis.build_number)
        parent_mastername = (reference_build_info.parent_mastername
                             or master_name)
        parent_buildername = (reference_build_info.parent_buildername
                              or builder_name)

        targets = (IsolatedTarget.FindIsolateAtOrAfterCommitPositionByMaster(
            parent_mastername, parent_buildername, constants.GITILES_HOST,
            constants.GITILES_PROJECT, constants.GITILES_REF,
            isolate_target_name, commit_position))

        # TODO(crbug.com/872992): Remove this entire branch's fallback logic once
        # LUCI migration is complete.
        if not targets:
            analysis.LogInfo((
                'No IsolatedTargets found for {}/{} with minimum commit position '
                '{}. Falling back to searching buildbot').format(
                    master_name, builder_name, commit_position))
            _, earliest_containing_build = step_util.GetValidBoundingBuildsForStep(
                master_name, builder_name, step_name, None,
                parameters.upper_bound_build_number, commit_position)

            assert earliest_containing_build, (
                'Unable to find nearest build cycle with minimum commit position '
                '{}'.format(commit_position))

            build_commit_position = earliest_containing_build.commit_position
            assert build_commit_position >= commit_position, (
                'Upper bound build commit position {} is before {}'.format(
                    build_commit_position, commit_position))

            if build_commit_position == commit_position:  # pragma: no branch
                get_build_sha_parameters = self.CreateInputObjectInstance(
                    GetIsolateShaForBuildParameters,
                    master_name=master_name,
                    builder_name=builder_name,
                    build_number=earliest_containing_build.build_number,
                    step_name=step_name,
                    url=buildbot.CreateBuildUrl(
                        master_name, builder_name,
                        earliest_containing_build.build_number))
                yield GetIsolateShaForBuildPipeline(get_build_sha_parameters)
                return

        if targets:
            upper_bound_target = targets[0]
            if upper_bound_target.commit_position == commit_position:
                # The requested commit position is that of a found IsolatedTarget.
                get_target_input = GetIsolateShaForTargetInput(
                    isolated_target_urlsafe_key=upper_bound_target.key.urlsafe(
                    ))
                yield GetIsolateShaForTargetPipeline(get_target_input)
                return

        # The requested commit position needs to be compiled.
        cache_name = swarmbot_util.GetCacheName(
            parent_mastername,
            parent_buildername,
            suffix=flake_constants.FLAKE_CACHE_SUFFIX)
        test_name = analysis.test_name

        try_job = flake_try_job.GetTryJob(master_name, builder_name, step_name,
                                          test_name, parameters.revision)
        run_flake_try_job_parameters = self.CreateInputObjectInstance(
            RunFlakeTryJobParameters,
            analysis_urlsafe_key=parameters.analysis_urlsafe_key,
            revision=parameters.revision,
            flake_cache_name=cache_name,
            dimensions=parameters.dimensions,
            isolate_target_name=isolate_target_name,
            urlsafe_try_job_key=try_job.key.urlsafe())

        with pipeline.InOrder():
            try_job_result = yield RunFlakeTryJobPipeline(
                run_flake_try_job_parameters)
            get_isolate_sha_from_try_job_input = self.CreateInputObjectInstance(
                GetIsolateShaForTryJobParameters,
                try_job_result=try_job_result,
                step_name=step_name)
            yield GetIsolateShaForTryJobPipeline(
                get_isolate_sha_from_try_job_input)
コード例 #6
0
    def RunImpl(self, parameters):
        """Pipeline for determining the next commit position to analyze."""

        analysis_urlsafe_key = parameters.analysis_urlsafe_key
        analysis = ndb.Key(urlsafe=analysis_urlsafe_key).get()
        assert analysis

        master_name = analysis.master_name
        builder_name = analysis.builder_name
        specified_lower_bound = parameters.commit_position_range.lower
        specified_upper_bound = parameters.commit_position_range.upper

        data_points = analysis.GetDataPointsWithinCommitPositionRange(
            IntRange(lower=specified_lower_bound, upper=specified_upper_bound))

        # Data points must be sorted in reverse order by commit position before.
        data_points = sorted(data_points,
                             key=lambda k: k.commit_position,
                             reverse=True)

        # A suspected build id is available when there is a regression range that
        # spans a single build cycle. During this time, bisect is preferred to
        # exponential search.
        use_bisect = (analysis.suspected_flake_build_number is not None
                      or analysis.suspected_build_id is not None)
        latest_regression_range = analysis.GetLatestRegressionRange()

        calculated_next_commit_id, culprit_commit_id = (
            lookback_algorithm.GetNextCommitId(data_points, use_bisect,
                                               latest_regression_range))

        if calculated_next_commit_id is None:
            # The analysis is finished according to the lookback algorithm.
            return NextCommitPositionOutput(
                next_commit_id=None, culprit_commit_id=culprit_commit_id)

        cutoff_commit_position = (
            next_commit_position_utils.GetEarliestCommitPosition(
                specified_lower_bound, specified_upper_bound))

        if calculated_next_commit_id.commit_position < cutoff_commit_position:
            # Long-standing flake. Do not continue the analysis.
            return NextCommitPositionOutput(next_commit_id=None,
                                            culprit_commit_id=None)

        # Try the analysis' heuristic results first, if any.
        next_commit_id = (
            next_commit_position_utils.GetNextCommitIdFromHeuristicResults(
                analysis_urlsafe_key))

        if next_commit_id is not None:
            # Heuristic results are available and should be tried first.
            assert not analysis.FindMatchingDataPointWithCommitPosition(
                next_commit_id.commit_position
            ), ('Existing heuristic results suggest commit position {} which has '
                'already been run'.format(next_commit_id.commit_position))
            return NextCommitPositionOutput(next_commit_id=next_commit_id,
                                            culprit_commit_id=None)

        # Round off the next calculated commit position to the nearest builds on
        # both sides.
        reference_build_info = build_util.GetBuildInfo(master_name,
                                                       builder_name,
                                                       analysis.build_number)
        parent_mastername = reference_build_info.parent_mastername or master_name
        parent_buildername = (reference_build_info.parent_buildername
                              or builder_name)
        target_name = parameters.step_metadata.isolate_target_name

        try:
            lower_bound_target, upper_bound_target = (
                step_util.GetBoundingIsolatedTargets(
                    parent_mastername, parent_buildername, target_name,
                    calculated_next_commit_id.commit_position))

            # Update the analysis' suspected build cycle if identified.
            analysis.UpdateSuspectedBuild(lower_bound_target,
                                          upper_bound_target)

            lower_bound_commit_id, upper_bound_commit_id = (
                next_commit_position_utils.GenerateCommitIDsForBoundingTargets(
                    data_points, lower_bound_target, upper_bound_target))
        except AssertionError as e:
            # Fallback to searching buildbot in case builds aren't indexed as
            # IsolatedTargets.
            # TODO(crbug.com/872992): Remove fallback logic.
            analysis.LogError(e.message)
            analysis.LogWarning((
                'Failed to determine isolated targets surrounding {}. Falling back '
                'to searching buildbot').format(
                    calculated_next_commit_id.commit_position))
            upper_bound_build_number = analysis.GetLowestUpperBoundBuildNumber(
                calculated_next_commit_id)
            lower_bound_build, upper_bound_build = (
                step_util.GetValidBoundingBuildsForStep(
                    master_name, builder_name, analysis.step_name, None,
                    upper_bound_build_number,
                    calculated_next_commit_id.commit_position))

            # Update the analysis' suspected build cycle if identified.
            analysis.UpdateSuspectedBuildUsingBuildInfo(
                lower_bound_build, upper_bound_build)
            lower_bound_commit_id = CommitID(
                commit_position=lower_bound_build.commit_position,
                revision=lower_bound_build.chromium_revision
            ) if lower_bound_build else None
            upper_bound_commit_id = CommitID(
                commit_position=upper_bound_build.commit_position,
                revision=upper_bound_build.chromium_revision
            ) if upper_bound_build else None

        # When identifying the neighboring builds of the requested commit position,
        # heuristic analysis may become eligible if the neighboring builds are
        # adjacent to one another.
        if analysis.CanRunHeuristicAnalysis():
            # Run heuristic analysis if eligible and not yet already done.
            heuristic_analysis.RunHeuristicAnalysis(analysis)

            # Try the newly computed heuristic results if any were identified.
            next_commit_id = (
                next_commit_position_utils.GetNextCommitIdFromHeuristicResults(
                    analysis_urlsafe_key))
            if next_commit_id is not None:  # pragma: no branch
                assert not analysis.FindMatchingDataPointWithCommitPosition(
                    next_commit_id.commit_position
                ), ('Newly run heuristic results suggest commit position {} which has '
                    'already been run'.format(next_commit_id))
                return NextCommitPositionOutput(next_commit_id=next_commit_id,
                                                culprit_commit_id=None)

        # Pick the commit position of the returned neighboring builds that has not
        # yet been analyzed if possible, or the commit position itself when not.
        build_range = CommitIDRange(lower=lower_bound_commit_id,
                                    upper=upper_bound_commit_id)
        actual_next_commit_id = (
            next_commit_position_utils.GetNextCommitIDFromBuildRange(
                analysis, build_range, calculated_next_commit_id))
        assert not analysis.FindMatchingDataPointWithCommitPosition(
            actual_next_commit_id.commit_position), (
                'Rounded-off commit position {} has already been run'.format(
                    actual_next_commit_id.commit_position))
        return NextCommitPositionOutput(next_commit_id=actual_next_commit_id,
                                        culprit_commit_id=culprit_commit_id)