~ionutbalutoiu/charms/trusty/neutron-api/next

23 by Liam Young
Added hooks unit tests
1
import logging
2
import unittest
3
import os
4
import yaml
5
6
from contextlib import contextmanager
7
from mock import patch, MagicMock
8
111.3.24 by David Ames
Fix unit tests
9
patch('charmhelpers.contrib.openstack.utils.set_os_workload_status').start()
10
patch('charmhelpers.core.hookenv.status_set').start()
11
23 by Liam Young
Added hooks unit tests
12
13
def load_config():
14
    '''
15
    Walk backwords from __file__ looking for config.yaml, load and return the
16
    'options' section'
17
    '''
18
    config = None
19
    f = __file__
20
    while config is None:
21
        d = os.path.dirname(f)
22
        if os.path.isfile(os.path.join(d, 'config.yaml')):
23
            config = os.path.join(d, 'config.yaml')
24
            break
25
        f = d
26
27
    if not config:
28
        logging.error('Could not find config.yaml in any parent directory '
29
                      'of %s. ' % file)
30
        raise Exception
31
32
    return yaml.safe_load(open(config).read())['options']
33
34
35
def get_default_config():
36
    '''
37
    Load default charm config from config.yaml return as a dict.
38
    If no default is set in config.yaml, its value is None.
39
    '''
40
    default_config = {}
41
    config = load_config()
42
    for k, v in config.iteritems():
43
        if 'default' in v:
44
            default_config[k] = v['default']
45
        else:
46
            default_config[k] = None
47
    return default_config
48
49
50
class CharmTestCase(unittest.TestCase):
51
52
    def setUp(self, obj, patches):
53
        super(CharmTestCase, self).setUp()
54
        self.patches = patches
55
        self.obj = obj
56
        self.test_config = TestConfig()
57
        self.test_relation = TestRelation()
58
        self.patch_all()
59
60
    def patch(self, method):
61
        _m = patch.object(self.obj, method)
62
        mock = _m.start()
63
        self.addCleanup(_m.stop)
64
        return mock
65
66
    def patch_all(self):
67
        for method in self.patches:
68
            setattr(self, method, self.patch(method))
69
70
71
class TestConfig(object):
72
73
    def __init__(self):
74
        self.config = get_default_config()
75
76
    def get(self, attr=None):
77
        if not attr:
78
            return self.get_all()
79
        try:
80
            return self.config[attr]
81
        except KeyError:
82
            return None
83
84
    def get_all(self):
85
        return self.config
86
87
    def set(self, attr, value):
88
            if attr not in self.config:
89
                raise KeyError
90
            self.config[attr] = value
91
92
93
class TestRelation(object):
94
95
    def __init__(self, relation_data={}):
96
        self.relation_data = relation_data
97
98
    def set(self, relation_data):
99
        self.relation_data = relation_data
100
26 by Liam Young
more tests, more coverage
101
    def get(self, attribute=None, unit=None, rid=None):
102
        if attribute is None:
23 by Liam Young
Added hooks unit tests
103
            return self.relation_data
26 by Liam Young
more tests, more coverage
104
        elif attribute in self.relation_data:
105
            return self.relation_data[attribute]
23 by Liam Young
Added hooks unit tests
106
        return None
107
108
109
@contextmanager
110
def patch_open():
111
    '''Patch open() to allow mocking both open() itself and the file that is
112
    yielded.
113
114
    Yields the mock for "open" and "file", respectively.'''
115
    mock_open = MagicMock(spec=open)
116
    mock_file = MagicMock(spec=file)
117
118
    @contextmanager
119
    def stub_open(*args, **kwargs):
120
        mock_open(*args, **kwargs)
121
        yield mock_file
122
123
    with patch('__builtin__.open', stub_open):
124
        yield mock_open, mock_file