summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Alejandro <ivanalejandro0@yahoo.com.ar>2013-06-25 16:53:36 -0300
committerIvan Alejandro <ivanalejandro0@yahoo.com.ar>2013-06-25 16:53:36 -0300
commit04a0fa945a0ec239960255bc2a0f2f01a5b4a224 (patch)
tree607027375791754a79b99838de5ace879ae6cd21
parenta5a51bcc1573d7b7cf281a4d8ac142705bd227d0 (diff)
parent77d9434c4a92528e13b008a50dfbcb5f2f1456a4 (diff)
Merge remote-tracking branch 'chiiph/feature/add_abstractbootstrapper_test' into develop
-rw-r--r--src/leap/services/abstractbootstrapper.py1
-rw-r--r--src/leap/services/tests/__init__.py0
-rw-r--r--src/leap/services/tests/test_abstractbootstrapper.py196
-rw-r--r--src/leap/util/keyring_helpers.py1
-rw-r--r--src/leap/util/pyside_tests_helper.py7
5 files changed, 203 insertions, 2 deletions
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
diff --git a/src/leap/services/tests/__init__.py b/src/leap/services/tests/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/src/leap/services/tests/__init__.py
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 <http://www.gnu.org/licenses/>.
+
+
+"""
+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
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