Comment 13 for bug 82693

On Thu, 2009-04-16 at 23:36 +0000, James Westby wrote:

> Thanks,
> However, as far as I can see this doesn't cover all the things
> that I need to make this useful.
> Allow me to be more explicit about the requirements that I have.
> I have written the following hook:
> import os
> import shutil
> import subprocess
> import tempfile
> from bzrlib import (
> branch,
> errors,
> export,
> trace,
> )
> def run_test_suite_hook(params):
> config = params.branch.get_config()
> command = config._get_location_config()._get_user_option("pre_change_branch_tip_test_command")
> if command is None:
> return
> trace.note("Running the testsuite: %s" % command)
> revid = params.new_revid
> revtree = params.branch.repository.revision_tree(revid)

nb: branch.basis_tree() is more pithy

> tempdir = tempfile.mkdtemp()
> try:
> export_dir = os.path.join(tempdir, "export")
> export.export(revtree, export_dir, format="dir")
> retcode =, cwd=export_dir, shell=True)
> if retcode != 0:
> raise errors.TipChangeRejected("The testsuite failed")
> finally:
> shutil.rmtree(tempdir)
> branch.Branch.hooks.install_named_hook('pre_change_branch_tip',
> run_test_suite_hook, "Check the testsuite passes before the "
> "change is made.")

> which looks for a configuration option giving the command to run to
> validate the commit, for a poor-man's PQM for my local work.

Better than that; its useful for servers that have [relatively] cheap
precommit test actions to enforce.

> I'd like to use this for my bzr plugins, however the usual way
> I test those is "bzr selftest -s bp.<plugin name>". However,
> that requires the tree I am committing is the one that bzr will
> load, which isn't always going to be the case. In particular,
> the above code exports to a temporary directory to run the tests,
> so it won't be something loaded by bzr.
> So, I need a way to run the tests for a plugin, but also pass
> an arbitrary filesystem location to use the tests from, and have
> the plugin appear as the correct name to bzr.

I would keep the layers separate. Reinvoking bzr is more than a little
ugly - and it a circular definition which means it won't work anyway.

so when you export, export to a subdir of the temporary directory; then
set the env when you invoke the sub process.

> My code does this by setting BZR_PLUGIN_PATH based on __file__,
> so that it will always be testing the code that you are running
> it from, as well as a symlink to get it to appear as the correct
> name, regardless of the directory name.

This is what is broken - you aren't testing the commit, you're testing
the original tree which isn't the same thing.

> Running the particular tests of a plugins isn't hard thanks to
> "-s", but loading a plugin from an arbitrary location with a specific
> name still is (As Jelmer stated as well, BZR_PLUGIN_PATH isn't
> ideal because you often have many branches of the same code in
> adjacent directories).

We could add improvements in this area, yes.

> Perhaps this bug can be considered fixed by "-s" and we should
> open a second about loading a plugin in the desired way, as while
> most commenters here seem to want that for running tests it
> would also be useful in other situations.

The bug isn't fixed, because -s fails to get all the tests for a plugin.