~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_decorators.py

MergeĀ fromĀ old-hpss-branch-implementation-test.

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import inspect
21
21
 
22
22
from bzrlib import decorators
23
 
from bzrlib.decorators import needs_read_lock, needs_write_lock
24
23
from bzrlib.tests import TestCase
25
24
 
26
25
 
27
 
class DecoratorSample(object):
28
 
    """Sample class that uses decorators.
 
26
def create_decorator_sample(style, except_in_unlock=False):
 
27
    """Create a DecoratorSample object, using specific lock operators.
29
28
 
30
 
    Log when requests go through lock_read()/unlock() or lock_write()/unlock.
 
29
    :param style: The type of lock decorators to use (fast/pretty/None)
 
30
    :param except_in_unlock: If True, raise an exception during unlock
 
31
    :return: An instantiated DecoratorSample object.
31
32
    """
32
33
 
33
 
    def __init__(self):
34
 
        self.actions = []
35
 
 
36
 
    def lock_read(self):
37
 
        self.actions.append('lock_read')
38
 
 
39
 
    def lock_write(self):
40
 
        self.actions.append('lock_write')
41
 
 
42
 
    def unlock(self):
43
 
        self.actions.append('unlock')
44
 
 
45
 
    @needs_read_lock
46
 
    def frob(self):
47
 
        """Frob the sample object"""
48
 
        self.actions.append('frob')
49
 
 
50
 
    @needs_write_lock
51
 
    def bank(self, bar, biz=None):
52
 
        """Bank the sample, but using bar and biz."""
53
 
        self.actions.append(('bank', bar, biz))
 
34
    if style is None:
 
35
        # Default
 
36
        needs_read_lock = decorators.needs_read_lock
 
37
        needs_write_lock = decorators.needs_write_lock
 
38
    elif style == 'pretty':
 
39
        needs_read_lock = decorators._pretty_needs_read_lock
 
40
        needs_write_lock = decorators._pretty_needs_write_lock
 
41
    else:
 
42
        needs_read_lock = decorators._fast_needs_read_lock
 
43
        needs_write_lock = decorators._fast_needs_write_lock
 
44
 
 
45
    class DecoratorSample(object):
 
46
        """Sample class that uses decorators.
 
47
 
 
48
        Log when requests go through lock_read()/unlock() or
 
49
        lock_write()/unlock.
 
