From bd4ece200400d6272dbba3259c25b6b59530b6c0 Mon Sep 17 00:00:00 2001 From: lars Date: Mon, 8 Jan 2007 05:08:07 +0000 Subject: [PATCH] improved base test classes added useful tools for testing unified test environment added description of test environment --- changelog | 9 +- plugins/date/unittests.py | 4 +- plugins/disks/unittests.py | 6 +- plugins/help/unittests.py | 4 +- plugins/language_selection/unittests.py | 4 +- plugins/logs/unittests.py | 4 +- plugins/network/unittests.py | 4 +- plugins/partition/unittests.py | 4 +- plugins/plugin_manager/unittests.py | 4 +- plugins/shutdown/unittests.py | 4 +- plugins/system_preferences/unittests.py | 4 +- plugins/user_manager/unittests.py | 4 +- plugins/volume_automount/unittests.py | 12 +- plugins/volume_chpasswd/unittests.py | 6 +- plugins/volume_details/unittests.py | 6 +- plugins/volume_format_fs/unittests.py | 35 +++-- plugins/volume_mount/unittests.py | 23 +-- plugins/volume_props/unittests.py | 6 +- plugins/volume_rename/unittests.py | 30 ++-- src/cryptobox/tests/__init__.py | 3 +- .../{web/testclass.py => tests/base.py} | 119 ++++++++------- src/cryptobox/tests/test.cryptobox.py | 27 ++-- src/cryptobox/tests/test.cryptoboxtools.py | 34 ++--- src/cryptobox/tests/test.plugins.py | 6 +- src/cryptobox/tests/test.websites.py | 18 +-- src/cryptobox/tests/tools.py | 140 ++++++++++++++++++ 26 files changed, 342 insertions(+), 178 deletions(-) rename src/cryptobox/{web/testclass.py => tests/base.py} (53%) create mode 100644 src/cryptobox/tests/tools.py diff --git a/changelog b/changelog index b5a685f..8eafa69 100644 --- a/changelog +++ b/changelog @@ -1,4 +1,9 @@ -Version 0.3.1 - 02/19/02007 +Version 0.3.2 - 01/08/02007 + * fixed bug causing ignorance towards group permissions (Closes: #114) + * fixed bug in Plugin manager breaking web interface (Closes: #111) + * fixed delay of Plugin manager settings being committed + +Version 0.3.1 - 12/20/02006 * fixed broken interface of 'partition' plugin for ie * fixed rendering bug of volume_properties for ie * fixed screen width in a mozilla/ie compatible way @@ -8,7 +13,7 @@ Version 0.3.1 - 02/19/02007 * changed default language to english * ports lower than 1024 are supported now -Version 0.3.0 - 02/15/02007 +Version 0.3.0 - 12/15/02006 * new interface * manage multiple disks * support custom partitioning diff --git a/plugins/date/unittests.py b/plugins/date/unittests.py index a09fa1a..604276c 100644 --- a/plugins/date/unittests.py +++ b/plugins/date/unittests.py @@ -20,9 +20,9 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_get_date(self): """retrieve the current date""" diff --git a/plugins/disks/unittests.py b/plugins/disks/unittests.py index 15149aa..e3311d7 100644 --- a/plugins/disks/unittests.py +++ b/plugins/disks/unittests.py @@ -20,9 +20,9 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): '''display all devices''' @@ -39,5 +39,5 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): self.cmd.find(r'Data.Status.Plugins.disks=(.*)$', "m") devices = self.locals["__match__"].split(":") self.assertTrue(len(devices)>0) - self.assertTrue("/dev/%s" % self.device in devices) + self.assertTrue(self.device in devices) diff --git a/plugins/help/unittests.py b/plugins/help/unittests.py index b876deb..62ef743 100644 --- a/plugins/help/unittests.py +++ b/plugins/help/unittests.py @@ -20,10 +20,10 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass from twill.errors import * -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_help_language_texts(self): '''help pages should be available in different languages''' diff --git a/plugins/language_selection/unittests.py b/plugins/language_selection/unittests.py index 7184664..c3dfcfe 100644 --- a/plugins/language_selection/unittests.py +++ b/plugins/language_selection/unittests.py @@ -20,9 +20,9 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): """Check if the 'language_selection' plugin works. diff --git a/plugins/logs/unittests.py b/plugins/logs/unittests.py index 3d8fa3f..af477d1 100644 --- a/plugins/logs/unittests.py +++ b/plugins/logs/unittests.py @@ -20,9 +20,9 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_logs(self): """Read the log files. diff --git a/plugins/network/unittests.py b/plugins/network/unittests.py index 8ecfd59..b72b47f 100644 --- a/plugins/network/unittests.py +++ b/plugins/network/unittests.py @@ -20,11 +20,11 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass from network import CHANGE_IP_DELAY -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_ip_change(self): '''Change network address.''' diff --git a/plugins/partition/unittests.py b/plugins/partition/unittests.py index 36ba4c9..eded740 100644 --- a/plugins/partition/unittests.py +++ b/plugins/partition/unittests.py @@ -20,9 +20,9 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): url = self.url + "partition?weblang=en" diff --git a/plugins/plugin_manager/unittests.py b/plugins/plugin_manager/unittests.py index caebd79..3207fd5 100644 --- a/plugins/plugin_manager/unittests.py +++ b/plugins/plugin_manager/unittests.py @@ -20,9 +20,9 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): """Check if the 'plugin_manager' works. diff --git a/plugins/shutdown/unittests.py b/plugins/shutdown/unittests.py index bfc2105..bfb4127 100644 --- a/plugins/shutdown/unittests.py +++ b/plugins/shutdown/unittests.py @@ -20,9 +20,9 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): """just read the form - I do not know of a way how to check success""" diff --git a/plugins/system_preferences/unittests.py b/plugins/system_preferences/unittests.py index 6342551..b653127 100644 --- a/plugins/system_preferences/unittests.py +++ b/plugins/system_preferences/unittests.py @@ -20,9 +20,9 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): self.cmd.go(self.url + "system_preferences") diff --git a/plugins/user_manager/unittests.py b/plugins/user_manager/unittests.py index eb9d821..f4f2670 100644 --- a/plugins/user_manager/unittests.py +++ b/plugins/user_manager/unittests.py @@ -20,12 +20,12 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass ## this user may not be removed from user_manager import RESERVED_USERS -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_users(self): diff --git a/plugins/volume_automount/unittests.py b/plugins/volume_automount/unittests.py index db0c6a8..2b6503e 100644 --- a/plugins/volume_automount/unittests.py +++ b/plugins/volume_automount/unittests.py @@ -20,13 +20,13 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): """try to read automount form""" - url = self.url + "volume_automount?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_automount?weblang=en&device=" + self.device_html self.register_auth(url) ## first: turn it off self.cmd.go(url + "&action=disable") @@ -38,10 +38,10 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): """try to toggle automount property""" url = self.url + "volume_automount" self.register_auth(url) - self.cmd.go(url + "?device=%%2Fdev%%2F%s&action=disable" % self.device) + self.cmd.go(url + "?device=%s&action=disable" % self.device_html) self.cmd.find("Automatic activation disabled") self.cmd.find("is disabled") - self.cmd.go(url + "?device=%%2Fdev%%2F%s&action=enable" % self.device) + self.cmd.go(url + "?device=%s&action=enable" % self.device_html) self.cmd.find("Automatic activation enabled") self.cmd.find("is enabled") @@ -50,7 +50,7 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): """check invalid inputs""" url = self.url + "volume_automount" self.register_auth(url) - self.cmd.go(url + "?device=%%2Fdev%%2F%s&action=foobar" % self.device) + self.cmd.go(url + "?device=%s&action=foobar" % self.device_html) self.cmd.notfind("Automatic activation disabled") self.cmd.notfind("Automatic activation enabled") diff --git a/plugins/volume_chpasswd/unittests.py b/plugins/volume_chpasswd/unittests.py index 5ad7f7a..d001dbc 100644 --- a/plugins/volume_chpasswd/unittests.py +++ b/plugins/volume_chpasswd/unittests.py @@ -20,12 +20,12 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): - url = self.url + "volume_chpasswd?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_chpasswd?weblang=en&device=" + self.device_html self.register_auth(url) self.cmd.go(url) self.cmd.find('hange') diff --git a/plugins/volume_details/unittests.py b/plugins/volume_details/unittests.py index cad34fe..e9d523b 100644 --- a/plugins/volume_details/unittests.py +++ b/plugins/volume_details/unittests.py @@ -20,12 +20,12 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): - url = self.url + "volume_details?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_details?weblang=en&device=" + self.device_html self.register_auth(url) self.cmd.go(url) self.cmd.find('Technical details') diff --git a/plugins/volume_format_fs/unittests.py b/plugins/volume_format_fs/unittests.py index 4746375..0e0d04b 100644 --- a/plugins/volume_format_fs/unittests.py +++ b/plugins/volume_format_fs/unittests.py @@ -20,15 +20,16 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass +import cryptobox.tests.tools as cbox_tools -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): """Simply check if the plugin works. """ - url = self.url + "volume_format_fs?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_format_fs?weblang=en&device=" + self.device_html self.register_auth(url) self.cmd.go(url) self.cmd.find('Initializing filesystem') @@ -37,8 +38,10 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def test_invalid_actions(self): """Try to issue some invalid orders. """ - url = self.url + "volume_format_fs?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_format_fs?weblang=en&device=" + self.device_html self.register_auth(url) + ## make sure, it is not mounted + cbox_tools.umount(self.device) ## try invalid filesystem type self.cmd.go(url + "&fs_type=foo") self.cmd.find('Initializing filesystem') @@ -70,21 +73,25 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def test_format_open_device(self): """Try to format an open device. """ - url = self.url + "volume_format_fs?weblang=en&device=%2Fdev%2F" + self.device - self.register_auth(url) - ## mount device - self.cmd.go(self.url + "volume_mount?weblang=en&device=%2Fdev%2F" \ - + self.device + "&action=mount_plain") + url_format = self.url + "volume_format_fs?weblang=en&device=" \ + + self.device_html + self.register_auth(url_format) + url_mount = self.url + "volume_mount?weblang=en&device=" \ + + self.device_html + self.register_auth(url_mount) + ## mount device - do not care, if it was mounted before + self.cmd.go(url_mount + "&action=mount_plain") self.cmd.find('Data.Status.Plugins.volume_mount=active') ## try plain device - self.cmd.go(url + "&store=step1&confirm=1&container_type=plain&fs_type=linux") + self.cmd.go(url_format + "&store=step1&confirm=1&container_type=plain&" \ + + "fs_type=linux") self.cmd.find('This action is not available while the volume is active.') ## try luks device - self.cmd.go(url + "&store=step2&container_type=luks&fs_type=windows" \ - + "&crypto_password=foo&crypto_password2=foo") + self.cmd.go(url_format + "&store=step2&container_type=luks&fs_type=" \ + + "windows&crypto_password=foo&crypto_password2=foo") self.cmd.find('This action is not available while the volume is active.') - self.cmd.go(self.url + "volume_mount?weblang=en&device=%2Fdev%2F" \ - + self.device + "&action=umount") + ## umount + cbox_tools.umount(self.device) def test_format_device(self): diff --git a/plugins/volume_mount/unittests.py b/plugins/volume_mount/unittests.py index 6f0870a..a0fb7ad 100644 --- a/plugins/volume_mount/unittests.py +++ b/plugins/volume_mount/unittests.py @@ -20,16 +20,19 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass +import cryptobox.tests.tools as cbox_tools import twill -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): """Simply check if the plugin works """ - url = self.url + "volume_mount?weblang=en&device=%2Fdev%2F" + self.device + ## umount, if necessary + cbox_tools.umount(self.device) + url = self.url + "volume_mount?weblang=en&device=" + self.device_html self.register_auth(url) self.cmd.go(url) self.cmd.find('Open volume') @@ -39,8 +42,10 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def test_mount(self): """Do all variations of mount/umount actions. """ - url = self.url + "volume_mount?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_mount?weblang=en&device=" + self.device_html self.register_auth(url) + ## umount, if necessary + cbox_tools.umount(self.device) ## we may not split these tests into two functions, as the order ## is important (we must leave a clean plain volume behind) self.__do_tests_with_luks() @@ -50,7 +55,7 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def __do_tests_with_luks(self): """Some tests with a luks partition. """ - url = self.url + "volume_mount?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_mount?weblang=en&device=" + self.device_html self.__format_luks() ## mount the volume self.cmd.go(url) @@ -89,7 +94,7 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def __do_tests_with_plain(self): """Some tests with a plain partition. """ - url = self.url + "volume_mount?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_mount?weblang=en&device=" + self.device_html self.__format_plain() ## open plain volume self.cmd.go(url) @@ -118,7 +123,7 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def __format_luks(self): """Format a luks partition. """ - url = self.url + "volume_format_fs?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_format_fs?weblang=en&device=" + self.device_html self.register_auth(url) self.cmd.go(url) self.cmd.find('select name="fs_type"') @@ -144,7 +149,7 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def __format_plain(self): """Format a plaintext partition. """ - url = self.url + "volume_format_fs?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_format_fs?weblang=en&device=" + self.device_html self.register_auth(url) self.cmd.go(url) self.cmd.find('select name="fs_type"') @@ -173,7 +178,7 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def __is_device_busy(self): """Check if the device is busy. """ - url = self.url + "volume_format_fs?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_format_fs?weblang=en&device=" + self.device_html self.register_auth(url) self.cmd.go(url) try: diff --git a/plugins/volume_props/unittests.py b/plugins/volume_props/unittests.py index f2c7281..0da6640 100644 --- a/plugins/volume_props/unittests.py +++ b/plugins/volume_props/unittests.py @@ -20,12 +20,12 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): - url = self.url + "volume_props?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_props?weblang=en&device=" + self.device_html self.register_auth(url) self.cmd.go(url) self.cmd.find('Properties') diff --git a/plugins/volume_rename/unittests.py b/plugins/volume_rename/unittests.py index 17c4db8..6714066 100644 --- a/plugins/volume_rename/unittests.py +++ b/plugins/volume_rename/unittests.py @@ -20,15 +20,19 @@ __revision__ = "$Id" -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass +import cryptobox.tests.tools as cbox_tools -class unittests(cryptobox.web.testclass.WebInterfaceTestClass): +class unittests(WebInterfaceTestClass): def test_read_form(self): """Check if the 'volume_rename' plugin works. """ - url = self.url + "volume_rename?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_rename?weblang=en&device=" + self.device_html self.register_auth(url) + ## umount, if necessary + cbox_tools.umount(self.device) + ## check a language string self.cmd.go(url) self.cmd.find('Change the name of this volume') @@ -36,6 +40,8 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def test_rename(self): """Try to rename the volume. """ + ## umount, if necessary + cbox_tools.umount(self.device) save_name = self.__get_name() ## rename if the name is already "foo" if save_name == "foo": @@ -59,6 +65,8 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def test_invalid_names(self): """Setting of invalid names should fail. """ + ## umount, if necessary + cbox_tools.umount(self.device) save_name = self.__get_name() ## we want to avoid, that if the previous name is (by accident) 'foo' ## then the later search for "changed successfully" would fail @@ -92,12 +100,14 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def test_rename_while_open(self): """Try to change the name of the volume while it is open. """ + ## umount, if necessary + cbox_tools.umount(self.device) save_name = self.__get_name() ## first set the name to 'bar' self.__set_name("bar") - mount_url = self.url + "volume_mount?weblang=en&device=%2Fdev%2F" + self.device + mount_url = self.url + "volume_mount?weblang=en&device=" + self.device_html self.register_auth(mount_url) - name_url = self.url + "volume_rename?weblang=en&device=%2Fdev%2F" + self.device + name_url = self.url + "volume_rename?weblang=en&device=" + self.device_html self.register_auth(name_url) self.cmd.go(mount_url + "&action=mount_plain") self.cmd.find('Volume opened') @@ -113,8 +123,10 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def test_name_in_use(self): """Try to set a name that is already in use. """ + ## umount, if necessary + cbox_tools.umount(self.device) used_name = [ e.get_name() for e in self.cbox.get_container_list() - if e.get_device() != "/dev/%s" % self.device ] + if e.get_device() != self.device ] if not used_name: self.fail("could not find another device for this test") old_name = self.__get_name() @@ -128,7 +140,7 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): """Set the name of a volume. """ name = name.replace(" ", "%20") - url = self.url + "volume_rename?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_rename?weblang=en&device=" + self.device_html self.register_auth(url) # the following should work, but twill seems to have problems to recognize # the form - fix this later @@ -141,9 +153,9 @@ class unittests(cryptobox.web.testclass.WebInterfaceTestClass): def __get_name(self): """Retrieve the current name of the volume. """ - url = self.url + "volume_rename?weblang=en&device=%2Fdev%2F" + self.device + url = self.url + "volume_rename?weblang=en&device=" + self.device_html self.register_auth(url) self.cmd.go(url) self.cmd.find("Data.Status.Plugins.volume_rename=(.*)$", "m") return self.locals["__match__"] - + diff --git a/src/cryptobox/tests/__init__.py b/src/cryptobox/tests/__init__.py index afc7ca5..57b82a9 100644 --- a/src/cryptobox/tests/__init__.py +++ b/src/cryptobox/tests/__init__.py @@ -3,5 +3,6 @@ __revision__ = "$Id" -__all__ = [ 'test.cryptobox', 'test.cryptoboxtools', 'test.plugins', 'test.websites' ] +__all__ = [ 'test.cryptobox', 'test.cryptoboxtools', 'test.plugins', 'test.websites', + 'base', 'tools' ] diff --git a/src/cryptobox/web/testclass.py b/src/cryptobox/tests/base.py similarity index 53% rename from src/cryptobox/web/testclass.py rename to src/cryptobox/tests/base.py index f844564..9b77a35 100644 --- a/src/cryptobox/web/testclass.py +++ b/src/cryptobox/tests/base.py @@ -19,9 +19,21 @@ # """ -super class of all web interface unittests for the cryptobox +this module contains all super classes for different tests -just inherit this class and add some test functions +just inherit one of its classes and add some test functions + +All testclasses based on the classes of this module may assume the following: + - there is one valid parent blockdevice (self.blockdevice) + - the blockdevice contains exactly two partitions: + - part1: vfat, 50MB, formatted (devicename: self.device) + - part2: ext3, 50MB, formatted + - self.blockdevice_html and self.device_html are url-escaped strings + - all databases (pluginconf, volume names, users) are empty + +Additional hints: + - if the current state of self.device is important, then you should umount + it before any of these tests: cryptobox.tests.tools.umount(self.device) """ __revision__ = "$Id" @@ -30,7 +42,8 @@ import unittest import twill import cherrypy import cryptobox.web.sites -import os +import cryptobox.tests.base + ## commands api: http://twill.idyll.org/commands.html @@ -39,27 +52,65 @@ CBXPORT = 8081 CBX_URL = "http://%s:%d/" % (CBXHOST, CBXPORT) LOG_FILE = "/tmp/cryptobox-twill.log" WEBLOG_FILE = "/tmp/cryptobox-cherrypy.log" +CONF_FILE = 'cryptobox-unittests.conf' -class WebInterfaceTestClass(unittest.TestCase): +class CommonTestClass(unittest.TestCase): + """Super class of all tests of the CryptoBox + + prepare environment, set some values ... + """ + + def __init__(self, methodName='runTest'): + unittest.TestCase.__init__(self, methodName) + import cryptobox.core.settings as cbox_settings + import cryptobox.tests.tools as testtools + import os + ## search for a usable block device + ## use /dev/ubd? if possible - otherwise /dev/hd? + ## so it will be possible to use these tests inside of a uml + self.blockdevice = testtools.find_test_device() + ## umount the partitions of this device (just to be sure) + for num in range(12): + testtools.umount("%s%d" % (self.blockdevice, num)) + ## format device and partition block device if necessary + testtools.prepare_partition(self.blockdevice) + self.blockdevice = testtools.find_test_device() + self.device = self.blockdevice + "1" + self.blockdevice_html = self.blockdevice.replace("/", "%2F") + self.device_html = self.device.replace("/", "%2F") + + ## remove configuration files + ## first: retrieve the settings directory + settings_dir = cbox_settings.CryptoBoxSettings(CONF_FILE)\ + ["Locations"]["SettingsDir"] + for filename in [ + cbox_settings.VOLUMESDB_FILE, + cbox_settings.PLUGINCONF_FILE, + cbox_settings.USERDB_FILE]: + try: + os.unlink(os.path.join(settings_dir, filename)) + except OSError: + pass + + + +class WebInterfaceTestClass(CommonTestClass): '''this class checks the webserver, using "twill" the tests in this class are from the browsers point of view, so not really unittests. fetch twill from: http://twill.idyll.org - one way to manually run twill code is through the python - interpreter commandline e.g.: - - import twill - twill.shell.main() - go http://localhost:8080 - find "my very special html content" - help ''' + def __init__(self, methodName='runTest'): + CommonTestClass.__init__(self, methodName) + + def setUp(self): '''configures the cherrypy server that it works nice with twill ''' + CommonTestClass.setUp(self) cherrypy.config.update({ 'server.logToScreen' : False, 'autoreload.on': False, @@ -68,8 +119,8 @@ class WebInterfaceTestClass(unittest.TestCase): 'server.log_tracebacks': True, 'server.log_file': WEBLOG_FILE, }) - cherrypy.root = cryptobox.web.sites.WebInterfaceSites( - "cryptobox-unittests.conf") + cherrypy.root = cryptobox.web.sites.WebInterfaceSites(CONF_FILE) + cherrypy.server.start(initOnly=True, serverClass=None) from cherrypy._cpwsgi import wsgiApp @@ -82,15 +133,6 @@ class WebInterfaceTestClass(unittest.TestCase): self.url = CBX_URL self.cbox = cherrypy.root.cbox self.globals, self.locals = twill.namespaces.get_twill_glocals() - ## search for a usable block device - ## use /dev/ubd? if possible - otherwise /dev/hd? - ## so it will be possible to use these tests inside of an uml - self.blockdevice, self.device = self.__find_test_device() - ## umount the device (just to be sure) - url = self.url + "volume_mount?weblang=en&device=%2Fdev%2F" + self.device - self.register_auth(url) - self.cmd.go(url + "&action=umount") - def tearDown(self): @@ -102,6 +144,9 @@ class WebInterfaceTestClass(unittest.TestCase): ## shut down the cherrypy server. cherrypy.server.stop() self.output.close() + ## inform the parent + CommonTestClass.tearDown(self) + def __get_soup(): @@ -110,34 +155,6 @@ class WebInterfaceTestClass(unittest.TestCase): return soup - def __find_test_device(self): - """Search for a valid test device - the data will get lost ... - """ - for dev in ["ubdb", "loop", "ubda", "udbc", "ubdd"]: - if os.path.exists("/dev/%s1" % dev) \ - and not self.__is_config_partition("/dev/%s1" % dev): - return (dev, dev + "1") - if os.path.exists("/dev/%s2" % dev) \ - and not self.__is_config_partition("/dev/%s2" % dev): - return (dev, dev + "2") - else: - raise Exception, "no valid device for testing found" - - - def __is_config_partition(self, device): - """Check if the device is a configuration partition. - """ - import subprocess - proc = subprocess.Popen( - shell = False, - stdout = subprocess.PIPE, - stderr = subprocess.PIPE, - args = [ '/sbin/e2label', - device ]) - (stdout, stderr) = proc.communicate() - return stdout.strip() == "cbox_config" - - def register_auth(self, url, user="admin", password="admin"): self.cmd.add_auth("CryptoBox", url, user, password) diff --git a/src/cryptobox/tests/test.cryptobox.py b/src/cryptobox/tests/test.cryptobox.py index fb849dd..5b4c274 100755 --- a/src/cryptobox/tests/test.cryptobox.py +++ b/src/cryptobox/tests/test.cryptobox.py @@ -25,34 +25,37 @@ __revision__ = "$Id" -import unittest -import sys import cryptobox.core.main from cryptobox.core.exceptions import * import cryptobox.core.settings +from cryptobox.tests.base import CommonTestClass import os -class CryptoBoxDeviceTests(unittest.TestCase): + +class CryptoBoxDeviceTests(CommonTestClass): """Some unittests for the CryptoBox """ cb = cryptobox.core.main.CryptoBox() - + + def test_allowed_devices(self): '''is_device_allowed should accept permitted devices''' self.assertTrue(self.cb.is_device_allowed("/dev/loop")) self.assertTrue(self.cb.is_device_allowed("/dev/loop1")) self.assertTrue(self.cb.is_device_allowed("/dev/loop/urgd")) self.assertTrue(self.cb.is_device_allowed("/dev/usb/../loop1")) - + + def test_denied_devices(self): '''is_device_allowed should fail with not explicitly allowed devices''' self.assertFalse(self.cb.is_device_allowed("/dev/hda")) self.assertFalse(self.cb.is_device_allowed("/dev/loopa/../hda")) self.assertFalse(self.cb.is_device_allowed("/")) - -class CryptoBoxConfigTests(unittest.TestCase): + + +class CryptoBoxConfigTests(CommonTestClass): '''test here if everything with the config turns right''' files = { "configFileOK" : "cbox-test_ok.conf", @@ -92,7 +95,10 @@ CryptoBoxRootActions = CryptoBoxRootActions def setUp(self): - '''generate all files in tmp and remember the names''' + '''prepare the test + ''' + CommonTestClass.setUp(self) + ## generate all files in tmp and remember the names import tempfile self.tmpdirname = tempfile.mkdtemp(prefix="cbox-") for tfile in self.files.keys(): @@ -109,6 +115,7 @@ CryptoBoxRootActions = CryptoBoxRootActions os.remove(compl_name) # remove temp dir os.rmdir(self.tmpdirname) + CommonTestClass.tearDown(self) def test_config_init(self): @@ -176,7 +183,3 @@ CryptoBoxRootActions = CryptoBoxRootActions cfile.write(content) cfile.close() - -if __name__ == "__main__": - unittest.main() - diff --git a/src/cryptobox/tests/test.cryptoboxtools.py b/src/cryptobox/tests/test.cryptoboxtools.py index 534f5f5..20aad25 100755 --- a/src/cryptobox/tests/test.cryptoboxtools.py +++ b/src/cryptobox/tests/test.cryptoboxtools.py @@ -25,22 +25,12 @@ __revision__ = "$Id" -import unittest import cryptobox.core.tools as cbx_tools +from cryptobox.tests.base import CommonTestClass import os -## use /dev/ubd? if possible - otherwise /dev/hd? -## so it will be possible to use these tests inside of an uml -for d in ["ubdb", "ubda", "udbc", "ubdd", "hdb", "hda", "hdc", "hdd"]: - if os.path.exists("/dev/%s1" % d): - device = d - break -else: - device = "hda" - - -class CryptoBoxToolsTests(unittest.TestCase): +class CryptoBoxToolsTests(CommonTestClass): """All unittests for cryptoboxtools """ @@ -48,7 +38,7 @@ class CryptoBoxToolsTests(unittest.TestCase): """check the get_absolute_devicename function """ func = cbx_tools.get_absolute_devicename - self.assertTrue(func(device) == "/dev/%s" % device) + self.assertTrue(func(os.path.basename(self.device)) == self.device) self.assertTrue(func("loop0") == "/dev/loop0") self.assertTrue(func(os.path.devnull) == os.path.devnull) @@ -75,17 +65,13 @@ class CryptoBoxToolsTests(unittest.TestCase): """check the is_part_of_blockdevice function """ func = cbx_tools.is_part_of_blockdevice - self.assertTrue(func("/dev/%s" % device, "/dev/%s1" % device)) - self.assertFalse(func("/dev/%s" % device, "/dev/%s" % device)) - self.assertFalse(func("/dev/%s1" % device, "/dev/%s" % device)) - self.assertFalse(func("/dev/%s1" % device, "/dev/%s1" % device)) - self.assertFalse(func("/dev/%s" % device, "/dev/hde1")) - self.assertFalse(func(None, "/dev/%s1" % device)) - self.assertFalse(func("/dev/%s" % device, None)) + self.assertTrue(func(self.blockdevice, self.device)) + self.assertFalse(func(self.blockdevice, self.blockdevice)) + self.assertFalse(func(self.device, self.blockdevice)) + self.assertFalse(func(self.device, self.device)) + self.assertFalse(func(self.blockdevice, "/dev/hde1")) + self.assertFalse(func(None, self.blockdevice)) + self.assertFalse(func(self.blockdevice, None)) self.assertFalse(func(None, "")) self.assertFalse(func("loop0", "loop1")) - -if __name__ == "__main__": - unittest.main() - diff --git a/src/cryptobox/tests/test.plugins.py b/src/cryptobox/tests/test.plugins.py index 5e3f89d..723d540 100755 --- a/src/cryptobox/tests/test.plugins.py +++ b/src/cryptobox/tests/test.plugins.py @@ -24,10 +24,10 @@ __revision__ = "$Id" -import unittest +from cryptobox.tests.base import CommonTestClass import cryptobox.plugins.manage -class CheckForUndefinedTestCases(unittest.TestCase): +class CheckForUndefinedTestCases(CommonTestClass): """here we will add failing test functions for every non-existing testcase""" @@ -54,5 +54,3 @@ def create_testcases(): create_testcases() -if __name__ == "__main__": - unittest.main() diff --git a/src/cryptobox/tests/test.websites.py b/src/cryptobox/tests/test.websites.py index 26927eb..0621778 100755 --- a/src/cryptobox/tests/test.websites.py +++ b/src/cryptobox/tests/test.websites.py @@ -26,18 +26,11 @@ This class uses twill. __revision__ = "$Id" -import unittest - -## this makes assertRaises shorter -from twill.errors import * -from mechanize import BrowserStateError, LinkNotFoundError - -## import the module of the common super class of all web interface test classes -import cryptobox.web.testclass +from cryptobox.tests.base import WebInterfaceTestClass -class WebServer(cryptobox.web.testclass.WebInterfaceTestClass): +class WebServer(WebInterfaceTestClass): """Basic tests for the webserver. """ @@ -49,7 +42,8 @@ class WebServer(cryptobox.web.testclass.WebInterfaceTestClass): ## other URLs must not be checked, as we do not know, if they are valid -class BuiltinPages(cryptobox.web.testclass.WebInterfaceTestClass): + +class BuiltinPages(WebInterfaceTestClass): """Basic test of builtin pages (no features). """ @@ -66,7 +60,3 @@ class BuiltinPages(cryptobox.web.testclass.WebInterfaceTestClass): self.cmd.go(self.url + "?weblang=fr") self.cmd.find("La CryptoBox") - -if __name__ == "__main__": - unittest.main() - diff --git a/src/cryptobox/tests/tools.py b/src/cryptobox/tests/tools.py new file mode 100644 index 0000000..51dfe36 --- /dev/null +++ b/src/cryptobox/tests/tools.py @@ -0,0 +1,140 @@ +# +# Copyright 2006 sense.lab e.V. +# +# This file is part of the CryptoBox. +# +# The CryptoBox is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# The CryptoBox is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the CryptoBox; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +this module contains some useful tools to be used during the tests + +just inherit one of its classes and add some test functions +""" + +__revision__ = "$Id" + +TEST_DEVICE_LIST = ["ubdb", "loop", "ubda", "udbc", "ubdd", "sd"] + + +import os +import subprocess + +def find_test_device(): + """Search for a valid test device - the data will get lost ... + + the result is the parent blockdevice (containing the partition table) + and the single partition + """ + for dev in TEST_DEVICE_LIST: + if os.path.exists("/dev/%s" % dev) \ + and os.access("/dev/%s" % dev, os.W_OK): + try: + ## try if it is a symlink + return os.readlink("/dev/%s" % dev) + except OSError: + ## not a symlink (usual) + return "/dev/%s" % dev + else: + raise Exception, "no valid device for testing found" + + +def is_config_partition(device): + """Check if the device is a configuration partition. + """ + proc = subprocess.Popen( + shell = False, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + args = [ '/sbin/e2label', + device ]) + (stdout, stderr) = proc.communicate() + return stdout.strip() == "cbox_config" + + +def umount(device): + """Umount the specified device if possible - ignore errors + """ + proc = subprocess.Popen( + shell = False, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + args = [ '/bin/umount', '-d', device ]) + proc.wait() + + +def prepare_partition(blockdevice): + """Prepare the expected partition in the device (destroy all data) + + Check if 'device' is a vfat partition - if not, then + partition 'blockdevice' and format 'device' as vfat + """ + if (get_fs_type(blockdevice + "1") == "vfat") \ + and (get_fs_type(blockdevice + "2") == "ext3") \ + and (get_fs_type(blockdevice + "3") is None) \ + and (get_fs_type(blockdevice + "5") is None): + ## everything is fine + return + else: + ## repartitioning + proc = subprocess.Popen( + shell = False, + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + args = [ '/sbin/sfdisk', blockdevice ]) + proc.stdin.write(",50,0xC\n,50,L\n") + (output, error) = proc.communicate() + if proc.returncode != 0: + raise Exception, "could not partition the device (%s): %s" \ + % (blockdevice, output.strip()) + ## formatting + format_device(blockdevice + "1", "vfat") + format_device(blockdevice + "2", "ext3") + + +def get_fs_type(device): + proc = subprocess.Popen( + shell = False, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + args = [ '/sbin/blkid', + '-c', os.path.devnull, + '-w', os.path.devnull, + '-o', 'value', + '-s', 'TYPE', + device]) + (output, error) = proc.communicate() + if (proc.returncode == 0) and output.strip(): + ## everything is fine + return output.strip() + else: + return None + + +def format_device(device, fs_type="vfat"): + proc = subprocess.Popen( + shell = False, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE, + args = [ '/sbin/mkfs', + '-t', fs_type, + device ]) + (output, error) = proc.communicate() + if proc.returncode != 0: + raise OSError, "could not format the device (%s): %s" \ + % (device, output.strip()) + +