Commits

Mikhail Korobov committed 8308d67

Basic test infrastructure

Comments (0)

Files changed (10)

    fabfile
    reference
    related
+   testing
 
 Make sure you've read the following document if you are upgrading from
 previous versions of django-fab-deploy:
+Running tests
+=============
+
+Preparations
+------------
+
+In order to run tests you'll need `VirtualBox`_ 4.x and a configured OS image.
+Image should:
+
+* have root user with '123' password
+* have openssh server installed
+
+.. note::
+
+    Example VMs:
+
+    * `Lenny.ova (312M) <http://dl.dropbox.com/u/21197464/Lenny.ova>`_
+    * `Squeeze.ova (436M) <http://dl.dropbox.com/u/21197464/Squeeze.ova>`_
+
+After you get the image, make sure it is not running and execute the
+'preparevm.py' script from fab_deploy_tests folder (pass your VM name)::
+
+    ./preparevm.py Lenny
+
+This command configures port forwarding (127.0.0.1:2222 to guest 22 port,
+127.0.0.1:8888 to guest 80 port) and takes 'initial' snapshot used for test
+rollbacks (it is taken from booted machine in order to speedup tests).
+
+.. _VirtualBox: http://www.virtualbox.org/
+
+Running
+-------
+
+Pass OS name (as for :attr:`env.conf.OS`) and VM name (e.g. Lenny)
+to runtests.py script::
+
+    cd fab_deploy_tests
+    ./runtests.py <OS name> <VM name or uid>
+
+Tests can take a long time to run because VM is rolled back to clean
+state before each test.

fab_deploy_tests/__init__.py

+

fab_deploy_tests/fabfile.py

+from fab_deploy import *
+
+def foo_node():
+    env.hosts = ['foo@127.0.0.1:2222']
+    env.conf = dict(
+        DB_PASSWORD = '1234',
+        OS = env._OS,
+    )
+    update_env()

fab_deploy_tests/keys/id_rsa

+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEA1ZjdDZou5Kzq20Bqq+7c+CMJdpDb6n5AJ8hs3aDO+jjIaMsW
+GpbO9hOSzquia5WlnntJjwHNhnynPWv8ggQYI613/CIUyOzt3JUA+DKbRvaQR0tL
+fH0MVcijIU3MD6BMCpvPk+I/xBLQPxvKLBYsJYvtEvnWki75kaNJE/YMIdOwMyYi
+4CiPckLtzlTfbs8gzfBq0uQmEiTTADVvguMs6MyqBDaopeadANic7Vkf9nLw/UET
+VewQuzvAus4nmhTy2yZmSDHKpkn0mO08t1FKJSL5/kit8nkzeSuVSXp9LGfiGHSd
+k1F7oHXDWCQff7RpRLmyWCa5F/hEWo7Zj1M7iQIBIwKCAQA27MsgwT9CHdX93V1C
+J3qmNOUtHe9oLxfPtzHv2OTD//kFAQWvENYiBQh+SWRHjOFx5TAsFmgMo7X52fB5
+NEC4t5Phv57x1oZOqfjvXXhitG4+N+7W3lOhB7TrToTuE0bA5jyw/6n/OAmp0/Io
+l/y5MpwMMZ2TTehnRz6tXIbG3jDrCkUJP/9oeeNUnCbef/Zyelz1JoX2FLGx0Cvs
+ePEz5JVTYnG5vQjgTfIfzYGUsZjwVuf1Ii44iqSQN7amUJVJSiZpKn9lU+CcMjlv
+I/pTgfDnSA25HEnAKPfAF146aVNiocc1lgOanz5yItaLjQRAEQZb71OLu0t56o+b
+7HbHAoGBAP+E2tssJd2bXSEFDxRjsxxwPC/72lD9D5BHT351jBC+yxKBwYqL7Gf7
+xKvlvDcAl09Pys3q8278rneakJliJkQZb/QH8uZY/Vk9ubyLPPamX1Af3dBaLFgU
+9Pq1WgHyCdM6OTDYkFfHAKpyjZ34GsOe59fHYYSFrY7TEx2hJk4PAoGBANX/zgJX
+JkJdC8qAO96NY0X12F+PdAUCxMiTn/DngMd8pRno2dWc/qC5Oib9tpuzmsCxeaLq
+kCbiqwIL1qt4Q4aksoeK0oMYlKOmcC8KFqJy5sgiGcSr+0rOQfOMqSk6xHVCOBCx
+ecCAJkJ/DwZMdT/JHd5HsLbIOXOQ641zXHTnAoGBAINo5ZVJ55aKamjAxe06lqDp
+Q4ZkRGQqX8aLEvCUOWeylFKpIbT3gOUFI1EXEFbNGp3RQ7pbkyMi3WIU+eh7nqat
+/w/JktzdTxfz291O7CcTu/1SN4+5WKJT67QiwJNJRuGo6jZgv0MV4xXUg1iOOaZu
++uQAI4X7mxZAqr7H59BfAoGAZ/FGze/QwSXhJ9fikKsS9hhTJxnKo1kdwII3vidN
+LbGSBUU2mvR7rSbEeVapJw4X9zGhewQ3Y1gnLOEtwP/mSLZlV8cVyqWKBlgn3FVb
+c3mjS0PDX4a74oFwfZwXpk++ghjZZzGhiWLQwTZmYiUjAbl06E606xDLcqV5ubuw
+kI0CgYEAu+nju+rKf+3n4G902ZrJSxp9H3Rezdtvd5o+hQc7awPD+6aNzTfnsDEd
+ZtM6rbNIebGx1xDELy0JqsQ22HL/Q99gDgkZ17z3Qddl20hveo2PmTNBF6HVFKzb
+G/tSZ09Wna8uq0snHbGPC/NTRgkwzoGuCb0bOFYnYuXCFWTcyPo=
+-----END RSA PRIVATE KEY-----

