~1chb1n/charms/trusty/nova-cloud-controller/15.10-stable-flip-tests-helper-syncs

« back to all changes in this revision

Viewing changes to unit_tests/test_utils.py

Check in start of py redux.

Show diffs side-by-side

added added

removed removed

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