50
        """
 
51
 
 
52
        def __init__(self):
 
53
            self.actions = []
 
54
 
 
55
        def lock_read(self):
 
56
            self.actions.append('lock_read')
 
57
 
 
58
        def lock_write(self):
 
59
            self.actions.append('lock_write')
 
60
 
 
61
        def unlock(self):
 
62
            if except_in_unlock:
 
63
                self.actions.append('unlock_fail')
 
64
                raise KeyError('during unlock')
 
65
            else:
 
66
                self.actions.append('unlock')
 
67
 
 
68
        @needs_read_lock
 
69
        def frob(self):
 
70
            """Frob the sample object"""
 
71
            self.actions.append('frob')
 
72
            return 'newbie'
 
73
 
 
74
        @needs_write_lock
 
75
        def bank(self, bar, biz=None):
 
76
            """Bank the sample, but using bar and biz."""
 
77
            self.actions.append(('bank', bar, biz))
 
78
            return (bar, biz)
 
79
 
 
80
        @needs_read_lock
 
81
        def fail_during_read(self):
 
82
            self.actions.append('fail_during_read')
 
83
            raise TypeError('during read')
 
84
 
 
85
        @needs_write_lock
 
86
        def fail_during_write(self):
 
87
            self.actions.append('fail_during_write')
 
88
            raise TypeError('during write')
 
89
 
 
90
    return DecoratorSample()
 
91
 
 
92
 
 
93
class TestDecoratorActions(TestCase):
 
94
 
 
95
    _decorator_style = None # default
 
96
 
 
97
    def test_read_lock_locks_and_unlocks(self):
 
98
        sam = create_decorator_sample(self._decorator_style)
 
99
        self.assertEqual('newbie', sam.frob())
 
100
        self.assertEqual(['lock_read', 'frob', 'unlock'], sam.actions)
 
101
 
 
102
    def test_write_lock_locks_and_unlocks(self):
 
103
        sam = create_decorator_sample(self._decorator_style)
 
104
        self.assertEqual(('bar', 'bing'), sam.bank('bar', biz='bing'))
 
105
        self.assertEqual(['lock_write', ('bank', 'bar', 'bing'), 'unlock'],
 
106
                         sam.actions)
 
107
 
 
108
    def test_read_lock_unlocks_during_failure(self):
 
109
        sam = create_decorator_sample(self._decorator_style)
 
110
        self.assertRaises(TypeError, sam.fail_during_read)
 
111
        self.assertEqual(['lock_read', 'fail_during_read', 'unlock'],
 
112
                         sam.actions)
 
113
 
 
114
    def test_write_lock_unlocks_during_failure(self):
 
115
        sam = create_decorator_sample(self._decorator_style)
 
116
        self.assertRaises(TypeError, sam.fail_during_write)
 
117
        self.assertEqual(['lock_write', 'fail_during_write', 'unlock'],
 
118
                         sam.actions)
 
119
 
 
120
    def test_read_lock_raises_original_error(self):
 
121
        sam = create_decorator_sample(self._decorator_style,
 
122
                                      except_in_unlock=True)
 
123
        self.assertRaises(TypeError, sam.fail_during_read)
 
124
        self.assertEqual(['lock_read', 'fail_during_read', 'unlock_fail'],
 
125
                         sam.actions)
 
126
 
 
127
    def test_write_lock_raises_original_error(self):
 
128
        sam = create_decorator_sample(self._decorator_style,
 
129
                                      except_in_unlock=True)
 
130
        self.assertRaises(TypeError, sam.fail_during_write)
 
131
        self.assertEqual(['lock_write', 'fail_during_write', 'unlock_fail'],
 
132
                         sam.actions)
 
133
 
 
134
    def test_read_lock_raises_unlock_error(self):
 
135
        sam = create_decorator_sample(self._decorator_style,
 
136
                                      except_in_unlock=True)
 
137
        self.assertRaises(KeyError, sam.frob)
 
138
        self.assertEqual(['lock_read', 'frob', 'unlock_fail'], sam.actions)
 
139
 
 
140
    def test_write_lock_raises_unlock_error(self):
 
141
        sam = create_decorator_sample(self._decorator_style,
 
142
                                      except_in_unlock=True)
 
143
        self.assertRaises(KeyError, sam.bank, 'bar', biz='bing')
 
144
        self.assertEqual(['lock_write', ('bank', 'bar', 'bing'),
 
145
                          'unlock_fail'], sam.actions)
 
146
 
 
147
 
 
148
class TestFastDecoratorActions(TestDecoratorActions):
 
149
 
 
150
    _decorator_style = 'fast'
 
151
 
 
152
 
 
153
class TestPrettyDecoratorActions(TestDecoratorActions):
 
154
 
 
155
    _decorator_style = 'pretty'
54
156
 
55
157
 
56
158
class TestDecoratorDocs(TestCase):
58
160
 
59
161
    def test_read_lock_passthrough(self):
60
162
        """@needs_read_lock exposes underlying name and doc."""
61
 
        sam = DecoratorSample()
 
163
        sam = create_decorator_sample(None)
62
164
        self.assertEqual('frob', sam.frob.__name__)
63
165
        self.assertEqual('Frob the sample object', sam.frob.__doc__)
64
166
 
65
167
    def test_write_lock_passthrough(self):
66
168
        """@needs_write_lock exposes underlying name and doc."""
67
 
        sam = DecoratorSample()
 
169
        sam = create_decorator_sample(None)
68
170
        self.assertEqual('bank', sam.bank.__name__)
69
171
        self.assertEqual('Bank the sample, but using bar and biz.',
70
172
                         sam.bank.__doc__)
71
173
 
72
174
    def test_argument_passthrough(self):
73
175
        """Test that arguments get passed around properly."""
74
 
        sam = DecoratorSample()
 
176
        sam = create_decorator_sample(None)
75
177
        sam.bank('1', biz='2')
76
178
        self.assertEqual(['lock_write',
77
179
                          ('bank', '1', '2'),