def _makeDefaultStackedOnBranch(self, private=False): """Make a default stacked-on branch. This creates a database product branch, makes it the default stacked-on branch for its product and creates a Bazaar branch for it. :param private: Whether the created branch should be private or not (defaults to not). :return: `IBranch`. """ # Make the branch in the database. product = self.factory.makeProduct() if private: information_type = InformationType.USERDATA else: information_type = InformationType.PUBLIC default_branch = self.factory.makeProductBranch( product=product, information_type=information_type) transaction.commit() # Create the underlying bzr branch. lp_server = self.getLPServerForUser(default_branch.owner) BzrDir.create_branch_convenience( lp_server.get_url() + default_branch.unique_name) transaction.commit() # Make it the default stacked-on branch for the product. series = removeSecurityProxy(product.development_focus) series.branch = default_branch self.assertEqual( default_branch, IBranchTarget(product).default_stacked_on_branch) return default_branch
def test_shared_repos(self): self.make_repository('a', shared=True) BzrDir.create_branch_convenience('a/branch1') b = BzrDir.create_branch_convenience('a/branch2') b.create_checkout(lightweight=True, to_location='b') out, err = self.run_bzr('branches b') self.assertEqual(out, " branch1\n" "* branch2\n")
def test_shared_repos(self): self.make_repository('a', shared=True) BzrDir.create_branch_convenience('a/branch1') b = BzrDir.create_branch_convenience('a/branch2') b.create_checkout(lightweight=True, to_location='b') out, err = self.run_bzr('branches b') self.assertEquals(out, " branch1\n" "* branch2\n")
def ensure_repo_consistency(self): """ Makes sure the self.repo_location directory is a Bazaar branch. The repo and Bazaar branch will be created if they don't already exist. Any unknown or modified files will be commited to the branch. """ try: BzrDir.open(self.repo_location) except bzrlib.errors.NotBranchError, e: logger.info("Location [%s] is not a Bazaar branch. Will turn it into one." % self.repo_location) BzrDir.create_branch_convenience(self.repo_location)
def ensure_repo_consistency(self): """ Makes sure the self.repo_location directory is a Bazaar branch. The repo and Bazaar branch will be created if they don't already exist. Any unknown or modified files will be commited to the branch. Also, 'bzr whoami' will be set to the current user so that all commands can be traced back to an actual person (assuming everyone has their own logins). """ try: BzrDir.open(self.repo_location) except bzrlib.errors.NotBranchError, e: logger.info('Location [{}] is not a Bazaar branch. Will turn it into one.'.format(self.repo_location)) BzrDir.create_branch_convenience(self.repo_location)
def ensure_repo_consistency(self): """ Makes sure the self.repo_location directory is a Bazaar branch. The repo and Bazaar branch will be created if they don't already exist. Any unknown or modified files will be commited to the branch. Also, 'bzr whoami' will be set to the current user so that all commands can be traced back to an actual person (assuming everyone has their own logins). """ try: BzrDir.open(self.repo_location) except bzrlib.errors.NotBranchError, e: logger.info( 'Location [{}] is not a Bazaar branch. Will turn it into one.'. format(self.repo_location)) BzrDir.create_branch_convenience(self.repo_location)
def test_post_push_bound_branch(self): # pushing to a bound branch should pass in the master branch to the # hook, allowing the correct number of emails to be sent, while still # allowing hooks that want to modify the target to do so to both # instances. target = self.make_branch('target') local = self.make_branch('local') try: local.bind(target) except errors.UpgradeRequired: # We can't bind this format to itself- typically it is the local # branch that doesn't support binding. As of May 2007 # remotebranches can't be bound. Let's instead make a new local # branch of the default type, which does allow binding. # See https://bugs.launchpad.net/bzr/+bug/112020 local = BzrDir.create_branch_convenience('local2') local.bind(target) source = self.make_branch('source') Branch.hooks.install_named_hook('post_push', self.capture_post_push_hook, None) source.push(local) # with nothing there we should still get a notification, and # have both branches locked at the notification time. self.assertEqual([ ('post_push', source, local.base, target.base, 0, NULL_REVISION, 0, NULL_REVISION, True, True, True) ], self.hook_calls)
def test_post_push_bound_branch(self): # pushing to a bound branch should pass in the master branch to the # hook, allowing the correct number of emails to be sent, while still # allowing hooks that want to modify the target to do so to both # instances. target = self.make_branch('target') local = self.make_branch('local') try: local.bind(target) except errors.UpgradeRequired: # We can't bind this format to itself- typically it is the local # branch that doesn't support binding. As of May 2007 # remotebranches can't be bound. Let's instead make a new local # branch of the default type, which does allow binding. # See https://bugs.launchpad.net/bzr/+bug/112020 local = BzrDir.create_branch_convenience('local2') local.bind(target) source = self.make_branch('source') Branch.hooks.install_named_hook('post_push', self.capture_post_push_hook, None) source.push(local) # with nothing there we should still get a notification, and # have both branches locked at the notification time. self.assertEqual([('post_push', source, local.base, target.base, 0, NULL_REVISION, 0, NULL_REVISION, True, True, True)], self.hook_calls)
def test_lock_with_magic_id(self): # When the subprocess locks a branch, it is locked with the right ID. class PullerMonitorProtocolWithLockID( scheduler.PullerMonitorProtocol): """Subclass of PullerMonitorProtocol with a lock_id method. This protocol defines a method that records on the listener the lock id reported by the subprocess. """ def do_lock_id(self, id): """Record the lock id on the listener.""" self.listener.lock_ids.append(id) class PullerMasterWithLockID(scheduler.PullerMaster): """A subclass of PullerMaster that allows recording of lock ids. """ protocol_class = PullerMonitorProtocolWithLockID check_lock_id_script = """ branch.lock_write() protocol.mirrorFailed('a', 'b') protocol.sendEvent( 'lock_id', branch.control_files._lock.peek().get('user')) sys.stdout.flush() branch.unlock() """ puller_master = self.makePullerMaster( PullerMasterWithLockID, check_lock_id_script) puller_master.lock_ids = [] # We need to create a branch at the destination_url, so that the # subprocess can actually create a lock. BzrDir.create_branch_convenience(puller_master.destination_url) deferred = puller_master.mirror().addErrback(self._dumpError) def checkID(ignored): self.assertEqual( puller_master.lock_ids, [get_lock_id_for_branch_id(puller_master.branch_id)]) return deferred.addCallback(checkID)
def __init__(self, source, revision=None): self.revision = revision and int(revision) self.project = None self.new = False self.zipfile = None self.config = None if isinstance(source, basestring): self.config = self._newconf(source) elif isinstance(source, ZipFile): self.zipfile = source try: conf = StringIO.StringIO(self.zipfile.read('sharetx.conf')) self.config = SafeConfigParser() self.config.readfp(conf) conf.close() except KeyError: self.config = self._newconf(str(uuid.uuid1())) self.new = True if not self.config: raise 'Configuration not found', source self.checkout_path = mkdtemp() self.branch_path = os.path.join(userdir(session['username']), self.config.get('sharetx', 'uri')) if self.new: if os.path.exists(self.branch_path): raise 'Project already exists', self.branch_path os.makedirs(self.branch_path) self.branch = BzrDir.create_branch_convenience(self.branch_path) else: self.branch = Branch.open(self.branch_path) if self.new: self.checkout() self.extract() conf = open(os.path.join(self.checkout_path, 'sharetx.conf'), 'wb') self.config.write(conf) conf.close() self.wt.add('sharetx.conf') elif self.zipfile: self.extract() else: self.checkout() self.project = CeltxRDFProject(self.checkout_path) # Re-read configuration and check version conf = os.path.join(self.checkout_path, 'sharetx.conf') self.config = SafeConfigParser() self.config.read(conf) version = self.config.get('sharetx', 'version') if version != '1': raise 'Not a valid version: %s' % version
def addTreeReference(self, tree): """Add a tree reference to a tree and commit. :param tree: A Bazaar WorkingTree to add a tree to. """ sub_branch = BzrDir.create_branch_convenience( tree.bzrdir.root_transport.clone('sub').base) tree.add_reference(sub_branch.bzrdir.open_workingtree()) tree.commit('added tree reference', committer='*****@*****.**')
def ensure_repo_consistency(self): """ Makes sure the self.repo_location directory is a Bazaar branch. The repo and Bazaar branch will be created if they don't already exist. Any unknown or modified files will be commited to the branch. Also, 'bzr whoami' will be set to the current user so that all commands can be traced back to an actual person (assuming everyone has their own logins). """ # Bazaar import bzrlib from bzrlib.branch import Branch from bzrlib.bzrdir import BzrDir from bzrlib.workingtree import WorkingTree try: BzrDir.open(self.repo_location) except bzrlib.errors.NotBranchError: BzrDir.create_branch_convenience(self.repo_location) c = Branch.open(self.repo_location).get_config_stack() c.set('email', '{}@{}'.format(get_current_user(), socket.getfqdn())) self.tree = WorkingTree.open(self.repo_location) delta = self.tree.changes_from(self.tree.basis_tree(), want_unversioned=True) logger.debug('tree `{}`'.format(self.tree)) logger.debug('delta `{}`'.format(delta)) for file_info in delta.unversioned: logger.debug('unversioned [{}]'.format(file_info)) file_name = file_info[0] self.tree.add(file_name) if delta.unversioned: self.tree.commit('Added new unversioned files') else: logger.debug('No unversioned files found') if delta.modified: self.tree.commit('Committed modified files') else: logger.debug('No modified files found')
def ensure_repo_consistency(self): """ Makes sure the self.repo_location directory is a Bazaar branch. The repo and Bazaar branch will be created if they don't already exist. Any unknown or modified files will be commited to the branch. Also, 'bzr whoami' will be set to the current user so that all commands can be traced back to an actual person (assuming everyone has their own logins). """ try: BzrDir.open(self.repo_location) except bzrlib.errors.NotBranchError: logger.info('Location [{}] is not a Bazaar branch. Will turn it into one.'.format(self.repo_location)) BzrDir.create_branch_convenience(self.repo_location) c = Branch.open(self.repo_location).get_config_stack() c.set('email', '{}@{}'.format(get_current_user(), socket.getfqdn())) self.tree = WorkingTree.open(self.repo_location) delta = self.tree.changes_from(self.tree.basis_tree(), want_unversioned=True) logger.debug('tree [{}]'.format(self.tree)) logger.debug('delta [{}]'.format(delta)) for file_info in delta.unversioned: logger.debug('unversioned [{}]'.format(file_info)) file_name = file_info[0] self.tree.add(file_name) if delta.unversioned: self.tree.commit('Added new unversioned files') else: logger.debug('No unversioned files found') if delta.modified: self.tree.commit('Committed modified files') else: logger.debug('No modified files found')
def test_use_subtree_format_for_tree_references(self): """Subtree references cause RepositoryFormat2aSubtree to be used.""" self.useBzrBranches(direct_database=True) format = format_registry.make_bzrdir('pack-0.92-subtree') branch, tree = self.create_branch_and_tree(format=format) sub_branch = BzrDir.create_branch_convenience( tree.bzrdir.root_transport.clone('sub').base, format=format) tree.add_reference(sub_branch.bzrdir.open_workingtree()) tree.commit('added tree reference', committer='*****@*****.**') upgrader = self.getUpgrader(tree.branch, branch) with read_locked(tree.branch): upgrader.create_upgraded_repository() upgraded = upgrader.get_bzrdir().open_repository() self.assertIs(RepositoryFormat2aSubtree, upgraded._format.__class__)
def __init__(self, tree_dir, source_branch=None): self.tree_dir = tree_dir os.makedirs(tree_dir) if source_branch: source_dir = source_branch._internal_bzr_branch.bzrdir bzrdir = source_dir.sprout(tree_dir) self._internal_tree, self._internal_bzr_branch = \ bzrdir.open_tree_or_branch(tree_dir) self.revision_count = source_branch.revision_count else: self._internal_bzr_branch = BzrDir.create_branch_convenience( tree_dir) self.revision_count = 0 self.bzr_identity = 'lp:%s' % os.path.basename(self.tree_dir) self.web_link = self.bzr_identity self.unique_name = self.bzr_identity self.project = MockLPProject()
def create(self): """ Create a branch with a working tree at the base directory. If the base directory is inside a Bazaar style "shared repository", it will use that to create a branch and working tree (make sure it allows working trees). """ self.log.info('Initializing new repository in %r...', self.basedir) try: bzrdir = BzrDir.open(self.basedir) except errors.NotBranchError: # really a NotBzrDir error... branch = BzrDir.create_branch_convenience(self.basedir, force_new_tree=True) wtree = branch.bzrdir.open_workingtree() else: bzrdir.create_branch() wtree = bzrdir.create_workingtree() return wtree
def test_mirror_imported_branch(self): # Run the puller on a populated imported branch pull queue. # Create the branch in the database. db_branch = self.factory.makeAnyBranch(branch_type=BranchType.IMPORTED) db_branch.requestMirror() transaction.commit() # Create the Bazaar branch in the expected location. branch_url = urljoin(config.launchpad.bzr_imports_root_url, '%08x' % db_branch.id) branch = BzrDir.create_branch_convenience(branch_url) tree = branch.bzrdir.open_workingtree() tree.commit('rev1') transaction.commit() # Run the puller. command, retcode, output, error = self.runPuller() self.assertRanSuccessfully(command, retcode, output, error) self.assertMirrored(db_branch, source_branch=branch)
def test_mirror_imported_branch(self): # Run the puller on a populated imported branch pull queue. # Create the branch in the database. db_branch = self.factory.makeAnyBranch( branch_type=BranchType.IMPORTED) db_branch.requestMirror() transaction.commit() # Create the Bazaar branch in the expected location. branch_url = urljoin( config.launchpad.bzr_imports_root_url, '%08x' % db_branch.id) branch = BzrDir.create_branch_convenience(branch_url) tree = branch.bzrdir.open_workingtree() tree.commit('rev1') transaction.commit() # Run the puller. command, retcode, output, error = self.runPuller() self.assertRanSuccessfully(command, retcode, output, error) self.assertMirrored(db_branch, source_branch=branch)
def test_simple_binding(self): self.build_tree(['base/', 'base/a', 'base/b', 'child/']) try: wt_base = BzrDir.create_standalone_workingtree( self.get_url('base')) except errors.NotLocalUrl: raise TestSkipped('Not a local URL') wt_base.add('a') wt_base.add('b') wt_base.commit('first', rev_id='r@b-1') b_base = wt_base.branch # manually make a branch we can bind, because the default format # may not be bindable-from, and we want to test the side effects etc # of bondage. format = bzrdir.format_registry.make_bzrdir('knit') b_child = BzrDir.create_branch_convenience('child', format=format) self.assertEqual(None, b_child.get_bound_location()) self.assertEqual(None, b_child.get_master_branch()) sftp_b_base = Branch.open(self.get_url('base')) b_child.bind(sftp_b_base) self.assertEqual(sftp_b_base.base, b_child.get_bound_location()) # the bind must not have given b_child history: self.assertEqual([], b_child.revision_history()) # we should be able to update the branch at this point: self.assertEqual(None, b_child.update()) # and now there must be history. self.assertEqual(['r@b-1'], b_child.revision_history()) # this line is more of a working tree test line, but - what the hey, # it has work to do. b_child.bzrdir.open_workingtree().update() self.failUnlessExists('child/a') self.failUnlessExists('child/b') b_child.unbind() self.assertEqual(None, b_child.get_bound_location())
def test_simple_binding(self): self.build_tree(['base/', 'base/a', 'base/b', 'child/']) try: wt_base = BzrDir.create_standalone_workingtree(self.get_url('base')) except errors.NotLocalUrl: raise TestSkipped('Not a local URL') wt_base.add('a') wt_base.add('b') wt_base.commit('first', rev_id='r@b-1') b_base = wt_base.branch # manually make a branch we can bind, because the default format # may not be bindable-from, and we want to test the side effects etc # of bondage. format = bzrdir.format_registry.make_bzrdir('knit') b_child = BzrDir.create_branch_convenience('child', format=format) self.assertEqual(None, b_child.get_bound_location()) self.assertEqual(None, b_child.get_master_branch()) sftp_b_base = Branch.open(self.get_url('base')) b_child.bind(sftp_b_base) self.assertEqual(sftp_b_base.base, b_child.get_bound_location()) # the bind must not have given b_child history: self.assertEqual([], b_child.revision_history()) # we should be able to update the branch at this point: self.assertEqual(None, b_child.update()) # and now there must be history. self.assertEqual(['r@b-1'], b_child.revision_history()) # this line is more of a working tree test line, but - what the hey, # it has work to do. b_child.bzrdir.open_workingtree().update() self.failUnlessExists('child/a') self.failUnlessExists('child/b') b_child.unbind() self.assertEqual(None, b_child.get_bound_location())
def _run_with_destination_locked(self, func, lock_id_delta=0): """Run the function `func` with the destination branch locked. :param func: The function that is to be run with the destination branch locked. It will be called no arguments and is expected to return a deferred. :param lock_id_delta: By default, the destination branch will be locked as if by another worker process for the same branch. If lock_id_delta != 0, the lock id will be different, so the worker should not break it. """ # Lots of moving parts :/ # We launch two subprocesses, one that locks the branch, tells us that # its done so and waits to be killed (we need to do the locking in a # subprocess to get the lock id to be right, see the above test). # When the first process tells us that it has locked the branch, we # run the provided function. When the deferred this returns is called # or erred back, we keep hold of the result and send a signal to kill # the first process and wait for it to die. class LockingPullerMonitorProtocol(scheduler.PullerMonitorProtocol): """Extend PullerMonitorProtocol with a 'branchLocked' method.""" def do_branchLocked(self): """Notify the listener that the branch is now locked.""" self.listener.branchLocked() def connectionMade(self): """Record the protocol instance on the listener. Normally the PullerMaster doesn't need to find the protocol again, but we need to to be able to kill the subprocess after the test has completed. """ self.listener.protocol = self class LockingPullerMaster(scheduler.PullerMaster): """Extend PullerMaster for the purposes of the test.""" protocol_class = LockingPullerMonitorProtocol # This is where the result of the deferred returned by 'func' will # be stored. We need to store seen_final_result and final_result # separately because we don't have any control over what # final_result may be (in the successful case at the time of # writing it is None). seen_final_result = False final_result = None def branchLocked(self): """Called when the subprocess has locked the branch. When this has happened, we can proceed with the main part of the test. """ branch_locked_deferred.callback(None) lock_and_wait_script = """ branch.lock_write() protocol.sendEvent('branchLocked') sys.stdout.flush() time.sleep(3600) """ # branch_locked_deferred will be called back when the subprocess locks # the branch. branch_locked_deferred = defer.Deferred() # So we add the function passed in as a callback to # branch_locked_deferred. def wrapper(ignore): return func() branch_locked_deferred.addCallback(wrapper) # When it is done, successfully or not, we store the result on the # puller master and kill the locking subprocess. def cleanup(result): locking_puller_master.seen_final_result = True locking_puller_master.final_result = result try: locking_puller_master.protocol.transport.signalProcess('INT') except error.ProcessExitedAlready: # We can only get here if the locking subprocess somehow # manages to crash between locking the branch and being killed # by us. In that case, locking_process_errback below will # cause the test to fail, so just do nothing here. pass branch_locked_deferred.addBoth(cleanup) locking_puller_master = self.makePullerMaster( LockingPullerMaster, lock_and_wait_script) locking_puller_master.branch_id += lock_id_delta # We need to create a branch at the destination_url, so that the # subprocess can actually create a lock. BzrDir.create_branch_convenience( locking_puller_master.destination_url) # Because when the deferred returned by 'func' is done we kill the # locking subprocess, we know that when the subprocess is done, the # test is done (note that this also applies if the locking script # fails to start up properly for some reason). locking_process_deferred = locking_puller_master.mirror() def locking_process_callback(ignored): # There's no way the process should have exited normally! self.fail("Subprocess exited normally!?") def locking_process_errback(failure): # Exiting abnormally is expected, but there are two sub-cases: if not locking_puller_master.seen_final_result: # If the locking subprocess exits abnormally before we send # the signal to kill it, that's bad. return failure else: # Afterwards, though that's the whole point :) # Return the result of the function passed in. return locking_puller_master.final_result return locking_process_deferred.addCallbacks( locking_process_callback, locking_process_errback)
def createRepository(self, path): BzrDir.create_branch_convenience(path)
def init_meta_branch(self, path): format = bzrdir.format_registry.make_bzrdir('default') return BzrDir.create_branch_convenience(path, format=format)
def makeBranch(self, path): transport = get_transport(path) transport.ensure_base() BzrDir.create_branch_convenience( transport.base, possible_transports=[transport])