コード例 #1
0
class TestBackendTomboy(unittest.TestCase):
    """ Tests for the tomboy backend """

    def setUp(self):
        thread_tomboy = threading.Thread(target=self.spawn_fake_tomboy_server)
        thread_tomboy.start()
        thread_tomboy.join()
        # only the test process should go further, the dbus server one should
        # stop here
        if not PID_TOMBOY:
            return
        # we create a custom dictionary listening to the server, and register
        # it in GTG.
        additional_dic = {}
        additional_dic["use this fake connection instead"] = (
            FakeTomboy.BUS_NAME, FakeTomboy.BUS_PATH, FakeTomboy.BUS_INTERFACE)
        additional_dic[GenericBackend.KEY_ATTACHED_TAGS] = \
            [GenericBackend.ALLTASKS_TAG]
        additional_dic[GenericBackend.KEY_DEFAULT_BACKEND] = True
        dic = BackendFactory().get_new_backend_dict('backend_tomboy',
                                                    additional_dic)
        self.datastore = DataStore()
        self.backend = self.datastore.register_backend(dic)
        # waiting for the "start_get_tasks" to settle
        time.sleep(1)
        # we create a dbus session to speak with the server
        self.bus = dbus.SessionBus()
        obj = self.bus.get_object(FakeTomboy.BUS_NAME, FakeTomboy.BUS_PATH)
        self.tomboy = dbus.Interface(obj, FakeTomboy.BUS_INTERFACE)

    def spawn_fake_tomboy_server(self):
        # the fake tomboy server has to be in a different process,
        # otherwise it will lock on the GIL.
        # For details, see
        # http://lists.freedesktop.org/archives/dbus/2007-January/006921.html

        # we use a lockfile to make sure the server is running before we start
        # the test
        global PID_TOMBOY
        lockfile_fd, lockfile_path = tempfile.mkstemp()
        PID_TOMBOY = os.fork()
        if PID_TOMBOY:
            # we wait in polling that the server has been started
            while True:
                try:
                    fd = os.open(lockfile_path,
                                 os.O_CREAT | os.O_EXCL | os.O_RDWR)
                except OSError as e:
                    if e.errno != errno.EEXIST:
                        raise
                    time.sleep(0.3)
                    continue
                os.close(fd)
                break
        else:
            FakeTomboy()
            os.close(lockfile_fd)
            os.unlink(lockfile_path)

    def tearDown(self):
        if not PID_TOMBOY:
            return
        self.datastore.save(quit=True)
        time.sleep(0.5)
        self.tomboy.FakeQuit()
        # FIXME: self.bus.close()
        os.kill(PID_TOMBOY, signal.SIGKILL)
        os.waitpid(PID_TOMBOY, 0)

    def test_everything(self):
        # we cannot use separate test functions because we only want a single
        # FakeTomboy dbus server running
        if not PID_TOMBOY:
            return
        for function in dir(self):
            if function.startswith("TEST_"):
                getattr(self, function)()
                self.tomboy.Reset()
                for tid in self.datastore.get_all_tasks():
                    self.datastore.request_task_deletion(tid)
                time.sleep(0.1)

    def TEST_processing_tomboy_notes(self):
        self.backend.set_attached_tags([GenericBackend.ALLTASKS_TAG])
        # adding a note
        note = self.tomboy.CreateNamedNote(str(uuid.uuid4()))
        self.backend._process_tomboy_note(note)
        self.assertEqual(len(self.datastore.get_all_tasks()), 1)
        tid = self.backend.sync_engine.sync_memes.get_local_id(note)
        task = self.datastore.get_task(tid)
        # re-adding that (should not change anything)
        self.backend._process_tomboy_note(note)
        self.assertEqual(len(self.datastore.get_all_tasks()), 1)
        self.assertEqual(
            self.backend.sync_engine.sync_memes.get_local_id(note), tid)
        # removing the note and updating gtg
        self.tomboy.DeleteNote(note)
        self.backend.set_task(task)
        self.assertEqual(len(self.datastore.get_all_tasks()), 0)

    def TEST_set_task(self):
        self.backend.set_attached_tags([GenericBackend.ALLTASKS_TAG])
        # adding a task
        task = self.datastore.requester.new_task()
        task.set_title("title")
        self.backend.set_task(task)
        self.assertEqual(len(self.tomboy.ListAllNotes()), 1)
        note = self.tomboy.ListAllNotes()[0]
        self.assertEqual(str(self.tomboy.GetNoteTitle(note)), task.get_title())
        # re-adding that (should not change anything)
        self.backend.set_task(task)
        self.assertEqual(len(self.tomboy.ListAllNotes()), 1)
        self.assertEqual(note, self.tomboy.ListAllNotes()[0])
        # removing the task and updating tomboy
        self.datastore.request_task_deletion(task.get_id())
        self.backend._process_tomboy_note(note)
        self.assertEqual(len(self.tomboy.ListAllNotes()), 0)

    def TEST_update_newest(self):
        self.backend.set_attached_tags([GenericBackend.ALLTASKS_TAG])
        task = self.datastore.requester.new_task()
        task.set_title("title")
        self.backend.set_task(task)
        note = self.tomboy.ListAllNotes()[0]
        gtg_modified = task.get_modified()
        tomboy_modified = self._modified_string_to_datetime(
            self.tomboy.GetNoteChangeDate(note))
        # no-one updated, nothing should happen
        self.backend.set_task(task)
        self.assertEqual(gtg_modified, task.get_modified())
        self.assertEqual(tomboy_modified,
                         self._modified_string_to_datetime(
                         self.tomboy.GetNoteChangeDate(note)))
        # we update the GTG task
        UPDATED_GTG_TITLE = "UPDATED_GTG_TITLE"
        task.set_title(UPDATED_GTG_TITLE)
        self.backend.set_task(task)
        self.assertTrue(gtg_modified < task.get_modified())
        self.assertTrue(tomboy_modified <=
                        self._modified_string_to_datetime(
                        self.tomboy.GetNoteChangeDate(note)))
        self.assertEqual(task.get_title(), UPDATED_GTG_TITLE)
        self.assertEqual(self.tomboy.GetNoteTitle(note), UPDATED_GTG_TITLE)
        gtg_modified = task.get_modified()
        tomboy_modified = self._modified_string_to_datetime(
            self.tomboy.GetNoteChangeDate(note))
        # we update the TOMBOY task
        UPDATED_TOMBOY_TITLE = "UPDATED_TOMBOY_TITLE"
        # the resolution of tomboy notes changed time is 1 second, so we need
        # to wait. This *shouldn't* be needed in the actual code because
        # tomboy signals are always a few seconds late.
        time.sleep(1)
        self.tomboy.SetNoteContents(note, UPDATED_TOMBOY_TITLE)
        self.backend._process_tomboy_note(note)
        self.assertTrue(gtg_modified <= task.get_modified())
        self.assertTrue(tomboy_modified <=
                        self._modified_string_to_datetime(
                        self.tomboy.GetNoteChangeDate(note)))
        self.assertEqual(task.get_title(), UPDATED_TOMBOY_TITLE)
        self.assertEqual(self.tomboy.GetNoteTitle(note), UPDATED_TOMBOY_TITLE)

    def TEST_processing_tomboy_notes_with_tags(self):
        self.backend.set_attached_tags(['@a'])
        # adding a not syncable note
        note = self.tomboy.CreateNamedNote("title" + str(uuid.uuid4()))
        self.backend._process_tomboy_note(note)
        self.assertEqual(len(self.datastore.get_all_tasks()), 0)
        # re-adding that (should not change anything)
        self.backend._process_tomboy_note(note)
        self.assertEqual(len(self.datastore.get_all_tasks()), 0)
        # adding a tag to that note
        self.tomboy.SetNoteContents(note, "something with @a")
        self.backend._process_tomboy_note(note)
        self.assertEqual(len(self.datastore.get_all_tasks()), 1)
        # removing the tag and resyncing
        self.tomboy.SetNoteContents(note, "something with no tags")
        self.backend._process_tomboy_note(note)
        self.assertEqual(len(self.datastore.get_all_tasks()), 0)
        # adding a syncable note
        note = self.tomboy.CreateNamedNote("title @a" + str(uuid.uuid4()))
        self.backend._process_tomboy_note(note)
        self.assertEqual(len(self.datastore.get_all_tasks()), 1)
        tid = self.backend.sync_engine.sync_memes.get_local_id(note)
        task = self.datastore.get_task(tid)
        # re-adding that (should not change anything)
        self.backend._process_tomboy_note(note)
        self.assertEqual(len(self.datastore.get_all_tasks()), 1)
        self.assertEqual(
            self.backend.sync_engine.sync_memes.get_local_id(note), tid)
        # removing the note and updating gtg
        self.tomboy.DeleteNote(note)
        self.backend.set_task(task)
        self.assertEqual(len(self.datastore.get_all_tasks()), 0)

    def TEST_set_task_with_tags(self):
        self.backend.set_attached_tags(['@a'])
        # adding a not syncable task
        task = self.datastore.requester.new_task()
        task.set_title("title")
        self.backend.set_task(task)
        self.assertEqual(len(self.tomboy.ListAllNotes()), 0)
        # making that task  syncable
        task.set_title("something else")
        task.add_tag("@a")
        self.backend.set_task(task)
        self.assertEqual(len(self.tomboy.ListAllNotes()), 1)
        note = self.tomboy.ListAllNotes()[0]
        self.assertEqual(str(self.tomboy.GetNoteTitle(note)), task.get_title())
        # re-adding that (should not change anything)
        self.backend.set_task(task)
        self.assertEqual(len(self.tomboy.ListAllNotes()), 1)
        self.assertEqual(note, self.tomboy.ListAllNotes()[0])
        # removing the syncable property and updating tomboy
        task.remove_tag("@a")
        self.backend.set_task(task)
        self.assertEqual(len(self.tomboy.ListAllNotes()), 0)

    def TEST_multiple_task_same_title(self):
        self.backend.set_attached_tags(['@a'])
        how_many_tasks = int(math.ceil(20 * random.random()))
        for iteration in range(0, how_many_tasks):
            task = self.datastore.requester.new_task()
            task.set_title("title")
            task.add_tag('@a')
            self.backend.set_task(task)
        self.assertEqual(len(self.tomboy.ListAllNotes()), how_many_tasks)

    def _modified_string_to_datetime(self, modified_string):
        return datetime.fromtimestamp(modified_string)