[tracker/sam/functional-test-runner: 9/15] WIP: functional-tests: migrating to new layout ...



commit 91571554c3b669075ad66e5d874481fb654fc9d4
Author: Sam Thursfield <sam afuera me uk>
Date:   Mon Dec 29 16:56:16 2014 +0000

    WIP: functional-tests: migrating to new layout ...

 tests/functional-tests/apps/__init__.py            |    3 +
 .../functional-tests/common/{utils => }/helpers.py |    0
 tests/functional-tests/common/sandbox.py           |   85 ++++
 tests/functional-tests/common/utils/storetest.py   |   50 ---
 .../functional-tests/store/test_backup_restore.py  |  415 ++++++++++----------
 tests/functional-tests/store/testcase.py           |   47 +++
 6 files changed, 341 insertions(+), 259 deletions(-)
---
diff --git a/tests/functional-tests/apps/__init__.py b/tests/functional-tests/apps/__init__.py
new file mode 100644
index 0000000..61b258f
--- /dev/null
+++ b/tests/functional-tests/apps/__init__.py
@@ -0,0 +1,3 @@
+"""
+This module contains functional tests for Tracker.
+"""
diff --git a/tests/functional-tests/common/utils/helpers.py b/tests/functional-tests/common/helpers.py
similarity index 100%
rename from tests/functional-tests/common/utils/helpers.py
rename to tests/functional-tests/common/helpers.py
diff --git a/tests/functional-tests/common/sandbox.py b/tests/functional-tests/common/sandbox.py
new file mode 100644
index 0000000..d3b9f2f
--- /dev/null
+++ b/tests/functional-tests/common/sandbox.py
@@ -0,0 +1,85 @@
+# Copyright (C) 2014, Sam Thursfield <sam afuera me uk>
+#
+# This program 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.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+
+import os
+import shutil
+import subprocess
+import tempfile
+
+from logging import info
+
+
+class TrackerSandbox(object):
+    '''FIXME: merge with 'tracker-sandbox' tool
+
+    This class handles isolating each test case from both other test cases and
+    from the host system.
+
+    '''
+    def __init__(self, user_dirs=True, message_bus=True):
+        self.tempdir = None
+        self.dbus_process = self.dbus_address = None
+
+        self._old_environ = os.environ
+
+        if user_dirs:
+            self.tempdir = self._sandbox_user_dirs()
+
+        if message_bus:
+            self.dbus_process, self.dbus_address = self._sandbox_message_bus()
+
+    def _sandbox_user_dirs(self):
+        tempdir = tempfile.mkdtemp(prefix='tracker-test')
+
+        # We need to use the actual home directory for some tests because
+        # Tracker will explicitly ignore files in /tmp ...
+        os.environ['REAL_HOME'] = os.path.expanduser('~')
+
+        # ... but /tmp is preferred for test data, to avoid leaving debris
+        # in the filesystem
+        os.environ['HOME'] = tempdir
+        info("HOME=%s" % tempdir)
+
+        return tempdir
+
+    def _sandbox_message_bus(self):
+        dbus_process = subprocess.Popen(
+            ["dbus-daemon", "--session", "--print-address=1", "--fork"],
+            stdout=subprocess.PIPE)
+        dbus_address = self.dbus_process.stdout.readline().rstrip()
+
+        os.environ['DBUS_SESSION_BUS_ADDRESS'] = dbus_address
+        info("DBUS_SESSION_BUS_ADDRESS=%s" % dbus_address)
+
+        return dbus_process, dbus_address
+
+    def _stop_message_bus(self, dbus_process):
+        info('Stopping D-Bus daemon (PID %i) ...' % (dbus_process.pid))
+        dbus_process.terminate()
+        dbus_process.stop()
+
+    def _remove_tempdir(self, tempdir):
+        shutil.rmtree(tempdir)
+
+    def close(self):
+        if self.tempdir:
+            self._remove_tempdir(self.tempdir)
+        if self.dbus_process:
+            self._stop_message_bus(self.dbus_process)
+
+        os.environ = self._old_environ
diff --git a/tests/functional-tests/store/test_backup_restore.py 
b/tests/functional-tests/store/test_backup_restore.py
index 6d58f5b..63cecdf 100644
--- a/tests/functional-tests/store/test_backup_restore.py
+++ b/tests/functional-tests/store/test_backup_restore.py
@@ -23,9 +23,9 @@ import dbus  # For the exception handling
 from common.utils.system import TrackerSystemAbstraction
 from common.utils.helpers import StoreHelper
 from common.utils import configuration as cfg
