yellow team mailing list archive
-
yellow team
-
Mailing list archive
-
Message #01029
[Merge] lp:~frankban/lpsetup/complete-tests into lp:lpsetup
Francesco Banconi has proposed merging lp:~frankban/lpsetup/complete-tests into lp:lpsetup.
Requested reviews:
Yellow Squad (yellow)
For more details, see:
https://code.launchpad.net/~frankban/lpsetup/complete-tests/+merge/115985
Sorry, the diff is huge, I had to change several things to support the "buildbot-http-no-checkout" story, but at least manual tests pass, and *lpsetup install-lxc* exits successfully when run like the following::
lp-setup install-lxc -B `bzr info | grep parent | cut -c 18-`
-u buildbot -E launchpad-pqm@xxxxxxxxxxxxx -f 'Launchpad PQM' -r
/var/lib/buildbot/slaves/slave --no-checkout -S launchpad_lxc_id_rsa
--use-http
== Changes ==
Changed UI for *finish_inithost* and *update* commands, as described in my email this morning: they now accept a *target_dir* defaulting to current directory.
handle_lpuser_from_lplogin: the handler no longer raises a ValidationError if --use-http is provided.
handle_target_from_repository: added an handler to calculate the *target_dir*. A target_dir must be passed to both update and finish-inithost commands.
handle_target_dir: just makes namespace.target_dir an absolute path.
Renamed *code_dir* and *working_dir* to *target_dir*.
s/ensure_ssh_keys/setup_ssh: it seemed to me more expressive. Also updated names in the relevant test case.
Added a *setup_home* step to init-host: from the docstring::
This is a separate step for several reasons::
- It is directly called by *initlxc* as one of its first steps.
Note that *initlxc* needs the user's `.ssh` dir to be set up
to be able to connect to the container.
- *initlxc* should be able to skip this step when re-executing
*inithost* from inside the container, to avoid setting up the
user home two times. Note: the user home is bind mounted by lxc.
Consequentially `changed initlxc.inithost_in_lxc` to skip the *setup_home* step.
inithost: moved the code calling *setup_ssh* and *bzr whoami/lp-login* from *initialize_base* to *initialize*, so that the ssh directory and bzr login are set up only once by initlxc.
initlxc: moved initialize() up at the beginning of the file so that it's easier to follow the code flow.
initrepo: setup_bzr_locations is now only called when the user Launchpad login can be retrieved. The check is done defining a call_setup_bzr_locations subcommand method.
install_lxc: steps updated to reflect the new UI. Added support for --no-checkout in *init_repo_in_lxc*. Updated *cmd_in_lxc* to ssh as the given user rather than ssh as root and then run sudo.
Moved lpuser and skip_if_no_lpuser definition from `tests.subcommands.test_initrepo` to `tests.utils` because they are now used by other tests too (see below).
Added a testcase for `handlers.handle_lpuser_from_lplogin`.
--
https://code.launchpad.net/~frankban/lpsetup/complete-tests/+merge/115985
Your team Yellow Squad is requested to review the proposed merge of lp:~frankban/lpsetup/complete-tests into lp:lpsetup.
=== modified file 'lpsetup/handlers.py'
--- lpsetup/handlers.py 2012-07-19 17:48:40 +0000
+++ lpsetup/handlers.py 2012-07-20 13:28:21 +0000
@@ -6,11 +6,14 @@
__metaclass__ = type
__all__ = [
- 'handle_code_dir',
+ 'handle_branch_and_checkout',
'handle_directories',
'handle_lpuser_as_username',
'handle_lpuser_from_lplogin',
+ 'handle_source',
'handle_ssh_keys',
+ 'handle_target_dir',
+ 'handle_target_from_repository',
'handle_testing',
'handle_user',
'handle_userdata',
@@ -85,12 +88,18 @@
def handle_lpuser_from_lplogin(namespace):
"""Handle lpuser argument.
+
+ The validation fails if *lpuser* is not provided, is not retrievable
+ and *use-http* is False.
"""
if getattr(namespace, 'lpuser', None) is None:
try:
namespace.lpuser = run('bzr', 'launchpad-login').strip()
except subprocess.CalledProcessError:
- raise ValidationError("No bzr launchpad-login set.")
+ if getattr(namespace, 'use_http', False):
+ namespace.lpuser = None
+ else:
+ raise ValidationError("No bzr launchpad-login set.")
def handle_userdata(namespace, whois=bzr_whois):
@@ -276,6 +285,19 @@
namespace.source = LP_SSH_REPO
+def handle_target_from_repository(namespace):
+ """Handle *repository*, *branch_name*, *checkout_name* and *no_checkout*.
+
+ These names must be present in the namespace.
+ Produces *target_dir*: the real working dir where the actual code lives.
+ """
+ if namespace.no_checkout:
+ target_name = namespace.branch_name
+ else:
+ target_name = namespace.checkout_name
+ namespace.target_dir = os.path.join(namespace.repository, target_name)
+
+
def normalize_path(path):
"""Return the absolute, expanded path.
@@ -286,6 +308,12 @@
return os.path.abspath(os.path.expanduser(path))
+def handle_target_dir(namespace):
+ """Handle path to the working directory."""
+ path = namespace.target_dir
+ namespace.target_dir = os.path.abspath(os.path.expanduser(path))
+
+
def handle_branch_and_checkout(namespace):
"""Handle branch and checkout names.
@@ -315,12 +343,3 @@
raise ValidationError(
'branch and checkout: can not use the same name ({0}).'.format(
checkout_name))
-
-
-def handle_code_dir(namespace):
- """Handle the computed value for `code_dir`.
-
- It must be invoked after handle_directories.
- """
- namespace.code_dir = os.path.join(
- namespace.repository, namespace.checkout_name)
=== modified file 'lpsetup/subcommands/finish_inithost.py'
--- lpsetup/subcommands/finish_inithost.py 2012-07-19 17:48:40 +0000
+++ lpsetup/subcommands/finish_inithost.py 2012-07-20 13:28:21 +0000
@@ -29,28 +29,22 @@
from lpsetup import argparser
from lpsetup.handlers import (
- handle_code_dir,
- handle_directories,
handle_user,
- )
-from lpsetup.settings import (
- LP_CHECKOUT_NAME,
- LP_REPOSITORY_DIR,
- )
-
+ handle_target_dir,
+ )
from lpsetup.utils import call
-def setup_launchpad(user, code_dir):
+def setup_launchpad(user, target_dir):
"""Set up the Launchpad environment."""
# Launchpad database setup.
# nested is required for use by python 2.6.
- with nested(su(user), cd(code_dir)):
+ with nested(su(user), cd(target_dir)):
call('utilities/launchpad-database-setup', user)
# Make and install launchpad.
- with cd(code_dir):
+ with cd(target_dir):
# Using real su because mailman make script uses uid.
call(*get_su_command(user, ['make', 'schema']))
call('make', 'install')
@@ -74,30 +68,19 @@
needs_root = True
steps = (
- (setup_launchpad, 'user', 'code_dir'),
+ (setup_launchpad, 'user', 'target_dir'),
)
- handlers = (
- handle_user,
- handle_directories,
- handle_code_dir,
- )
+ handlers = (handle_user, handle_target_dir)
def add_arguments(self, parser):
super(SubCommand, self).add_arguments(parser)
parser.add_argument(
+ 'target_dir', nargs='?', default=os.getcwd(),
+ help='The directory of the Launchpad code checkout. '
+ '[DEFAULT=current directory]')
+ parser.add_argument(
'-u', '--user',
help='The name of the system user. '
'The current user is used if this script is not run as '
'root and this argument is omitted.')
- parser.add_argument(
- '--checkout-name', default=LP_CHECKOUT_NAME,
- help='Create a checkout with the given name. '
- 'Ignored if --no-checkout is specified. '
- 'Defaults to {0}.'.format(LP_CHECKOUT_NAME))
- parser.add_argument(
- '-r', '--repository', default=LP_REPOSITORY_DIR,
- help='The directory of the Launchpad repository to be created. '
- 'The directory must reside under the home directory of the '
- 'given user (see -u argument). '
- '[DEFAULT={0}]'.format(LP_REPOSITORY_DIR))
=== modified file 'lpsetup/subcommands/inithost.py'
--- lpsetup/subcommands/inithost.py 2012-07-13 15:16:12 +0000
+++ lpsetup/subcommands/inithost.py 2012-07-20 13:28:21 +0000
@@ -99,9 +99,10 @@
os.chmod(filename, 0644)
-def ensure_ssh_keys(ssh_dir, private_key, public_key, valid_ssh_keys,
- ssh_key_path):
- """Ensure that SSH is configured correctly for the user."""
+def setup_ssh(ssh_dir, private_key, public_key, valid_ssh_keys, ssh_key_path):
+ """Set up the user's `.ssh` directory.
+
+ Also ensure that SSH is configured correctly for the user."""
# Set up the user's ssh directory. The ssh key must be associated
# with the lpuser's Launchpad account.
mkdirs(ssh_dir)
@@ -138,29 +139,12 @@
if not user_exists(user):
call('useradd', '-m', '-s', '/bin/bash', '-U', user)
- # Add user to the sudo group.
- subprocess.call(['adduser', user, 'sudo'])
- # Add the user to his own group.
- pwd_database = pwd.getpwnam(user)
- subprocess.call(['addgroup', '--gid', str(pwd_database.pw_gid), user])
-
-
-def initialize(
- user, full_name, email, lpuser, private_key, public_key, valid_ssh_keys,
- ssh_key_path):
+
+def initialize(user):
"""Initialize host machine."""
make_version_dir()
initialize_base(user)
- with su(user) as env:
- ssh_dir = os.path.join(env.home, '.ssh')
- ensure_ssh_keys(
- ssh_dir, private_key, public_key, valid_ssh_keys, ssh_key_path)
-
- # Set up bzr and Launchpad authentication.
- call('bzr', 'whoami', formataddr([full_name, email]))
- if valid_ssh_keys:
- subprocess.call(['bzr', 'lp-login', lpuser])
-
+ with su(user):
# Create Apache document roots, to avoid warnings.
mkdirs(*LP_APACHE_ROOTS)
@@ -168,6 +152,15 @@
for module in LP_APACHE_MODULES.split():
call('a2enmod', module)
+ # The user must be added to sudoers if inithost is run in a container
+ # and we are running the developer story.
+ # XXX 2012-07-18 frankban: add the developer/testing check.
+ if running_in_container():
+ subprocess.call(['adduser', user, 'sudo'])
+ # Add the user to his own group.
+ pwd_database = pwd.getpwnam(user)
+ subprocess.call(['addgroup', '--gid', str(pwd_database.pw_gid), user])
+
# Set up container hosts file.
lines = [get_file_header()]
lines.extend(['{0}\t{1}\n'.format(ip, names)
@@ -177,6 +170,32 @@
file_append(HOSTS_FILE, line)
+def setup_home(
+ user, full_name, email, lpuser, private_key, public_key, valid_ssh_keys,
+ ssh_key_path):
+ """Initialize the user home directory.
+
+ This is a separate step for several reasons::
+
+ - It is directly called by *initlxc* as one of its first steps.
+ Note that *initlxc* needs the user's `.ssh` dir to be set up
+ to be able to connect to the container.
+ - *initlxc* should be able to skip this step when re-executing
+ *inithost* from inside the container, to avoid setting up the
+ user home two times. Note: the user home is bind mounted by lxc.
+ """
+ with su(user) as env:
+ # Set up the `.ssh` directory.
+ setup_ssh(
+ os.path.join(env.home, '.ssh'), private_key, public_key,
+ valid_ssh_keys, ssh_key_path)
+
+ # Set up bzr and Launchpad authentication.
+ call('bzr', 'whoami', formataddr([full_name, email]))
+ if valid_ssh_keys:
+ subprocess.call(['bzr', 'lp-login', lpuser])
+
+
def initialize_lxc():
"""Initialize LXC container.
@@ -223,10 +242,11 @@
class SubCommand(argparser.StepsBasedSubCommand):
"""Prepare a machine to run Launchpad. May be an LXC container or not."""
- initialize_step = (initialize,
+ initialize_step = (initialize, 'user')
+
+ setup_home_step = (setup_home,
'user', 'full_name', 'email', 'lpuser',
- 'private_key', 'public_key', 'valid_ssh_keys', 'ssh_key_path',
- )
+ 'private_key', 'public_key', 'valid_ssh_keys', 'ssh_key_path')
initialize_lxc_step = (initialize_lxc, )
@@ -234,6 +254,7 @@
steps = (
initialize_step,
+ setup_home_step,
initialize_lxc_step,
setup_apt_step,
)
=== modified file 'lpsetup/subcommands/initlxc.py'
--- lpsetup/subcommands/initlxc.py 2012-07-17 20:17:48 +0000
+++ lpsetup/subcommands/initlxc.py 2012-07-20 13:28:21 +0000
@@ -57,6 +57,14 @@
)
+def initialize(user):
+ """Initialize the LXC host."""
+ inithost.initialize_base(user)
+ # haveged is used to fill /dev/random, avoiding
+ # entropy exhaustion during automated parallel tests.
+ apt_get_install('haveged', caller=call)
+
+
def create_lxc(lxc_name, lxc_arch, lxc_os, user, install_subunit=False):
"""Create the LXC named `lxc_name` sharing `user` home directory.
@@ -125,14 +133,6 @@
retry_ssh(lxc_name, 'true', key=ssh_key_path)
-def initialize(user):
- """Initialize the LXC host."""
- inithost.initialize_base(user)
- # haveged is used to fill /dev/random, avoiding
- # entropy exhaustion during automated parallel tests.
- apt_get_install('haveged', caller=call)
-
-
def install_lpsetup_in_lxc(lxc_name, ssh_key_path, lxc_os,
user, home_dir, lpsetup_branch=None):
"""Initialize LXC container."""
@@ -194,9 +194,7 @@
"""Prepare the Launchpad environment inside an LXC."""
# Use ssh to call this script from inside the container.
args = ['init-host', '-u', user, '-E', email, '-f', full_name,
- '-l', lpuser, '-S', ssh_key_name,
- ]
-
+ '-l', lpuser, '-S', ssh_key_name, '--skip-steps', 'setup_home']
cmd = this_command(home_dir, args)
ssh(lxc_name, cmd, key=ssh_key_path)
@@ -230,6 +228,7 @@
steps = (
(initialize, 'user'),
+ inithost.SubCommand.setup_home_step,
create_lxc_step,
start_lxc_step,
wait_for_lxc_step,
=== modified file 'lpsetup/subcommands/initrepo.py'
--- lpsetup/subcommands/initrepo.py 2012-07-19 14:31:26 +0000
+++ lpsetup/subcommands/initrepo.py 2012-07-20 13:28:21 +0000
@@ -86,7 +86,11 @@
def setup_bzr_locations(
lpuser, repository, branch_name, template=LP_BZR_LOCATIONS):
- """Set up bazaar locations."""
+ """Set up bazaar locations.
+
+ Note that this step is guarded by the *call_setup_bzr_locations* method
+ so that it is only called when the user Launchpad login can be retrieved.
+ """
context = {
'branch_dir': os.path.join(repository, branch_name),
'repository': repository,
@@ -128,6 +132,11 @@
handlers.handle_source,
)
+ def call_setup_bzr_locations(self, namespace, step, args):
+ """Caller that only sets up bzr locations if lpuser exists."""
+ if namespace.lpuser is not None:
+ return step(*args)
+
@staticmethod
def add_common_arguments(parser):
parser.add_argument(
=== modified file 'lpsetup/subcommands/install_lxc.py'
--- lpsetup/subcommands/install_lxc.py 2012-07-19 17:48:40 +0000
+++ lpsetup/subcommands/install_lxc.py 2012-07-20 13:28:21 +0000
@@ -13,9 +13,10 @@
import os
from lpsetup.handlers import (
- handle_code_dir,
+ handle_branch_and_checkout,
handle_directories,
handle_source,
+ handle_target_from_repository,
)
from lpsetup.settings import (
LXC_IP_COMMAND,
@@ -70,13 +71,13 @@
def cmd_in_lxc(lxc_name, ssh_key_path, home_dir, args, as_user=None):
cmd = this_command(home_dir, args)
- if as_user is not None:
- cmd = "su {} -c '{}'".format(as_user, cmd)
- ssh(lxc_name, cmd, key=ssh_key_path)
-
-
-def init_repo_in_lxc(lxc_name, ssh_key_path, home_dir, user, source,
- use_http, branch_name, checkout_name, repository):
+ print "CMD =", cmd
+ ssh(lxc_name, cmd, key=ssh_key_path, user=as_user)
+
+
+def init_repo_in_lxc(
+ lxc_name, ssh_key_path, home_dir, user, source, use_http,
+ branch_name, checkout_name, repository, no_checkout):
args = [
'init-repo', '--source', source,
'--branch-name', branch_name, '--checkout-name', checkout_name,
@@ -84,26 +85,23 @@
]
if use_http:
args.append('--use-http')
+ if no_checkout:
+ args.append('--no-checkout')
cmd_in_lxc(lxc_name, ssh_key_path, home_dir, args, as_user=user)
-def update_in_lxc(lxc_name, ssh_key_path, home_dir, user, external_path,
- use_http, checkout_name, repository):
- args = [
- 'update', '--external-path', external_path,
- '-r', repository, '--checkout-name', checkout_name,
- ]
+def update_in_lxc(
+ lxc_name, ssh_key_path, home_dir, user, external_path,
+ target_dir, use_http):
+ args = ['update', target_dir, '--external-path', external_path]
if use_http:
args.append('--use-http')
cmd_in_lxc(lxc_name, ssh_key_path, home_dir, args, as_user=user)
-def finish_inithost_in_lxc(lxc_name, ssh_key_path, home_dir, user,
- repository, checkout_name):
- args = [
- 'finish-init-host', '--user', user, '--repository', repository,
- '--checkout-name', checkout_name,
- ]
+def finish_inithost_in_lxc(
+ lxc_name, ssh_key_path, home_dir, user, target_dir):
+ args = ['finish-init-host', target_dir, '--user', user]
cmd_in_lxc(lxc_name, ssh_key_path, home_dir, args)
@@ -116,12 +114,13 @@
# Run on host:
(create_scripts, 'lxc_name', 'ssh_key_path', 'user'),
# Run inside the container:
- (init_repo_in_lxc, 'lxc_name', 'ssh_key_path', 'home_dir', 'user',
- 'source', 'use_http', 'branch_name', 'checkout_name', 'repository'),
+ (init_repo_in_lxc,
+ 'lxc_name', 'ssh_key_path', 'home_dir', 'user', 'source', 'use_http',
+ 'branch_name', 'checkout_name', 'repository', 'no_checkout'),
(update_in_lxc, 'lxc_name', 'ssh_key_path', 'home_dir', 'user',
- 'external_path', 'use_http', 'checkout_name', 'repository'),
+ 'external_path', 'target_dir', 'use_http'),
(finish_inithost_in_lxc, 'lxc_name', 'ssh_key_path', 'home_dir',
- 'user', 'repository', 'checkout_name'),
+ 'user', 'target_dir'),
)
help = __doc__
@@ -130,8 +129,9 @@
handlers = super(SubCommand, self).get_handlers(namespace)
return handlers + (
handle_directories,
- handle_code_dir,
+ handle_branch_and_checkout,
handle_source,
+ handle_target_from_repository,
)
def call_create_scripts(self, namespace, step, args):
=== modified file 'lpsetup/subcommands/update.py'
--- lpsetup/subcommands/update.py 2012-07-19 17:48:40 +0000
+++ lpsetup/subcommands/update.py 2012-07-20 13:28:21 +0000
@@ -18,50 +18,46 @@
from lpsetup import argparser
from lpsetup import handlers
-from lpsetup.settings import (
- LP_CHECKOUT_NAME,
- LP_REPOSITORY_DIR,
- LP_SOURCE_DEPS,
- )
-
-
-def initialize_directories(code_dir, external_path):
+from lpsetup.settings import LP_SOURCE_DEPS
+
+
+def initialize_directories(target_dir, external_path):
"""Initialize the eggs, yui, and sourcecode directories.
Create them if necessary.
"""
for dir_ in ['eggs', 'yui', 'sourcecode']:
- mkdirs(os.path.join(code_dir, external_path, dir_))
-
-
-def update_dependencies(code_dir, external_path, use_http):
+ mkdirs(os.path.join(target_dir, external_path, dir_))
+
+
+def update_dependencies(target_dir, external_path, use_http):
"""Update the external dependencies."""
use_http_param = '--use-http' if use_http else None
- cmd = os.path.join(code_dir, 'utilities', 'update-sourcecode')
+ cmd = os.path.join(target_dir, 'utilities', 'update-sourcecode')
abs_external_path = os.path.abspath(
- os.path.join(code_dir, external_path))
+ os.path.join(target_dir, external_path))
source_path = os.path.join(abs_external_path, 'sourcecode')
run(cmd, use_http_param, source_path)
# Update the download cache.
- download_cache = os.path.join(code_dir, 'download-cache')
+ download_cache = os.path.join(target_dir, 'download-cache')
if os.path.exists(download_cache):
run('bzr', 'up', download_cache)
else:
run('bzr', 'co', '-v', '--lightweight', LP_SOURCE_DEPS, download_cache)
# Link to the external sourcecode.
- if abs_external_path != code_dir:
+ if abs_external_path != target_dir:
cmd = os.path.join(
- code_dir, 'utilities', 'link-external-sourcecode')
+ target_dir, 'utilities', 'link-external-sourcecode')
run(cmd,
- '--target', code_dir,
+ '--target', target_dir,
'--parent', external_path)
-def update_tree(code_dir):
- """Update the tree at code_dir with the latest LP code."""
- with cd(code_dir):
+def update_tree(target_dir):
+ """Update the tree at target_dir with the latest LP code."""
+ with cd(target_dir):
run('bzr', 'pull')
@@ -72,16 +68,15 @@
"""
steps = (
- (initialize_directories, 'code_dir', 'external_path'),
- (update_dependencies, 'code_dir', 'external_path', 'use_http'),
- (update_tree, 'code_dir'),
+ (initialize_directories, 'target_dir', 'external_path'),
+ (update_dependencies, 'target_dir', 'external_path', 'use_http'),
+ (update_tree, 'target_dir'),
)
help = __doc__
handlers = (
# Normalize paths and default to cwd if none exists.
handlers.handle_user,
- handlers.handle_directories,
- handlers.handle_code_dir,
+ handlers.handle_target_dir,
)
@staticmethod
@@ -94,19 +89,11 @@
def add_arguments(self, parser):
super(SubCommand, self).add_arguments(parser)
+ parser.add_argument(
+ 'target_dir', nargs='?', default=os.getcwd(),
+ help='Path to branch to update. [DEFAULT=current directory]')
self.add_common_arguments(parser)
parser.add_argument(
'--use-http', default=False, action='store_true',
help='Force bzr to use http to get the sourcecode '
'branches rather than using bzr+ssh.')
- parser.add_argument(
- '--checkout-name', default=LP_CHECKOUT_NAME,
- help='Create a checkout with the given name. '
- 'Ignored if --no-checkout is specified. '
- 'Defaults to {0}.'.format(LP_CHECKOUT_NAME))
- parser.add_argument(
- '-r', '--repository', default=LP_REPOSITORY_DIR,
- help='The directory of the Launchpad repository to be created. '
- 'The directory must reside under the home directory of the '
- 'given user (see -u argument). '
- '[DEFAULT={0}]'.format(LP_REPOSITORY_DIR))
=== modified file 'lpsetup/tests/subcommands/test_finish_inithost.py'
--- lpsetup/tests/subcommands/test_finish_inithost.py 2012-07-19 17:48:40 +0000
+++ lpsetup/tests/subcommands/test_finish_inithost.py 2012-07-20 13:28:21 +0000
@@ -15,25 +15,20 @@
setup_launchpad_step = (
- finish_inithost.setup_launchpad, ['user', 'code_dir'])
+ finish_inithost.setup_launchpad, ['user', 'target_dir'])
def get_arguments():
- repo = '~/' + get_random_string()
- checkout = get_random_string()
+ target_dir = '~/' + get_random_string()
user = get_random_string()
- return ('-r', repo, '--checkout-name', checkout, '-u', user)
+ return (target_dir, '-u', user)
class FinishInitHostTest(StepsBasedSubCommandTestMixin, unittest.TestCase):
sub_command_class = finish_inithost.SubCommand
expected_arguments = get_arguments()
- expected_handlers = (
- handlers.handle_user,
- handlers.handle_directories,
- handlers.handle_code_dir,
- )
+ expected_handlers = (handlers.handle_user, handlers.handle_target_dir)
@property
def expected_steps(self):
=== modified file 'lpsetup/tests/subcommands/test_inithost.py'
--- lpsetup/tests/subcommands/test_inithost.py 2012-07-13 15:16:12 +0000
+++ lpsetup/tests/subcommands/test_inithost.py 2012-07-20 13:28:21 +0000
@@ -18,12 +18,12 @@
)
-initialize_step = (
- inithost.initialize, ['user', 'full_name', 'email', 'lpuser',
+initialize_step = (inithost.initialize, ['user'])
+setup_home_step = (
+ inithost.setup_home, ['user', 'full_name', 'email', 'lpuser',
'private_key', 'public_key', 'valid_ssh_keys', 'ssh_key_path',
])
-initialize_lxc_step = (
- inithost.initialize_lxc, [])
+initialize_lxc_step = (inithost.initialize_lxc, [])
setup_apt_step = (inithost.setup_apt, [])
@@ -52,6 +52,7 @@
)
expected_steps = (
initialize_step,
+ setup_home_step,
initialize_lxc_step,
setup_apt_step,)
needs_root = True
@@ -111,8 +112,8 @@
'/tmp/foo', 'Hello, world!', 'a+')
-class EnsureSSHKeysTestCase(unittest.TestCase):
- """Tests for inithost.ensure_ssh_keys()."""
+class SetupSSHTestCase(unittest.TestCase):
+ """Tests for inithost.setup_ssh()."""
def setUp(self):
temp_file = tempfile.NamedTemporaryFile()
@@ -123,42 +124,42 @@
self.addCleanup(os.remove, self.temp_filename)
self.addCleanup(os.remove, self.temp_filename + ".pub")
- def test_ensure_ssh_keys_writes_to_ssh_key_path(self):
- # If inithost.ensure_ssh_keys() is told that the keys it has
+ def test_setup_ssh_writes_to_ssh_key_path(self):
+ # If inithost.setup_ssh() is told that the keys it has
# been passed are valid, it will write them out to the provided
# ssh_key_path.
public_key = "Public"
private_key = "Private"
- inithost.ensure_ssh_keys(
+ inithost.setup_ssh(
self.ssh_dir, private_key, public_key, True, self.temp_filename)
with open(self.temp_filename + '.pub', 'r') as pub_file:
self.assertIn(public_key, pub_file.read())
with open(self.temp_filename, 'r') as priv_file:
self.assertIn(private_key, priv_file.read())
- def test_ensure_ssh_keys_generates_keys_if_not_passed(self):
- # If SSH keys aren't passed to ensure_ssh_keys(), the function
+ def test_setup_ssh_generates_keys_if_not_passed(self):
+ # If SSH keys aren't passed to setup_ssh(), the function
# will generate some.
- inithost.ensure_ssh_keys(
+ inithost.setup_ssh(
self.ssh_dir, None, None, False, self.temp_filename)
self.assertTrue(os.path.exists(self.temp_filename))
self.assertTrue(os.path.exists(self.temp_filename + ".pub"))
- def test_ensure_ssh_keys_generates_other_files(self):
- # ensure_ssh_keys() also generates an authorized_keys file and a
+ def test_setup_ssh_generates_other_files(self):
+ # setup_ssh() also generates an authorized_keys file and a
# known_hosts file in the ssh dir.
- inithost.ensure_ssh_keys(
+ inithost.setup_ssh(
self.ssh_dir, None, None, False, self.temp_filename)
self.assertTrue(
os.path.exists(os.path.join(self.ssh_dir, 'authorized_keys')))
self.assertTrue(
os.path.exists(os.path.join(self.ssh_dir, 'known_hosts')))
- def test_ensure_ssh_keys_creates_ssh_dir(self):
- # If the ssh_dir passed to ensure_ssh_keys() doesn't exist, it
+ def test_setup_ssh_creates_ssh_dir(self):
+ # If the ssh_dir passed to setup_ssh() doesn't exist, it
# will be created.
shutil.rmtree(self.ssh_dir)
- inithost.ensure_ssh_keys(
+ inithost.setup_ssh(
self.ssh_dir, None, None, False, self.temp_filename)
self.assertTrue(os.path.exists(self.ssh_dir))
self.assertTrue(os.path.isdir(self.ssh_dir))
=== modified file 'lpsetup/tests/subcommands/test_initlxc.py'
--- lpsetup/tests/subcommands/test_initlxc.py 2012-07-16 21:12:21 +0000
+++ lpsetup/tests/subcommands/test_initlxc.py 2012-07-20 13:28:21 +0000
@@ -55,6 +55,7 @@
)
expected_steps = (
initialize_step,
+ test_inithost.setup_home_step,
create_lxc_step,
start_lxc_step,
wait_for_lxc_step,
=== modified file 'lpsetup/tests/subcommands/test_initrepo.py'
--- lpsetup/tests/subcommands/test_initrepo.py 2012-07-17 10:46:49 +0000
+++ lpsetup/tests/subcommands/test_initrepo.py 2012-07-20 13:28:21 +0000
@@ -6,7 +6,6 @@
import os
import shutil
-import subprocess
import tempfile
import unittest
@@ -23,21 +22,13 @@
from lpsetup.tests.utils import (
create_test_branch,
get_random_string,
+ lpuser,
+ skip_if_no_lpuser,
StepsBasedSubCommandTestMixin,
)
from lpsetup.utils import ConfigParser
-try:
- lpuser = run('bzr', 'launchpad-login').strip()
-except subprocess.CalledProcessError:
- lpuser = None
-# Create a decorator to skip tests if lp login is not set.
-skip_if_no_lpuser = unittest.skipIf(
- lpuser is None,
- 'You need to set up a Launchpad login is needed to run this test.')
-
-
fetch_step = (initrepo.fetch,
['source', 'repository', 'branch_name', 'checkout_name', 'no_checkout'])
setup_bzr_locations_step = (initrepo.setup_bzr_locations,
=== modified file 'lpsetup/tests/subcommands/test_install_lxc.py'
--- lpsetup/tests/subcommands/test_install_lxc.py 2012-07-19 17:48:40 +0000
+++ lpsetup/tests/subcommands/test_install_lxc.py 2012-07-20 13:28:21 +0000
@@ -23,19 +23,18 @@
init_repo_in_lxc_step = (
install_lxc.init_repo_in_lxc, [
'lxc_name', 'ssh_key_path', 'home_dir', 'user', 'source', 'use_http',
- 'branch_name', 'checkout_name', 'repository',
+ 'branch_name', 'checkout_name', 'repository', 'no_checkout',
])
update_in_lxc_step = (
install_lxc.update_in_lxc, [
'lxc_name', 'ssh_key_path', 'home_dir', 'user', 'external_path',
- 'use_http', 'checkout_name', 'repository',
+ 'target_dir', 'use_http',
])
finish_inithost_in_lxc_step = (
install_lxc.finish_inithost_in_lxc, [
- 'lxc_name', 'ssh_key_path', 'home_dir', 'user', 'repository',
- 'checkout_name',
+ 'lxc_name', 'ssh_key_path', 'home_dir', 'user', 'target_dir',
])
@@ -53,8 +52,9 @@
expected_arguments = get_arguments()
expected_handlers = test_initlxc.InitLxcTest.expected_handlers + (
handlers.handle_directories,
- handlers.handle_code_dir,
+ handlers.handle_branch_and_checkout,
handlers.handle_source,
+ handlers.handle_target_from_repository,
)
expected_steps = test_initlxc.InitLxcTest.expected_steps + (
create_scripts_step,
=== modified file 'lpsetup/tests/subcommands/test_update.py'
--- lpsetup/tests/subcommands/test_update.py 2012-07-19 17:48:40 +0000
+++ lpsetup/tests/subcommands/test_update.py 2012-07-20 13:28:21 +0000
@@ -15,18 +15,19 @@
def get_arguments():
+ target_dir = '~/' + get_random_string()
+ external_path = get_random_string()
return (
- '--external-path', get_random_string(),
+ target_dir,
+ '--external-path', external_path,
'--use-http',
- '--repository', get_random_string(),
- '--checkout-name', get_random_string(),
)
init_dir_step = (
- update.initialize_directories, ['code_dir', 'external_path'])
+ update.initialize_directories, ['target_dir', 'external_path'])
update_dep_step = (
- update.update_dependencies, ['code_dir', 'external_path', 'use_http'])
-update_tree_step = (update.update_tree, ['code_dir'])
+ update.update_dependencies, ['target_dir', 'external_path', 'use_http'])
+update_tree_step = (update.update_tree, ['target_dir'])
class UpdateTest(StepsBasedSubCommandTestMixin, unittest.TestCase):
@@ -34,11 +35,7 @@
sub_command_name = 'update'
sub_command_class = update.SubCommand
expected_arguments = get_arguments()
- expected_handlers = (
- handlers.handle_user,
- handlers.handle_directories,
- handlers.handle_code_dir,
- )
+ expected_handlers = (handlers.handle_user, handlers.handle_target_dir)
expected_steps = (
init_dir_step,
update_dep_step,
=== modified file 'lpsetup/tests/test_handlers.py'
--- lpsetup/tests/test_handlers.py 2012-07-17 10:28:05 +0000
+++ lpsetup/tests/test_handlers.py 2012-07-20 13:28:21 +0000
@@ -9,20 +9,31 @@
import getpass
import os
import pwd
+import shutil
+import tempfile
import unittest
-from shelltoolbox import cd
+from shelltoolbox import (
+ cd,
+ environ,
+ )
from lpsetup.exceptions import ValidationError
from lpsetup.handlers import (
handle_branch_and_checkout,
handle_directories,
handle_lpuser_as_username,
+ handle_lpuser_from_lplogin,
handle_ssh_keys,
+ handle_target_from_repository,
handle_testing,
handle_user,
handle_userdata,
)
+from lpsetup.tests.utils import (
+ lpuser,
+ skip_if_no_lpuser,
+ )
class HandlersTestMixin(object):
@@ -167,7 +178,7 @@
handle_directories(namespace)
-class HandleLPUserTest(unittest.TestCase):
+class HandleLPUserAsUsernameTest(unittest.TestCase):
def test_lpuser(self):
# If lpuser is not provided by namespace, the user name is used.
@@ -177,6 +188,44 @@
self.assertEqual(username, namespace.lpuser)
+class HandleLPUserFromLPLoginTest(HandlersTestMixin, unittest.TestCase):
+
+ def temp_home(self):
+ home = tempfile.mkdtemp()
+ self.addCleanup(shutil.rmtree, home)
+ return environ(HOME=home)
+
+ def test_lpuser_in_namespace(self):
+ # Ensure nothing happen if the lpuser exists in the namespace.
+ value = 'myuser'
+ namespace = argparse.Namespace(lpuser=value)
+ handle_lpuser_from_lplogin(namespace)
+ self.assertEqual(value, namespace.lpuser)
+
+ @skip_if_no_lpuser
+ def test_lpuser_retrieval(self):
+ # Ensure lpuser is correctly retrieved using bzr if it does not
+ # exist in the namespace.
+ namespace = argparse.Namespace()
+ handle_lpuser_from_lplogin(namespace)
+ self.assertEqual(lpuser, namespace.lpuser)
+
+ def test_no_lpuser(self):
+ # The validation fails if lpuser is not retrievable.
+ with self.temp_home():
+ namespace = argparse.Namespace()
+ with self.assertNotValid('launchpad-login'):
+ handle_lpuser_from_lplogin(namespace)
+
+ def test_use_http(self):
+ # Ensure lpuser is set to None if not retrievable and
+ # *use_http* is True.
+ with self.temp_home():
+ namespace = argparse.Namespace(use_http=True)
+ handle_lpuser_from_lplogin(namespace)
+ self.assertIsNone(namespace.lpuser)
+
+
class HandleSSHKeysTest(HandlersTestMixin, unittest.TestCase):
home_dir = '/tmp/__does_not_exist__'
@@ -228,6 +277,36 @@
handle_ssh_keys(namespace)
+class HandleTargetFromRepositoryTest(unittest.TestCase):
+
+ branch_name = 'branch'
+ checkout_name = 'checkout'
+ repository = '/repository/'
+
+ def get_target_dir(self, no_checkout):
+ namespace = argparse.Namespace(
+ branch_name=self.branch_name,
+ checkout_name=self.checkout_name,
+ repository=self.repository,
+ no_checkout=no_checkout)
+ handle_target_from_repository(namespace)
+ return namespace.target_dir
+
+ def test_checkout(self):
+ # Ensure the target dir points to branch_name if
+ # lightweight checkout is not used.
+ expected = os.path.join(self.repository, self.checkout_name)
+ target_dir = self.get_target_dir(False)
+ self.assertEqual(expected, target_dir)
+
+ def test_no_checkout(self):
+ # Ensure the target dir points to checkout_name if
+ # lightweight checkout is used.
+ expected = os.path.join(self.repository, self.branch_name)
+ target_dir = self.get_target_dir(True)
+ self.assertEqual(expected, target_dir)
+
+
class HandleTestingTest(unittest.TestCase):
ctx = {
=== modified file 'lpsetup/tests/utils.py'
--- lpsetup/tests/utils.py 2012-07-17 10:26:46 +0000
+++ lpsetup/tests/utils.py 2012-07-20 13:28:21 +0000
@@ -21,6 +21,7 @@
import string
from StringIO import StringIO
import sys
+import subprocess
import tempfile
import unittest
@@ -113,6 +114,16 @@
return ''.join(random.sample(string.ascii_letters, size))
+# Retrieve the current lpuser to be used in tests.
+try:
+ lpuser = run('bzr', 'launchpad-login').strip()
+except subprocess.CalledProcessError:
+ lpuser = None
+# Create a decorator to skip tests if lp login is not set.
+skip_if_no_lpuser = unittest.skipIf(
+ lpuser is None, 'You need to set up a Launchpad login to run this test.')
+
+
class SubCommandTestMixin(object):
sub_command_class = examples.SubCommand