Comment 12 for bug 82693

On Thu, 2009-04-16 at 22:28 +0000, Robert Collins wrote:
> On Thu, 2009-04-16 at 20:30 +0000, James Westby wrote:
> > Hi,
> >
> > Having a better solution for this would be great, but with the help of
> > jam and vila I just knocked this up:
> >
> > if __name__ == '__main__':
>
> ug.
>
> from bzrlib import option, commands
> commands.Command.hooks.install_named_hook('extend_command',
> test_coverage, 'test_plugin')
>
>
> def test_plugin(cmd):
> if cmd.name() != 'selftest':
> return
> def handle_test_plugin(option, name, value, parser):
> cmd.additional_selftest_args['starting_with'] = \
> 'bzrlib.plugins.%s' % value
> cmd.takes_options = list(cmd.takes_options)
> cmd.takes_options.append(
> option.Option('test-plugin',
> help='Run tests for a single named plugin',
> custom_callback=handle_test_plugin))

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)
    tempdir = tempfile.mkdtemp()
    try:
        export_dir = os.path.join(tempdir, "export")
        export.export(revtree, export_dir, format="dir")
        retcode = subprocess.call(command, 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.

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.

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.

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).

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.

Thanks,

James