-from common.utils.storetest import CommonTrackerStoreTest as CommonTrackerStoreTest
 from common.utils.expectedFailure import expectedFailureBug, expectedFailureJournal
-import unittest as ut
+
+import storetest
 
 
 """
@@ -33,11 +33,9 @@ Call backup, restore, force the journal replay and check the data is correct aft
 """
 
 
-class BackupRestoreTest (CommonTrackerStoreTest):
+class BackupRestoreTest (storetest.TrackerStoreTest):
 
-    """
-    Backup and restore to/from valid/invalid files
-    """
+    '''Backup and restore to/from valid/invalid files'''
 
     def setUp(self):
         self.TEST_INSTANCE = "test://backup-restore/1"
@@ -47,209 +45,211 @@ class BackupRestoreTest (CommonTrackerStoreTest):
         if (os.path.exists(self.BACKUP_FILE)):
             os.unlink(self.BACKUP_FILE)
 
-    def __insert_test_instance(self):
-        self.tracker.update("INSERT { <%s> a nco:Contact; nco:fullname 'test-backup' } "
-                            % (self.TEST_INSTANCE))
-
-    def __delete_test_instance(self):
-        self.tracker.update(
-            "DELETE { <%s> a rdfs:Resource } " % (self.TEST_INSTANCE))
-
-    def __is_test_instance_there(self):
-        result = self.tracker.query(
-            "SELECT ?u WHERE { ?u a nco:Contact; nco:fullname 'test-backup'}")
-        if (len(result) == 1 and len(result[0]) == 1 and result[0][0] == self.TEST_INSTANCE):
-            return True
-        return False
-
-    def test_backup_01(self):
-        """
-        Inserted data is restored after backup
-
-        1.Insert contact
-        2.Take backup.
-        3.Delete contact. (check it is not there)
-        4.Restore the file.
-        5.Check the contact is back there
-        """
-
-        self.__insert_test_instance()
-        instances_before = self.tracker.count_instances("nco:Contact")
-
-        self.tracker.backup(self.BACKUP_FILE)
-
-        self.__delete_test_instance()
-        instances_now = self.tracker.count_instances("nco:Contact")
-
-        self.assertEquals(instances_before - 1, instances_now)
+        def __insert_test_instance(self):
+            self.tracker.update("INSERT { <%s> a nco:Contact; nco:fullname 'test-backup' } "
+                                % (self.TEST_INSTANCE))
 
-        self.tracker.restore(self.BACKUP_FILE)
+        def __delete_test_instance(self):
+            self.tracker.update(
+                "DELETE { <%s> a rdfs:Resource } " % (self.TEST_INSTANCE))
 
