From c2786de7d2d09d600fa516f93cc1a1f851f0d705 Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 27 Aug 2012 05:13:29 +0900 Subject: make provider-fetch tests pass test provider-definition dump functions. refactored the set-temp-to-home methods to setUpClass separate provider-fetch tests on different testcases (so they actually call to requests). --- src/leap/base/config.py | 18 +++++- src/leap/base/exceptions.py | 2 + src/leap/base/providers.py | 33 ++++++++--- src/leap/base/tests/test_config.py | 100 +++++++++++++++++++++++++--------- src/leap/base/tests/test_providers.py | 1 + src/leap/testing/basetest.py | 6 +- 6 files changed, 124 insertions(+), 36 deletions(-) create mode 100644 src/leap/base/exceptions.py (limited to 'src') diff --git a/src/leap/base/config.py b/src/leap/base/config.py index dbd2e2c0..8455f9de 100644 --- a/src/leap/base/config.py +++ b/src/leap/base/config.py @@ -12,13 +12,15 @@ import os logger = logging.getLogger(name=__name__) logger.setLevel('DEBUG') +from leap.base import exceptions from leap.util.fileutil import (mkdir_p) class BaseLeapConfig(object): slug = None - # XXX we have to enforce that we have a slug (via interface) + # XXX we have to enforce that every derived class + # has a slug (via interface) # get property getter that raises NI.. def save(self): @@ -58,6 +60,9 @@ class JSONLeapConfig(BaseLeapConfig): def save(self, to=None): if to is None: to = self.filename + folder, filename = os.path.split(to) + if folder and not os.path.isdir(folder): + mkdir_p(folder) self._config.serialize(to) def load(self, fromfile=None): @@ -175,11 +180,17 @@ def get_config_json(config_file=None): mkdir_p(dpath) with open(fpath, 'wb') as configfile: configfile.flush() - return json.load(open(fpath)) + try: + return json.load(open(fpath)) + except ValueError: + raise exceptions.MissingConfigFileError else: #TODO: add validity checks of file - return json.load(open(config_file)) + try: + return json.load(open(config_file)) + except IOError: + raise exceptions.MissingConfigFileError def get_definition_file(url=None): @@ -214,6 +225,7 @@ class Configuration(object): """ def __init__(self, provider_url=None): try: + #requests.get('foo') self.providers = {} self.error = False provider_file = self.check_and_get_definition_file(provider_url) diff --git a/src/leap/base/exceptions.py b/src/leap/base/exceptions.py new file mode 100644 index 00000000..93dde385 --- /dev/null +++ b/src/leap/base/exceptions.py @@ -0,0 +1,2 @@ +class MissingConfigFileError(Exception): + pass diff --git a/src/leap/base/providers.py b/src/leap/base/providers.py index 6fc050a0..1f6ab54b 100644 --- a/src/leap/base/providers.py +++ b/src/leap/base/providers.py @@ -1,3 +1,4 @@ +"""all dealing with leap-providers: definition files, updating""" import configuration from leap.base.config import JSONLeapConfig @@ -6,15 +7,24 @@ from leap.base.config import JSONLeapConfig # hacking in progress: # Specs are instances of configuration.Configuration class +# -yeah, that's an external app, not ours- # and have to carry an options attr. # # Configs have: -# - slug -# - definition +# - a slug (from where a filename/folder is derived) +# - a spec (for validation and defaults). + +# all config objects, as BaseConfig derived, implment basic +# useful methods: +# - save +# - load +# - get_config (returns a optparse.OptionParser object) # TODO: -# - have a good type cast repertory -# - raise validation errors? +# - have a good type cast repertory (uris, version, hashes...) +# - raise validation errors +# - multilingual objects + ########################################################## @@ -76,9 +86,17 @@ class LeapProviderDefinition(JSONLeapConfig): class LeapProvider(object): - # XXX ??? - # do we need this? - # can we hook here the network fetching stuff? + # bring slug here (property) + # constructor: pass name + + # constructor: init definition class + # (__cls__.__name__ + Definition) + # initializes a JSONLeapConfig with slug and + # initializes also cls.name + Spec + + # and Abstract this thing out! + + # how can we hook here the network fetching stuff? # maybe (bstorming a little bit): # config = LeapProviderDefinition @@ -87,5 +105,6 @@ class LeapProvider(object): class LeapProviderSet(object): + # we gather them from the filesystem def __init__(self): self.count = 0 diff --git a/src/leap/base/tests/test_config.py b/src/leap/base/tests/test_config.py index c5231de2..73b0f32c 100644 --- a/src/leap/base/tests/test_config.py +++ b/src/leap/base/tests/test_config.py @@ -1,12 +1,15 @@ +import json import os import platform import socket -import tempfile +#import tempfile import mock import requests from leap.base import config +from leap.base import exceptions +from leap.util.fileutil import mkdir_p from leap.testing.basetest import BaseLeapTest @@ -18,29 +21,60 @@ except ImportError: _system = platform.system() -class DefinitionTestCase(BaseLeapTest): +class ProviderTest(BaseLeapTest): + # override per test fixtures + def setUp(self): + pass + + def tearDown(self): + pass + + +class BareHomeTestCase(ProviderTest): + + __name__ = "provider_config_tests" + + def test_should_raise_if_missing_eip_json(self): + with self.assertRaises(exceptions.MissingConfigFileError): + config.get_config_json(os.path.join(self.home, 'eip.json')) + + +class ProviderDefinitionTestCase(ProviderTest): # XXX See how to merge with test_providers # -- kali 2012-08-24 00:38 __name__ = "provider_config_tests" def setUp(self): - self.old_home = os.environ['HOME'] - self.home = tempfile.mkdtemp() - os.environ['HOME'] = self.home - pass - - #Not correct removing the test directories but will be refactor out - #with kali's new test classes - def tearDown(self): - os.environ['HOME'] = self.old_home - pass + # dump a sample eip file + # XXX Move to Use EIP Spec Instead!!! + EIP_JSON = { + "provider": "testprovider.org", + "transport": "openvpn", + "openvpn_protocol": "tcp", + "openvpn_port": "80", + "openvpn_ca_certificate": "~/.config/leap/testprovider.org/" + "keys/ca/testprovider-ca-cert-" + "2013-01-01.pem", + "openvpn_client_certificate": "~/.config/leap/testprovider.org/" + "keys/client/openvpn-2012-09-31.pem", + "connect_on_login": True, + "block_cleartext_traffic": True, + "primary_gateway": "usa_west", + "secondary_gateway": "france", + "management_password": "oph7Que1othahwiech6J" + } + path = os.path.join(self.home, '.config', 'leap') + mkdir_p(path) + with open(os.path.join(path, 'eip.json'), 'w') as fp: + json.dump(EIP_JSON, fp) def test_complete_file(self): with mock.patch.object(requests, "get") as mock_method: mock_method.return_value.status_code = 200 mock_method.return_value.json = { + #XXX get from providers template u'api_uri': u'https://api.testprovider.org/', u'api_version': u'0.1.0', u'ca_cert': u'8aab80ae4326fd30721689db813733783fe0bd7e', @@ -56,23 +90,46 @@ class DefinitionTestCase(BaseLeapTest): cf = config.Configuration("http://localhost/") self.assertIn('default', cf.providers) +# +# provider fetch tests block +# + +# these tests below should move to wherever +# we put the fetcher for provider files and related stuff. +# TODO: +# - We're instantiating a ProviderTest because we're doing the home wipeoff +# on setUpClass instead of the setUp (for speedup of the general cases). + +# We really should be testing all of them in the same testCase, and +# doing an extra wipe of the tempdir... but be careful!!!! do not mess with +# os.environ home more than needed... that could potentially bite! + + +class ProviderFetchConError(ProviderTest): def test_connection_error(self): with mock.patch.object(requests, "get") as mock_method: mock_method.side_effect = requests.ConnectionError cf = config.Configuration() self.assertIsInstance(cf.error, str) + +class ProviderFetchHttpError(ProviderTest): def test_file_not_found(self): with mock.patch.object(requests, "get") as mock_method: mock_method.side_effect = requests.HTTPError cf = config.Configuration() self.assertIsInstance(cf.error, str) + +class ProviderFetchInvalidUrl(ProviderTest): def test_invalid_url(self): cf = config.Configuration("ht") self.assertTrue(cf.error) +# end provider fetch tests + + class ConfigHelperFunctions(BaseLeapTest): __name__ = "config_helper_tests" @@ -83,12 +140,7 @@ class ConfigHelperFunctions(BaseLeapTest): def tearDown(self): pass - # # tests - # - - # XXX fixme! /home/user should - # be replaced for proper home lookup. @unittest.skipUnless(_system == "Linux", "linux only") def test_lin_get_config_file(self): @@ -98,8 +150,9 @@ class ConfigHelperFunctions(BaseLeapTest): self.assertEqual( config.get_config_file( 'test', folder="foo/bar"), - '/home/%s/.config/leap/foo/bar/test' % - config.get_username()) + os.path.expanduser( + '~/.config/leap/foo/bar/test') + ) @unittest.skipUnless(_system == "Darwin", "mac only") def test_mac_get_config_file(self): @@ -130,10 +183,7 @@ class ConfigHelperFunctions(BaseLeapTest): """ self.assertEqual( config.get_config_dir(), - #XXX not correct!!! - #hardcoded home - '/home/%s/.config/leap' % - self.get_username()) + os.path.expanduser('~/.config/leap')) @unittest.skipUnless(_system == "Darwin", "mac only") def test_mac_get_config_dir(self): @@ -158,8 +208,8 @@ class ConfigHelperFunctions(BaseLeapTest): """ self.assertEqual( config.get_default_provider_path(), - '/home/%s/.config/leap/providers/default/' % - config.get_username()) + os.path.expanduser('~/.config/leap/providers/default/') + ) # validate ip diff --git a/src/leap/base/tests/test_providers.py b/src/leap/base/tests/test_providers.py index 2f029930..544355cc 100644 --- a/src/leap/base/tests/test_providers.py +++ b/src/leap/base/tests/test_providers.py @@ -48,6 +48,7 @@ class TestLeapProviderDefinition(BaseLeapTest): # XXX THIS TEST SHOULD MOVE TO test_baseconfig self.definition.save() filename = self.definition.filename + self.assertTrue(os.path.isfile(filename)) deserialized = json.load(open(filename, 'rb')) self.assertEqual(deserialized, EXPECTED_DEFAULT_CONFIG) diff --git a/src/leap/testing/basetest.py b/src/leap/testing/basetest.py index a55b0525..8d9264f1 100644 --- a/src/leap/testing/basetest.py +++ b/src/leap/testing/basetest.py @@ -20,15 +20,19 @@ class BaseLeapTest(unittest.TestCase): @classmethod def setUpClass(cls): cls.old_path = os.environ['PATH'] - cls.tempdir = tempfile.mkdtemp() + cls.old_home = os.environ['HOME'] + cls.tempdir = tempfile.mkdtemp(prefix="leap_tests-") + cls.home = cls.tempdir bin_tdir = os.path.join( cls.tempdir, 'bin') os.environ["PATH"] = bin_tdir + os.environ["HOME"] = cls.tempdir @classmethod def tearDownClass(cls): os.environ["PATH"] = cls.old_path + os.environ["HOME"] = cls.old_home shutil.rmtree(cls.tempdir) # you have to override these methods -- cgit v1.2.3