Ejemplo n.º 1
0
    def _MkPatch(self, source, sha1, ref='refs/heads/master', **kwds):
        json = self.test_json
        remote = kwds.pop('remote', constants.EXTERNAL_REMOTE)
        url_prefix = kwds.pop('url_prefix', constants.GERRIT_SSH_URL)
        suppress_branch = kwds.pop('suppress_branch', False)
        change_id = kwds.pop('ChangeId', None)
        if change_id is None:
            change_id = self.MakeChangeId()
        json.update(kwds)
        change_num, patch_num = _GetNumber(), _GetNumber()
        # Note we intentionally use a gerrit like refspec here; we want to
        # ensure that none of our common code pathways puke on a non head/tag.
        refspec = gerrit.GetChangeRef(change_num + 1000, patch_num)
        json['currentPatchSet'].update(
            dict(number=patch_num, ref=refspec, revision=sha1))
        json['branch'] = os.path.basename(ref)
        json['_unittest_url_bypass'] = source
        json['id'] = change_id

        obj = self.patch_kls(json.copy(), remote, url_prefix)
        self.assertEqual(obj.patch_dict, json)
        self.assertEqual(obj.remote, remote)
        self.assertEqual(obj.url_prefix, url_prefix)
        self.assertEqual(obj.project, json['project'])
        self.assertEqual(obj.ref, refspec)
        self.assertEqual(obj.change_id, change_id)
        self.assertEqual(
            obj.id,
            cros_patch.FormatChangeId(change_id, force_internal=obj.internal))
        # Now make the fetching actually work, if desired.
        if not suppress_branch:
            # Note that a push is needed here, rather than a branch; branch
            # will just make it under refs/heads, we want it literally in
            # refs/changes/
            self._run(['git', 'push', source,
                       '%s:%s' % (sha1, refspec)], source)
        return obj
Ejemplo n.º 2
0
    def QueryMultipleCurrentPatchset(self, queries):
        """Query chromeos gerrit servers for the current patch for given changes

    Args:
     queries: sequence of Change-IDs (Ic04g2ab, 6 characters to 40),
       or change numbers (12345 for example).
       A change number can refer to the same change as a Change ID,
       but Change IDs given should be unique, and the same goes for Change
       Numbers.

    Returns:
     an unordered sequence of GerritPatches for each requested query.

    Raises:
     GerritException: if a query fails to match, or isn't specific enough,
      or a query is malformed.
     RunCommandException: if for whatever reason, the ssh invocation to
      gerrit fails.
    """

        if not queries:
            return

        # process the queries in two seperate streams; this is done so that
        # we can identify exactly which patchset returned no results; it's
        # basically impossible to do it if you query with mixed numeric/ID

        numeric_queries = [x for x in queries if x.isdigit()]

        if numeric_queries:
            query = ' OR '.join('change:%s' % x for x in numeric_queries)
            results = self.Query(query, sort='number')

            # Sort via alpha comparison, rather than integer; Query sorts via the
            # raw textual field, thus we need to match that.
            numeric_queries = sorted(numeric_queries, key=str)

            for query, result in itertools.izip_longest(
                    numeric_queries, results):
                if result is None or result.gerrit_number != query:
                    raise GerritException(
                        'Change number %s not found on server %s.' %
                        (query, self.host))

                yield query, result

        id_queries = sorted(
            cros_patch.FormatPatchDep(x, sha1=False) for x in queries
            if not x.isdigit())

        if not id_queries:
            return

        results = self.Query(' OR '.join('change:%s' % x for x in id_queries),
                             sort='id')

        last_patch_id = None
        for query, result in itertools.izip_longest(id_queries, results):
            # case insensitivity to ensure that if someone queries for IABC
            # and gerrit returns Iabc, we still properly match.
            result_id = ''
            if result:
                result_id = cros_patch.FormatChangeId(result.change_id)

            if result is None or (query and not result_id.startswith(query)):
                if last_patch_id and result_id.startswith(last_patch_id):
                    raise GerritException(
                        'While querying for change %s, we received '
                        'back multiple results.  Please be more specific.  Server=%s'
                        % (last_patch_id, self.host))

                raise GerritException('Change-ID %s not found on server %s.' %
                                      (query, self.host))

            if query is None:
                raise GerritException(
                    'While querying for change %s, we received '
                    'back multiple results.  Please be more specific.  Server=%s'
                    % (last_patch_id, self.host))

            yield query, result
            last_patch_id = query