-        instances_after = self.tracker.count_instances("nco:Contact")
+        def __is_test_instance_there(self):
+            result = self.tracker.query(
+                "SELECT ?u WHERE { ?u a nco:Contact; nco:fullname 'test-backup'}")
+            if (len(result) == 1 and len(result[0]) == 1 and result[0][0] == self.TEST_INSTANCE):
+                return True
+            return False
+
+        def test_backup_01(self):
+            """
+            Inserted data is restored after backup
+
+            1.Insert contact
+            2.Take backup.
+            3.Delete contact. (check it is not there)
+            4.Restore the file.
+            5.Check the contact is back there
+            """
+
+            self.__insert_test_instance()
+            instances_before = self.tracker.count_instances("nco:Contact")
+
+            self.tracker.backup(self.BACKUP_FILE)
+
+            self.__delete_test_instance()
+            instances_now = self.tracker.count_instances("nco:Contact")
+
+            self.assertEquals(instances_before - 1, instances_now)
+
+            self.tracker.restore(self.BACKUP_FILE)
+
+            instances_after = self.tracker.count_instances("nco:Contact")
+
+            self.assertEquals(instances_before, instances_after)
+            self.assertTrue(self.__is_test_instance_there())
+
+            # Clean the DB for the next test
+            self.__delete_test_instance()
+
+        def test_backup_02(self):
+            """
+            Data inserted after backup is lost in restore
+
+            1.Take backup of db.
+            2.Insert a contact.
+            3.Restore the db.
+            4.Search for the contact inserted.
+            """
+
+            # Precondition: test backup contact shouldn't be there
+            self.assertFalse(self.__is_test_instance_there())
+
+            self.tracker.backup(self.BACKUP_FILE)
+
+            self.__insert_test_instance()
+            self.assertTrue(self.__is_test_instance_there())
+
+            self.tracker.restore(self.BACKUP_FILE)
+
+            self.assertFalse(self.__is_test_instance_there())
+
+        def test_backup_03(self):
+            """
+            Restore from a random text file
+            """
+            TEST_FILE = os.path.join(cfg.TEST_TMP_DIR, "trash_file")
+            trashfile = open(TEST_FILE, "w")
+            trashfile.write(
+                "Here some useless text that obviously is NOT a backup")
+            trashfile.close()
+
+            self.assertRaises(dbus.DBusException,
+                              self.tracker.restore,
+                              "file://" + TEST_FILE)
+            os.unlink(TEST_FILE)
+
+        def test_backup_04(self):
+            """
+            Restore from a random binary file
+            """
+            TEST_FILE = os.path.join(cfg.TEST_TMP_DIR, "trash_file.dat")
+
+            import struct
+            trashfile = open(TEST_FILE, "wb")
+            for n in range(0, 50):
+                data = struct.pack('i', n)
+                trashfile.write(data)
+            trashfile.close()
+
+            instances_before = self.tracker.count_instances(
+                "nie:InformationElement")
+            self.assertRaises(dbus.DBusException,
+                              self.tracker.restore,
+                              "file://" + TEST_FILE)
+
+            os.unlink(TEST_FILE)
+
+        def test_backup_05(self):
+            """
+            Take backup of db to a invalid path.
+            Expected: Backup should not be taken and tracker should behave normally.
+            """
+            self.assertRaises(dbus.DBusException,
+                              self.tracker.backup,
+                              "file://%s/this/is/a/non-existant/folder/backup" % (cfg.TEST_TMP_DIR))
+
+        def test_backup_06(self):
+            """
+            Try to restore an invalid path
+            """
+            self.assertRaises(dbus.DBusException,
+                              self.tracker.restore,
+                              "file://%s/this/is/a/non-existant/folder/backup" % (cfg.TEST_TMP_DIR))
+
+        def test_backup_07(self):
+            """
+            Restore after removing the DBs and journal
 
-        self.assertEquals(instances_before, instances_after)
-        self.assertTrue(self.__is_test_instance_there())
-
-        # Clean the DB for the next test
-        self.__delete_test_instance()
-
-    def test_backup_02(self):
-        """
-        Data inserted after backup is lost in restore
-
-        1.Take backup of db.
-        2.Insert a contact.
-        3.Restore the db.
-        4.Search for the contact inserted.
-        """
-
-        # Precondition: test backup contact shouldn't be there
-        self.assertFalse(self.__is_test_instance_there())
-
-        self.tracker.backup(self.BACKUP_FILE)
-
-        self.__insert_test_instance()
-        self.assertTrue(self.__is_test_instance_there())
-
-        self.tracker.restore(self.BACKUP_FILE)
-
-        self.assertFalse(self.__is_test_instance_there())
-
-    def test_backup_03(self):
-        """
-        Restore from a random text file
-        """
-        TEST_FILE = os.path.join(cfg.TEST_TMP_DIR, "trash_file")
-        trashfile = open(TEST_FILE, "w")
-        trashfile.write(
-            "Here some useless text that obviously is NOT a backup")
-        trashfile.close()
-
-        self.assertRaises(dbus.DBusException,
-                          self.tracker.restore,
-                          "file://" + TEST_FILE)
-        os.unlink(TEST_FILE)
-
-    def test_backup_04(self):
-        """
-        Restore from a random binary file
-        """
-        TEST_FILE = os.path.join(cfg.TEST_TMP_DIR, "trash_file.dat")
-
-        import struct
-        trashfile = open(TEST_FILE, "wb")
-        for n in range(0, 50):
-            data = struct.pack('i', n)
-            trashfile.write(data)
-        trashfile.close()
-
-        instances_before = self.tracker.count_instances(
-            "nie:InformationElement")
-        self.assertRaises(dbus.DBusException,
-                          self.tracker.restore,
-                          "file://" + TEST_FILE)
-
-        os.unlink(TEST_FILE)
-
-    def test_backup_05(self):
-        """
-        Take backup of db to a invalid path.
-        Expected: Backup should not be taken and tracker should behave normally.
-        """
-        self.assertRaises(dbus.DBusException,
-                          self.tracker.backup,
-                          "file://%s/this/is/a/non-existant/folder/backup" % (cfg.TEST_TMP_DIR))
-
-    def test_backup_06(self):
-        """
-        Try to restore an invalid path
-        """
-        self.assertRaises(dbus.DBusException,
-                          self.tracker.restore,
-                          "file://%s/this/is/a/non-existant/folder/backup" % (cfg.TEST_TMP_DIR))
-
-    def test_backup_07(self):
-        """
-        Restore after removing the DBs and journal
-
-        1.Insert a contact.
-        2.Take backup of db.
-        4.Delete the database
-        5.Restore the db.
-        6.Search for the contact inserted.
-        """
-        self.__insert_test_instance()
-        instances_before = self.tracker.count_instances("nco:Contact")
-        self.tracker.backup(self.BACKUP_FILE)
-
-        self.system.tracker_store_stop_nicely()
-        self.system.tracker_store_remove_dbs()
-        self.system.tracker_store_remove_journal()
-        self.system.tracker_store_start()
-
-        instances_before_restore = self.tracker.count_instances("nco:Contact")
-        self.assertNotEqual(instances_before_restore, instances_before)
-
-        self.tracker.restore(self.BACKUP_FILE)
-        self.assertTrue(self.__is_test_instance_there())
-
-        self.__delete_test_instance()
-
-    def test_backup_08(self):
-        """
-        Restore after corrupting DB
-
-        1.Insert a contact.
-        2.Take backup of db.
-        5.Restore the db.
-        6.Search for the contact inserted.
-        """
-        self.__insert_test_instance()
-        instances_before = self.tracker.count_instances("nco:Contact")
-        self.tracker.backup(self.BACKUP_FILE)
-
-        self.system.tracker_store_stop_brutally()
-        self.system.tracker_store_corrupt_dbs()
-        self.system.tracker_store_remove_journal()
-        self.system.tracker_store_start()
-
-        instances_before_restore = self.tracker.count_instances("nco:Contact")
-        self.assertNotEqual(instances_before_restore, instances_before)
-
-        self.tracker.restore(self.BACKUP_FILE)
-        self.assertTrue(self.__is_test_instance_there())
-
-        # DB to the original state
-        self.__delete_test_instance()
-
-    def test_backup_11(self):
-        """
-        Backup ignores the file extension
-
-        1.Insert a contact.
-        2.Take backup of db in .jpg format.
-        3.Restore the db.
-        4.Search for the contact inserted.
-        """
-        BACKUP_JPG_EXT = "file://%s/tracker-test-backup.jpg" % (
-            cfg.TEST_TMP_DIR)
-
-        self.__insert_test_instance()
-
-        instances_before = self.tracker.count_instances("nco:Contact")
-
-        self.tracker.backup(BACKUP_JPG_EXT)
-
-        self.__delete_test_instance()
-        instances_now = self.tracker.count_instances("nco:Contact")
-        self.assertEquals(instances_before, instances_now + 1)
-
-        self.tracker.restore(BACKUP_JPG_EXT)
-        instances_after = self.tracker.count_instances("nco:Contact")
-        self.assertEquals(instances_before, instances_after)
-
-        # Restore the DB to the original state
-        self.__delete_test_instance()
+            1.Insert a contact.
+            2.Take backup of db.
+            4.Delete the database
+            5.Restore the db.
+            6.Search for the contact inserted.
+            """
+            self.__insert_test_instance()
+            instances_before = self.tracker.count_instances("nco:Contact")
+            self.tracker.backup(self.BACKUP_FILE)
+
+            self.system.tracker_store_stop_nicely()
+            self.system.tracker_store_remove_dbs()
+            self.system.tracker_store_remove_journal()
+            self.system.tracker_store_start()
+
+            instances_before_restore = self.tracker.count_instances(
+                "nco:Contact")
+            self.assertNotEqual(instances_before_restore, instances_before)
+
+            self.tracker.restore(self.BACKUP_FILE)
+            self.assertTrue(self.__is_test_instance_there())
+
+            self.__delete_test_instance()
+
+        def test_backup_08(self):
+            """
+            Restore after corrupting DB
+
+            1.Insert a contact.
+            2.Take backup of db.
+            5.Restore the db.
+            6.Search for the contact inserted.
+            """
+            self.__insert_test_instance()
+            instances_before = self.tracker.count_instances("nco:Contact")
+            self.tracker.backup(self.BACKUP_FILE)
+
+            self.system.tracker_store_stop_brutally()
+            self.system.tracker_store_corrupt_dbs()
+            self.system.tracker_store_remove_journal()
+            self.system.tracker_store_start()
+
+            instances_before_restore = self.tracker.count_instances(
+                "nco:Contact")
+            self.assertNotEqual(instances_before_restore, instances_before)
+
+            self.tracker.restore(self.BACKUP_FILE)
+            self.assertTrue(self.__is_test_instance_there())
+
+            # DB to the original state
+            self.__delete_test_instance()
+
+        def test_backup_11(self):
+            """
+            Backup ignores the file extension
+
+            1.Insert a contact.
+            2.Take backup of db in .jpg format.
+            3.Restore the db.
+            4.Search for the contact inserted.
+            """
+            BACKUP_JPG_EXT = "file://%s/tracker-test-backup.jpg" % (
+                cfg.TEST_TMP_DIR)
+
+            self.__insert_test_instance()
+
+            instances_before = self.tracker.count_instances("nco:Contact")
+
+            self.tracker.backup(BACKUP_JPG_EXT)
+
+            self.__delete_test_instance()
+            instances_now = self.tracker.count_instances("nco:Contact")
+            self.assertEquals(instances_before, instances_now + 1)
+
+            self.tracker.restore(BACKUP_JPG_EXT)
+            instances_after = self.tracker.count_instances("nco:Contact")
+            self.assertEquals(instances_before, instances_after)
+
+            # Restore the DB to the original state
+            self.__delete_test_instance()
 
 
 class JournalReplayTest (CommonTrackerStoreTest):