fab_deploy_tests/keys/id_rsa.pub

+ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA1ZjdDZou5Kzq20Bqq+7c+CMJdpDb6n5AJ8hs3aDO+jjIaMsWGpbO9hOSzquia5WlnntJjwHNhnynPWv8ggQYI613/CIUyOzt3JUA+DKbRvaQR0tLfH0MVcijIU3MD6BMCpvPk+I/xBLQPxvKLBYsJYvtEvnWki75kaNJE/YMIdOwMyYi4CiPckLtzlTfbs8gzfBq0uQmEiTTADVvguMs6MyqBDaopeadANic7Vkf9nLw/UETVewQuzvAus4nmhTy2yZmSDHKpkn0mO08t1FKJSL5/kit8nkzeSuVSXp9LGfiGHSdk1F7oHXDWCQff7RpRLmyWCa5F/hEWo7Zj1M7iQ== 

fab_deploy_tests/preparevm.py

+#!/usr/bin/env python
+"""
+Prepares VirtualBox image: takes initial snapshot for rollbacks
+and configures port forwarding.
+"""
+
+import sys
+from time import sleep
+from fab_deploy_tests.utils import VirtualBox
+
+def prepare_vbox(name):
+    box = VirtualBox(name)
+    box.modifyvm('--natpf1', 'guestssh,tcp,,2222,,22')
+    box.modifyvm('--natpf1', 'http,tcp,,8888,,80')
+
+    box.start()
+    print 'Vaiting 100 seconds for OS to boot...'
+    for i in range(1,11):
+        sleep(10)
+        print '%ds remains' % (100-i*10)
+
+    box.snapshot('take', 'initial')
+    box.stop()
+
+if __name__ == '__main__':
+    prepare_vbox(sys.argv[1])
+

fab_deploy_tests/runtests.py

+#!/usr/bin/env python
+import sys
+import os.path
+
+# always use fab_deploy from the checkout, not the installed version
+path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+sys.path.insert(0, path)
+
+import unittest
+from fabric.api import env
+from fab_deploy_tests.tests import *
+
+if __name__ == '__main__':
+    env._OS = sys.argv[1]
+    env._VM_NAME = sys.argv[2]
+    sys.argv = [sys.argv[0]] + sys.argv[3:]
+    unittest.main()

fab_deploy_tests/tests/__init__.py

+import unittest
+import os.path
+from fabric.api import *
+from fab_deploy import create_linux_account
+from fab_deploy.utils import run_as
+
+from fab_deploy_tests.fabfile import foo_node
+from fab_deploy_tests.utils import fab, VirtualBox
+
+path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+print path
+
+class FabricTest(unittest.TestCase):
+    def setUp(self):
+        self.box = VirtualBox(env._VM_NAME)
+        self.run_snapshot('initial')
+
+        env.hosts = ['root@127.0.0.1:2222']
+        env.key_filename = None
+        env.password = '123'
+        env.disable_known_hosts = True
+
+    def tearDown(self):
+        self.box.stop()
+
+    def run_snapshot(self, name):
+        self.box.stop()
+        self.box.snapshot('restore', name)
+        self.box.start()
+
+    def assertUserIs(self, user):
+        # use it inside fab commands
+        assert run('whoami') == user
+
+class BasicTest(FabricTest):
+    def test_run_as(self):
+        foo_node()
+        @run_as('root')
+        def command():
+            self.assertUserIs('root')
+
+        fab(command)
+
+class SystemTest(FabricTest):
+    def test_create_linux_account(self):
+        foo_node()
+        fab(create_linux_account, os.path.join(path, "keys/id_rsa.pub"))
+        env.key_filename = [os.path.join(path, "keys/id_rsa")]
+
+        def command():
+            self.assertUserIs('foo')
+        fab(command)

fab_deploy_tests/utils.py

+import subprocess
+from time import sleep
+from os import system
+from functools import partial
+from fabric import state
+from fabric.main import get_hosts
+from fabric.network import interpret_host_string, HostConnectionCache
+
+def fab(command, *args, **kwargs):
+    """ Runs fab command. Accepts callable. """
+    state.connections = HostConnectionCache()
+    state.env.command = command.__name__
+    state.env.all_hosts = hosts = get_hosts(command, None, None)
+    for host in hosts:
+        interpret_host_string(host)
+        command(*args, **kwargs)
+
+
+class VirtualBox(object):
+    def __init__(self, name):
+        self.name = name
+
+    def __getattr__(self, name):
+        """
+        Attributes are converted to a functions calling
+        VBoxManage shell command.
+        """
+        return partial(self, name)
+
+    def __call__(self, command, *args):
+        params = ['VBoxManage', command, self.name] + list(args)
+        print '$ ' + ' '.join(params)
+        return subprocess.call(params)
+
+    def start(self):
+        self.startvm() #'--type', 'headless')
+
+    def stop(self):
+        self.controlvm('poweroff')