← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~benji/lpsetup/bug-1020734-first-integration-test into lp:lpsetup

 

Benji York has proposed merging lp:~benji/lpsetup/bug-1020734-first-integration-test into lp:lpsetup.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~benji/lpsetup/bug-1020734-first-integration-test/+merge/114044

This is a first cut at an integration test for lpsetup that uses juju to provision a clean EC2 instance and then uses that instance to run a test.

This first cut only tests init-host because I couldn't get init-repo to work yet.  That is either a bug in init-repo or a deficiency in the test setup, either way I wanted to get this test landed and we can address testing init-repo separately.

See the README for instructions on running the test.
-- 
https://code.launchpad.net/~benji/lpsetup/bug-1020734-first-integration-test/+merge/114044
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~benji/lpsetup/bug-1020734-first-integration-test into lp:lpsetup.
=== modified file 'lpsetup/handlers.py'
--- lpsetup/handlers.py	2012-07-06 19:18:58 +0000
+++ lpsetup/handlers.py	2012-07-09 20:57:30 +0000
@@ -255,7 +255,7 @@
 def handle_source(namespace):
     """Handle the --source and --use-http options."""
     # If a source has been provided, then there is nothing else to do.
-    if namespace.source:
+    if namespace.source is not None:
         return
     if namespace.use_http:
         namespace.source = LP_HTTP_REPO

=== modified file 'lpsetup/subcommands/inithost.py'
--- lpsetup/subcommands/inithost.py	2012-07-09 11:36:53 +0000
+++ lpsetup/subcommands/inithost.py	2012-07-09 20:57:30 +0000
@@ -201,9 +201,10 @@
 
         # Create Apache document roots, to avoid warnings.
         mkdirs(*LP_APACHE_ROOTS)
-        # Set up Apache modules.
-        for module in LP_APACHE_MODULES.split():
-            call('a2enmod', module)
+
+    # Set up Apache modules.
+    for module in LP_APACHE_MODULES.split():
+        call('a2enmod', module)
 
     # Set up container hosts file.
     lines = [get_file_header()]

=== modified file 'lpsetup/subcommands/initrepo.py'
--- lpsetup/subcommands/initrepo.py	2012-07-05 18:38:51 +0000
+++ lpsetup/subcommands/initrepo.py	2012-07-09 20:57:30 +0000
@@ -85,7 +85,7 @@
     def add_arguments(self, parser):
         super(SubCommand, self).add_arguments(parser)
         parser.add_argument(
-            '--source', default=LP_SSH_REPO,
+            '--source', default=None,
             help='Location from which to retrieve Launchpad source.  Default '
                 'is lp:launchpad (if --use-http is false), otherwise '
                 'http://bazaar.launchpad.net/~launchpad-pqm/launchpad/devel.')

=== added directory 'lpsetup/tests/integration'
=== added file 'lpsetup/tests/integration/non-lxc.py'
--- lpsetup/tests/integration/non-lxc.py	1970-01-01 00:00:00 +0000
+++ lpsetup/tests/integration/non-lxc.py	2012-07-09 20:57:30 +0000
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+# Copyright 2012 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""A simple, end-to-end integration test."""
+
+import os
+import sys
+import time
+
+from subprocess import (
+    check_call,
+    Popen,
+    PIPE,
+    STDOUT,
+    )
+
+def banner(s):
+    width = 70
+    print '*' * width
+    print '* ' + s.ljust(width - 4) + ' *'
+    print '*' * width
+
+def on_remote(args):
+    if type(args) == str:
+        args = args.split()
+
+    check_call('juju ssh 1 -e lpsetup-testing'.split() + list(args))
+
+
+def check_environment():
+    """Be sure the test environment doesn't exist."""
+    banner('Checking test environment.')
+    # We want to be really sure we do not clobber an already-existing juju
+    # environment.  Therefore we make sure one doesn't exist before
+    # bootstrapping.
+    code = os.system('juju status -e lpsetup-testing')
+    if code == 0:
+        # The "juju status" should have failed.
+        raise RuntimeError('A juju environment unexpectedly exists.')
+
+
+def set_up():
+    """Set up a juju-managed instance to run the tests on."""
+    banner('Setting up the test environment.')
+    check_call('juju bootstrap -e lpsetup-testing'.split())
+    # XXX The "ubuntu" charm is broken, so it has to be loaded from the local
+    # repository.  Get it from lp:~charmers/charms/precise/ubuntu/trunk.
+    check_call('juju deploy local:ubuntu --repository ~/juju-charms'
+        ' -e lpsetup-testing --constraints instance-type=m1.large'.split())
+
+    start_time = time.time()
+    while time.time() - start_time < 600:
+        process = Popen('juju status -e lpsetup-testing'.split(), stdout=PIPE)
+        stdout, stderr = process.communicate()
+        if 'instance-state: running' in stdout:
+            break
+    else:
+        raise RuntimeError('starting the instance took too long')
+
+    # Even though the instance-state is "running", it's still not ready, so
+    # wait a little while before continuing.
+    time.sleep(30)
+
+    on_remote('sudo apt-add-repository --yes ppa:yellow/ppa')
+    on_remote('sudo apt-get update')
+    on_remote('sudo apt-get install python-shelltoolbox')
+    on_remote('sudo apt-get install apache2')
+    on_remote('sudo apt-get install apache2.2-common')
+    on_remote(('bzr', 'whoami', '"Not A Real Person <no@xxxxxxxxxxx>"'))
+    on_remote('bzr branch lp:lpsetup')
+
+
+def do_test():
+    """Run an end-to-end integration tests of the non-LXC lpsetup story."""
+    banner('Running (non-LXC) integration test.')
+    on_remote('cd lpsetup; ./lp-setup init-host'.split())
+
+
+def tear_down():
+    banner('Cleaning up.')
+    code = os.system('juju destroy-environment -e lpsetup-testing')
+    if code != 0:
+        raise RuntimeError('Destroying the test juju environment failed.')
+
+
+def main():
+    check_environment()
+    try:
+        set_up()
+        try:
+            do_test()
+        except:
+            banner('Test failed.  Sorry.')
+            return 1
+        else:
+            banner('Test succeeded.')
+            return 0
+    finally:
+        tear_down()
+
+
+if __name__ == '__main__':
+    sys.exit(main())