@@ -324,6 +324,3 @@ class JournalReplayTest (CommonTrackerStoreTest):
 
         self.tracker.update(
             "DELETE { <test://journal-replay/02> a rdfs:Resource. }")
-
-if __name__ == "__main__":
-    ut.main()
diff --git a/tests/functional-tests/store/testcase.py b/tests/functional-tests/store/testcase.py
new file mode 100644
index 0000000..f26960d
--- /dev/null
+++ b/tests/functional-tests/store/testcase.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2010, Nokia <ivan frade nokia com>
+# Copyright (C) 2014, Sam Thursfield <sam afuera me uk>
+#
+# This program 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.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+
+
+import unittest
+
+import common
+
+
+class TrackerStoreTest(unittest.TestCase):
+    '''Common superclass for tests that just require a fresh store running.
+
+    The tracker-store test suites run each test case in one instance of
+    tracker-store, unlike the other ones which run each test in a clean
+    sandbox. The store is robust enough that the tests don't really interfere
+    with each other, and it takes a few seconds for the store to start up fully
+    if the database is empty.
+
+    '''
+
+    @classmethod
+    def setUpClass(self):
+        sandbox = common.sandbox.TrackerSandbox()
+
+        self.store = common.helpers.StoreHelper()
+        self.store.start(sandbox.dbus_address)
+
+        self.tracker = self.system.store
+
+    @classmethod
+    def tearDownClass(self):
+        self.store.stop()


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]