def test008Queries(self): """Verify assorted query operations.""" project = self.createProject('test008') clone_path = self.cloneProject(project) gpatch = self.createPatch(clone_path, project) helper = self._GetHelper() # Multi-queries with one valid and one invalid term should raise. invalid_change_id = 'I1234567890123456789012345678901234567890' self.assertRaises(gerrit.GerritException, gerrit.GetGerritPatchInfo, [invalid_change_id, gpatch.change_id]) self.assertRaises(gerrit.GerritException, gerrit.GetGerritPatchInfo, [gpatch.change_id, invalid_change_id]) self.assertRaises(gerrit.GerritException, gerrit.GetGerritPatchInfo, ['9876543', gpatch.gerrit_number]) self.assertRaises(gerrit.GerritException, gerrit.GetGerritPatchInfo, [gpatch.gerrit_number, '9876543']) # Simple query by project/changeid/sha1. patch_info = helper.GrabPatchFromGerrit(gpatch.project, gpatch.change_id, gpatch.sha1) self.assertEqual(patch_info.gerrit_number, gpatch.gerrit_number) self.assertEqual(patch_info.remote, site_config.params.EXTERNAL_REMOTE) # Simple query by gerrit number to external remote. patch_info = gerrit.GetGerritPatchInfo([gpatch.gerrit_number]) self.assertEqual(patch_info[0].gerrit_number, gpatch.gerrit_number) self.assertEqual(patch_info[0].remote, site_config.params.EXTERNAL_REMOTE) # Simple query by gerrit number to internal remote. patch_info = gerrit.GetGerritPatchInfo(['*' + gpatch.gerrit_number]) self.assertEqual(patch_info[0].gerrit_number, gpatch.gerrit_number) self.assertEqual(patch_info[0].remote, site_config.params.INTERNAL_REMOTE) # Query to external server by gerrit number and change-id which refer to # the same change should return one result. fq_changeid = '~'.join((gpatch.project, 'master', gpatch.change_id)) patch_info = gerrit.GetGerritPatchInfo( [gpatch.gerrit_number, fq_changeid]) self.assertEqual(len(patch_info), 1) self.assertEqual(patch_info[0].gerrit_number, gpatch.gerrit_number) self.assertEqual(patch_info[0].remote, site_config.params.EXTERNAL_REMOTE) # Query to internal server by gerrit number and change-id which refer to # the same change should return one result. patch_info = gerrit.GetGerritPatchInfo( ['*' + gpatch.gerrit_number, '*' + fq_changeid]) self.assertEqual(len(patch_info), 1) self.assertEqual(patch_info[0].gerrit_number, gpatch.gerrit_number) self.assertEqual(patch_info[0].remote, site_config.params.INTERNAL_REMOTE)
def testGetGerritPatchInfo(self): """Test ordering of results in GetGerritPatchInfo""" # Swizzle from our old syntax to the new syntax. changes = [] for change in self.CHANGES: if change.startswith('*'): changes.append('chrome-internal:%s' % (change[1:], )) else: changes.append('chromium:%s' % (change, )) results = list(gerrit.GetGerritPatchInfo(changes)) self.assertEqual(changes, [x.gerrit_number_str for x in results])
def main(argv): parser = GetParser() options = parser.parse_args(argv) options.Freeze() local_manifest = ResolveLocalManifestPath(options) if local_manifest: logging.info('Using local_manifest: %s', local_manifest) if options.manifest_url: manifest_url = options.manifest_url elif options.external: manifest_url = config_lib.GetSiteParams().MANIFEST_URL else: manifest_url = config_lib.GetSiteParams().MANIFEST_INT_URL osutils.SafeMakedirs(options.repo_root) repo = repository.RepoRepository( manifest_repo_url=manifest_url, directory=options.repo_root, branch=options.branch, git_cache_dir=options.git_cache_dir, repo_url=options.repo_url, groups=options.groups) if options.copy_repo: repo.PreLoad(options.copy_repo) if repository.IsARepoRoot(options.repo_root): repo.BuildRootGitCleanup(prune_all=True) repo.Sync(local_manifest=local_manifest, detach=True) if options.gerrit_patches: patches = gerrit.GetGerritPatchInfo(options.gerrit_patches) # TODO: Extract patches from manifest synced. helper_pool = patch_series.HelperPool.SimpleCreate( cros_internal=not options.external, cros=True) series = patch_series.PatchSeries( path=options.repo_root, helper_pool=helper_pool, forced_manifest=None) _, failed_tot, failed_inflight = series.Apply(patches) failed = failed_tot + failed_inflight if failed: logging.error('Failed to apply: %s', ', '.join(str(p) for p in failed)) return 1
def testIsAlreadyMerged(self): # Note that these are magic constants- they're known to be # merged (and the other abandoned) in public gerrit. # If old changes are ever flushed, or something 'special' occurs, # then this will break. That it's an acceptable risk. # Note we should be checking a known open one; seems rather likely # that'll get closed inadvertantly thus breaking the tests (not # an acceptable risk in the authors opinion). merged, abandoned, still_open = gerrit.GetGerritPatchInfo([ GERRIT_MERGED_CHANGEID, GERRIT_ABANDONED_CHANGEID, GERRIT_OPEN_CHANGEID ]) self.assertTrue(merged.IsAlreadyMerged()) self.assertFalse(abandoned.IsAlreadyMerged()) self.assertFalse(still_open.IsAlreadyMerged())
def _common_test(self, patches, server='gerrit.chromium.org', remote=constants.EXTERNAL_REMOTE, calls_allowed=1): output_obj = cros_build_lib.CommandResult() output_obj.returncode = 0 output_obj.output = self.result for _ in xrange(calls_allowed): cros_build_lib.RunCommand(mox.In(server), redirect_stdout=True).AndReturn(output_obj) self.mox.ReplayAll() patch_info = gerrit.GetGerritPatchInfo(patches) self.assertEquals(patch_info[0].remote, remote) self.mox.VerifyAll() return patch_info
def testPatchInfoParsing(self): """Test parsing of the JSON results.""" patches = ['Icb8e1d315d465a07'] output_obj = cros_build_lib.CommandResult() output_obj.returncode = 0 output_obj.output = self.result cros_build_lib.RunCommand(mox.In('gerrit.chromium.org'), redirect_stdout=True).AndReturn(output_obj) self.mox.ReplayAll() patch_info = gerrit.GetGerritPatchInfo(patches) self.assertEquals(patch_info[0].project, 'chromiumos/chromite') self.assertEquals(patch_info[0].ref, 'refs/changes/44/2144/3') self.mox.VerifyAll()
def FromOptions(cls, gerrit_patches=None, local_patches=None, sourceroot=None, remote_patches=None): """Generate patch objects from passed in options. Args: gerrit_patches: Gerrit ids that gerrit.GetGerritPatchInfo accepts. local_patches: Local ids that cros_patch.PrepareLocalPatches accepts. sourceroot: The source repository to look up |local_patches|. remote_patches: Remote ids that cros_patch.PrepareRemotePatches accepts. Returns: A TrybotPatchPool object. Raises: gerrit.GerritException, cros_patch.PatchException """ if gerrit_patches: gerrit_patches = gerrit.GetGerritPatchInfo(gerrit_patches) for patch in gerrit_patches: if patch.IsAlreadyMerged(): logging.warning('Patch %s has already been merged.', patch) else: gerrit_patches = () if local_patches: manifest = git.ManifestCheckout.Cached(sourceroot) local_patches = cros_patch.PrepareLocalPatches( manifest, local_patches) else: local_patches = () if remote_patches: remote_patches = cros_patch.PrepareRemotePatches(remote_patches) else: remote_patches = () return cls(gerrit_patches=gerrit_patches, local_patches=local_patches, remote_patches=remote_patches)
def main(argv): parser = _GetParser() options = parser.parse_args(argv) changes = options.change branch = options.branch try: patches = gerrit.GetGerritPatchInfo(changes) except ValueError as e: logging.error('Invalid patch: %s', e) cros_build_lib.Die('Did you swap the branch/gerrit number?') # Suppress all logging info output unless we're running debug. if not options.debug: logging.getLogger().setLevel(logging.NOTICE) # Get a pointer to your repo checkout to look up the local project paths for # both email addresses and for using your checkout as a git mirror. manifest = None if options.mirror: try: manifest = git.ManifestCheckout.Cached(constants.SOURCE_ROOT) except OSError as e: if e.errno == errno.ENOENT: logging.error('Unable to locate ChromiumOS checkout: %s', constants.SOURCE_ROOT) logging.error('Did you mean to use --nomirror?') return 1 raise if not _ManifestContainsAllPatches(manifest, patches): return 1 else: if not options.email: chromium_email = '*****@*****.**' % os.environ['USER'] logging.notice('--nomirror set without email, using %s', chromium_email) options.email = chromium_email index = 0 work_dir = None root_work_dir = tempfile.mkdtemp(prefix='cros_merge_to_branch') try: for index, (change, patch) in enumerate(zip(changes, patches)): # We only clone the project and set the committer the first time. work_dir = os.path.join(root_work_dir, patch.project) if not os.path.isdir(work_dir): branch = _SetupWorkDirectoryForPatch(work_dir, patch, branch, manifest, options.email) # Now that we have the project checked out, let's apply our change and # create a new change on Gerrit. logging.notice('Uploading change %s to branch %s', change, branch) urls = _UploadChangeToBranch(work_dir, patch, branch, options.draft, options.dryrun) logging.notice('Successfully uploaded %s to %s', change, branch) for url in urls: if url.endswith('\x1b[K'): # Git will often times emit these escape sequences. url = url[0:-3] logging.notice(' URL: %s', url) except (cros_build_lib.RunCommandError, cros_patch.ApplyPatchException, git.AmbiguousBranchName, OSError) as e: # Tell the user how far we got. good_changes = changes[:index] bad_changes = changes[index:] logging.warning( '############## SOME CHANGES FAILED TO UPLOAD ############') if good_changes: logging.notice('Successfully uploaded change(s) %s', ' '.join(good_changes)) # Printing out the error here so that we can see exactly what failed. This # is especially useful to debug without using --debug. logging.error('Upload failed with %s', str(e).strip()) if not options.wipe: logging.error( 'Not wiping the directory. You can inspect the failed ' 'change at %s; After fixing the change (if trivial) you can' ' try to upload the change by running:\n' 'git commit -a -c CHERRY_PICK_HEAD\n' 'git push %s HEAD:refs/for/%s', work_dir, patch.project_url, branch) else: logging.error( '--nowipe not set thus deleting the work directory. If you ' 'wish to debug this, re-run the script with change(s) ' '%s and --nowipe by running:\n %s %s %s --nowipe', ' '.join(bad_changes), sys.argv[0], ' '.join(bad_changes), branch) # Suppress the stack trace if we're not debugging. if options.debug: raise else: return 1 finally: if options.wipe: shutil.rmtree(root_work_dir) if options.dryrun: logging.notice('Success! To actually upload changes, re-run without ' '--dry-run.') else: logging.notice('Successfully uploaded all changes requested.') return 0
def testGetGerritPatchInfo(self): """Test ordering of results in GetGerritPatchInfo""" changes = self.CHANGES results = list(gerrit.GetGerritPatchInfo(changes)) self.assertEqual(changes, [x.gerrit_number_str for x in results])