diff options
| -rw-r--r-- | CHANGELOG | 7 | ||||
| -rw-r--r-- | setup.py | 2 | ||||
| -rw-r--r-- | src/leap/common/__init__.py | 2 | ||||
| -rw-r--r-- | src/leap/common/check.py | 9 | ||||
| -rw-r--r-- | src/leap/common/config/tests/test_baseconfig.py | 268 | ||||
| -rw-r--r-- | src/leap/common/testing/basetest.py | 3 | ||||
| -rw-r--r-- | src/leap/common/tests/test_check.py | 52 | 
7 files changed, 335 insertions, 8 deletions
| @@ -1,4 +1,9 @@ -0.2.2 Jun 28: +0.2.6 Jul 12: +  o Improve leap_assert so that it only prints the traceback from the +    leap_assert call up. Closes #2895 +  o Add OSX temp directories to the basetests class. + +0.2.5 Jun 28:    o Bugfix: use the provider's default language as default      string. Also take care (and note) a possible case with a      problematic provider misconfiguration. Closes #3029. @@ -56,7 +56,7 @@ setup(      name='leap.common',      # If you change version, do it also in      # src/leap/common/__init__.py -    version='0.2.5', +    version='0.2.6',      url='https://leap.se/',      license='GPLv3+',      author='The LEAP Encryption Access Project', diff --git a/src/leap/common/__init__.py b/src/leap/common/__init__.py index 2b30715..abeff0f 100644 --- a/src/leap/common/__init__.py +++ b/src/leap/common/__init__.py @@ -16,4 +16,4 @@ except ImportError:  __all__ = ["certs", "check", "files", "events"] -__version__ = "0.2.5" +__version__ = "0.2.6" diff --git a/src/leap/common/check.py b/src/leap/common/check.py index a2d39a6..e6b0b52 100644 --- a/src/leap/common/check.py +++ b/src/leap/common/check.py @@ -18,7 +18,6 @@  Set of functions to help checking situations  """ -import inspect  import logging  import traceback @@ -39,9 +38,11 @@ def leap_assert(condition, message=""):      if not condition:          logger.error("Bug: %s" % (message,))          try: -            frame = inspect.currentframe() -            stack_trace = traceback.format_stack(frame) -            logger.error(''.join(stack_trace)) +            for formatted_line in traceback.format_list( +                    traceback.extract_stack()[:-1]): +                for line in formatted_line.split("\n"): +                    if len(line.strip()) > 0: +                        logger.error(line)          except Exception as e:              logger.error("Bug in leap_assert: %r" % (e,))      assert condition, message diff --git a/src/leap/common/config/tests/test_baseconfig.py b/src/leap/common/config/tests/test_baseconfig.py new file mode 100644 index 0000000..8a2915e --- /dev/null +++ b/src/leap/common/config/tests/test_baseconfig.py @@ -0,0 +1,268 @@ +# -*- coding: utf-8 -*- +# test_baseconfig.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 baseconfig +""" +import json +import unittest +import copy + +from leap.common.config.baseconfig import BaseConfig, LocalizedKey +from leap.common.testing.basetest import BaseLeapTest + +from mock import Mock + +# reduced eipconfig sample config +sample_config = { +    "gateways": [ +    { +        "capabilities": { +            "adblock": False, +            "transport": ["openvpn"], +            "user_ips": False +        }, +        "host": "host.dev.example.org", +    }, { +        "capabilities": { +            "adblock": False, +            "transport": ["openvpn"], +            "user_ips": False +        }, +        "host": "host2.dev.example.org", +    } +    ], +    "default_language": "en", +    "languages": [ +        "en", +        "es" +    ], +    "name": { +        "en": "Baseconfig testing environment", +        "es": "Entorno de pruebas de Baseconfig" +    }, +    "serial": 1, +    "version": 1 +} + +# reduced eipconfig.spec version +sample_spec = { +    'description': 'sample eip service config', +    'type': 'object', +    'properties': { +        'serial': { +            'type': int, +            'default': 1, +            'required': ["True"] +        }, +        'version': { +            'type': int, +            'default': 1, +            'required': ["True"] +        }, +        "default_language": { +            'type': unicode, +            'default': 'en' +        }, +        'languages': { +            'type': list, +            'default': ['en'] +        }, +        'name': { +            'type': dict, +            'format': 'translatable', +            'default': {u'en': u'Test Provider'} +        }, +        'gateways': { +            'type': list, +            'default': [ +                {"capabilities": { +                    "adblock": True, +                    "transport": ["openvpn"], +                    "user_ips": False}, +                 "host": "location.example.org", +                 }] +        }, +    } +} + + +class TestConfig(BaseConfig): +    """ +    BaseConfig implementation for testing purposes only. +    """ +    def get_gateways(self): +        return self._safe_get_value("gateways") + +    def get_serial(self): +        return self._safe_get_value("serial") + +    def get_version(self): +        return self._safe_get_value("version") + +    def _get_spec(self): +        return sample_spec + +    def get_default_language(self): +        return self._safe_get_value("default_language") + +    @LocalizedKey +    def get_name(self): +        return self._safe_get_value("name") + + +class BaseConfigTest(BaseLeapTest): + +    def setUp(self): +        pass + +    def tearDown(self): +        pass + +    def _write_config(self, data): +        """ +        Helper to write some data to a temp config file. + +        :param data: data to be used to save in the config file. +        :data type: dict (valid json) +        """ +        self.config_file = self.get_tempfile("config.json") +        conf = open(self.config_file, "w") +        conf.write(json.dumps(data)) +        conf.close() + +    def _get_config(self, fromfile=False, data=sample_config): +        """ +        Helper that returns a TestConfig object using the data parameter +        or a sample data. + +        :param fromfile: sets if we should use a file or a string +        :fromfile type: bool +        :param data: sets the data to be used to load in the TestConfig object +        :data type: dict (valid json) +        :rtype: TestConfig +        """ +        config = TestConfig() + +        loaded = False +        if fromfile: +            self._write_config(data) +            loaded = config.load(self.config_file, relative=False) +        else: +            json_string = json.dumps(data) +            loaded = config.load(data=json_string) + +        if not loaded: +            return None + +        return config + +    def test_loads_from_file(self): +        config = self._get_config(fromfile=True) +        self.assertIsNotNone(config) + +    def test_loads_from_data(self): +        config = self._get_config() +        self.assertIsNotNone(config) + +    def test_load_valid_config_from_file(self): +        config = self._get_config(fromfile=True) +        self.assertIsNotNone(config) + +        self.assertEqual(config.get_version(), sample_config["version"]) +        self.assertEqual(config.get_serial(), sample_config["serial"]) +        self.assertEqual(config.get_gateways(), sample_config["gateways"]) + +    def test_load_valid_config_from_data(self): +        config = self._get_config() +        self.assertIsNotNone(config) + +        self.assertEqual(config.get_version(), sample_config["version"]) +        self.assertEqual(config.get_serial(), sample_config["serial"]) +        self.assertEqual(config.get_gateways(), sample_config["gateways"]) + +    def test_safe_get_value_no_config(self): +        config = TestConfig() + +        with self.assertRaises(AssertionError): +            config.get_version() + +    def test_safe_get_value_non_existent_value(self): +        config = self._get_config() + +        self.assertIsNone(config._safe_get_value('non-existent-value')) + +    def test_loaded(self): +        config = self._get_config() +        self.assertTrue(config.loaded()) + +    def test_not_loaded(self): +        config = TestConfig() +        self.assertFalse(config.loaded()) + +    def test_save_and_load(self): +        config = self._get_config() +        config.get_path_prefix = Mock(return_value=self.tempdir) +        config_file = 'test_config.json' +        self.assertTrue(config.save([config_file])) + +        config_saved = TestConfig() +        config_file_path = self.get_tempfile(config_file) +        self.assertTrue(config_saved.load(config_file_path, relative=False)) + +        self.assertEqual(config.get_version(), config_saved.get_version()) +        self.assertEqual(config.get_serial(), config_saved.get_serial()) +        self.assertEqual(config.get_gateways(), config_saved.get_gateways()) + +    def test_localizations(self): +        conf = self._get_config() + +        self.assertEqual(conf.get_name(lang='en'), sample_config['name']['en']) +        self.assertEqual(conf.get_name(lang='es'), sample_config['name']['es']) + +    def _localized_config(self, lang): +        """ +        Helper to change default language of the provider config. +        """ +        conf = copy.deepcopy(sample_config) +        conf['default_language'] = lang +        json_string = json.dumps(conf) +        config = TestConfig() +        config.load(data=json_string) + +        return config + +    def test_default_localization1(self): +        default_language = sample_config['languages'][0] +        config = self._localized_config(default_language) + +        default_name = sample_config['name'][default_language] + +        self.assertEqual(config.get_name(lang='xx'), default_name) +        self.assertEqual(config.get_name(), default_name) + +    def test_default_localization2(self): +        default_language = sample_config['languages'][1] +        config = self._localized_config(default_language) + +        default_name = sample_config['name'][default_language] + +        self.assertEqual(config.get_name(lang='xx'), default_name) +        self.assertEqual(config.get_name(), default_name) + + +if __name__ == "__main__": +    unittest.main(verbosity=2) diff --git a/src/leap/common/testing/basetest.py b/src/leap/common/testing/basetest.py index 8890bf9..54826d5 100644 --- a/src/leap/common/testing/basetest.py +++ b/src/leap/common/testing/basetest.py @@ -68,7 +68,8 @@ class BaseLeapTest(unittest.TestCase):          # safety check! please do not wipe my home...          # XXX needs to adapt to non-linuces          leap_assert( -            cls.tempdir.startswith('/tmp/leap_tests-'), +            cls.tempdir.startswith('/tmp/leap_tests-') or +            cls.tempdir.startswith('/var/folder'),              "beware! tried to remove a dir which does not "              "live in temporal folder!")          shutil.rmtree(cls.tempdir) diff --git a/src/leap/common/tests/test_check.py b/src/leap/common/tests/test_check.py new file mode 100644 index 0000000..6ce8493 --- /dev/null +++ b/src/leap/common/tests/test_check.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- +# test_check.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: +    * leap/common/check.py +""" +try: +    import unittest2 as unittest +except ImportError: +    import unittest + +import mock + +from leap.common import check + +class CheckTests(unittest.TestCase): +    def test_raises_on_false_condition(self): +        with self.assertRaises(AssertionError): +            check.leap_assert(False, "Condition") + +    def test_raises_on_none_condition(self): +        with self.assertRaises(AssertionError): +            check.leap_assert(None, "Condition") + +    def test_suceeds_with_good_condition(self): +        check.leap_assert(True, "") + +    def test_raises_on_bad_type(self): +        with self.assertRaises(AssertionError): +            check.leap_assert_type(42, str) + +    def test_succeeds_on_good_type(self): +        check.leap_assert_type(42, int) + +    @mock.patch("traceback.extract_stack", mock.MagicMock(return_value=None)) +    def test_does_not_raise_on_bug(self): +        with self.assertRaises(AssertionError): +            check.leap_assert(False, "") | 
