From 38809bd51fe72a351de6eaf951df6495e6aa7541 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 24 Jun 2013 20:35:27 -0300 Subject: Return the deferred so that we can use it for other things --- src/leap/services/abstractbootstrapper.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/leap/services/abstractbootstrapper.py b/src/leap/services/abstractbootstrapper.py index f0937197..633d818d 100644 --- a/src/leap/services/abstractbootstrapper.py +++ b/src/leap/services/abstractbootstrapper.py @@ -157,3 +157,4 @@ class AbstractBootstrapper(QtCore.QObject): d.addErrback(self._errback, signal=sig) d.addCallback(self._gui_notify, signal=sig) d.addErrback(self._gui_errback) + return d -- cgit v1.2.3 From 900543f380ec6e002023be4d5210e0d93c74ee70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 24 Jun 2013 20:44:10 -0300 Subject: Add tests for AbstractBootstrapper --- src/leap/services/tests/__init__.py | 0 .../services/tests/test_abstractbootstrapper.py | 196 +++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 src/leap/services/tests/__init__.py create mode 100644 src/leap/services/tests/test_abstractbootstrapper.py diff --git a/src/leap/services/tests/__init__.py b/src/leap/services/tests/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/leap/services/tests/test_abstractbootstrapper.py b/src/leap/services/tests/test_abstractbootstrapper.py new file mode 100644 index 00000000..a9ee220f --- /dev/null +++ b/src/leap/services/tests/test_abstractbootstrapper.py @@ -0,0 +1,196 @@ +## -*- coding: utf-8 -*- +# test_abstrctbootstrapper.py +# Copyright (C) 2013 LEAP +# +# 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 3 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, see . + + +""" +Tests for the Abstract Boostrapper functionality +""" + +import mock + +from PySide import QtCore + +from nose.twistedtools import deferred + +from leap.services.abstractbootstrapper import AbstractBootstrapper +from leap.util.pyside_tests_helper import UsesQApplication, BasicPySlotCase + + +class TesterBootstrapper(AbstractBootstrapper): + test_signal1 = QtCore.Signal(dict) + test_signal2 = QtCore.Signal(dict) + test_signal3 = QtCore.Signal(dict) + + ERROR_MSG = "This is a test error msg" + + def _check_that_passes(self, *args): + pass + + def _second_check_that_passes(self, *args): + pass + + def _check_that_fails(self, *args): + raise Exception(self.ERROR_MSG) + + def run_checks_pass(self): + cb_chain = [ + (self._check_that_passes, self.test_signal1), + (self._second_check_that_passes, self.test_signal2), + ] + return self.addCallbackChain(cb_chain) + + def run_second_checks_pass(self): + cb_chain = [ + (self._check_that_passes, None), + ] + return self.addCallbackChain(cb_chain) + + def run_checks_fail(self): + cb_chain = [ + (self._check_that_passes, self.test_signal1), + (self._check_that_fails, self.test_signal2) + ] + return self.addCallbackChain(cb_chain) + + def run_second_checks_fail(self): + cb_chain = [ + (self._check_that_passes, self.test_signal1), + (self._check_that_fails, self.test_signal2), + (self._second_check_that_passes, self.test_signal1) + ] + return self.addCallbackChain(cb_chain) + + def run_third_checks_fail(self): + cb_chain = [ + (self._check_that_passes, self.test_signal1), + (self._check_that_fails, None) + ] + return self.addCallbackChain(cb_chain) + + +class AbstractBootstrapperTest(UsesQApplication, BasicPySlotCase): + def setUp(self): + UsesQApplication.setUp(self) + BasicPySlotCase.setUp(self) + + self.tbt = TesterBootstrapper() + self.called1 = self.called2 = 0 + + @deferred() + def test_all_checks_executed_once(self): + self.tbt._check_that_passes = mock.MagicMock() + self.tbt._second_check_that_passes = mock.MagicMock() + + d = self.tbt.run_checks_pass() + + def check(*args): + self.tbt._check_that_passes.assert_called_once_with() + self.tbt._second_check_that_passes.\ + assert_called_once_with(None) + + d.addCallback(check) + return d + + ####################################################################### + # Dummy callbacks that test the arguments expected from a certain + # signal and only allow being called once + + def cb1(self, *args): + if tuple(self.args1) == args: + self.called1 += 1 + else: + raise ValueError('Invalid arguments for callback') + + def cb2(self, *args): + if tuple(self.args2) == args: + self.called2 += 1 + else: + raise ValueError('Invalid arguments for callback') + + # + ####################################################################### + + def _check_cb12_once(self, *args): + self.assertEquals(self.called1, 1) + self.assertEquals(self.called2, 1) + + @deferred() + def test_emits_correct(self): + self.tbt.test_signal1.connect(self.cb1) + self.tbt.test_signal2.connect(self.cb2) + d = self.tbt.run_checks_pass() + + self.args1 = [{ + AbstractBootstrapper.PASSED_KEY: True, + AbstractBootstrapper.ERROR_KEY: "" + }] + + self.args2 = self.args1 + + d.addCallback(self._check_cb12_once) + return d + + @deferred() + def test_emits_failed(self): + self.tbt.test_signal1.connect(self.cb1) + self.tbt.test_signal2.connect(self.cb2) + d = self.tbt.run_checks_fail() + + self.args1 = [{ + AbstractBootstrapper.PASSED_KEY: True, + AbstractBootstrapper.ERROR_KEY: "" + }] + + self.args2 = [{ + AbstractBootstrapper.PASSED_KEY: False, + AbstractBootstrapper.ERROR_KEY: + TesterBootstrapper.ERROR_MSG + }] + + d.addCallback(self._check_cb12_once) + return d + + @deferred() + def test_emits_failed_and_stops(self): + self.tbt.test_signal1.connect(self.cb1) + self.tbt.test_signal2.connect(self.cb2) + self.tbt.test_signal3.connect(self.cb1) + d = self.tbt.run_second_checks_fail() + + self.args1 = [{ + AbstractBootstrapper.PASSED_KEY: True, + AbstractBootstrapper.ERROR_KEY: "" + }] + + self.args2 = [{ + AbstractBootstrapper.PASSED_KEY: False, + AbstractBootstrapper.ERROR_KEY: + TesterBootstrapper.ERROR_MSG + }] + + d.addCallback(self._check_cb12_once) + return d + + @deferred() + def test_failed_without_signal(self): + d = self.tbt.run_third_checks_fail() + return d + + @deferred() + def test_sucess_without_signal(self): + d = self.tbt.run_second_checks_pass() + return d -- cgit v1.2.3 From 77d9434c4a92528e13b008a50dfbcb5f2f1456a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 24 Jun 2013 22:45:04 -0300 Subject: pep8 fixes --- src/leap/util/keyring_helpers.py | 1 + src/leap/util/pyside_tests_helper.py | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/leap/util/keyring_helpers.py b/src/leap/util/keyring_helpers.py index b3dd0175..b815d385 100644 --- a/src/leap/util/keyring_helpers.py +++ b/src/leap/util/keyring_helpers.py @@ -26,6 +26,7 @@ OBSOLETE_KEYRINGS = [ keyring.backends.file.PlaintextKeyring ] + def has_keyring(): """ diff --git a/src/leap/util/pyside_tests_helper.py b/src/leap/util/pyside_tests_helper.py index a010934a..5c0eb8d6 100644 --- a/src/leap/util/pyside_tests_helper.py +++ b/src/leap/util/pyside_tests_helper.py @@ -15,14 +15,17 @@ except ImportError: else: has_gui = True + def adjust_filename(filename, orig_mod_filename): dirpath = os.path.dirname(os.path.abspath(orig_mod_filename)) return os.path.join(dirpath, filename) + class NoQtGuiError(Exception): def __init__(self): Exception.__init__(self, 'No QtGui found') + class BasicPySlotCase(object): '''Base class that tests python slots and signal emissions. @@ -75,7 +78,6 @@ if has_gui: del self.app super(UsesQApplication, self).tearDown() - class TimedQApplication(unittest.TestCase): '''Helper class with timed QApplication exec loop''' @@ -97,13 +99,14 @@ else: class UsesQApplication(unittest.TestCase): def setUp(self): raise NoQtGuiError() + class TimedQapplication(unittest.TestCase): def setUp(self): raise NoQtGuiError() - _core_instance = None + class UsesQCoreApplication(unittest.TestCase): '''Helper class for test cases that require an QCoreApplication Just connect or call self.exit_app_cb. When called, will ask -- cgit v1.2.3