##// END OF EJS Templates
tests: update test-util.py for modern attrs package...
Matt Harbison -
r50537:7e6f3c69 default
parent child Browse files
Show More
@@ -1,143 +1,143 b''
1 # unit tests for mercuril.util utilities
1 # unit tests for mercuril.util utilities
2
2
3 import contextlib
3 import contextlib
4 import io
4 import io
5 import itertools
5 import itertools
6 import unittest
6 import unittest
7
7
8 from mercurial import pycompat, util, utils
8 from mercurial import pycompat, util, utils
9
9
10
10
11 @contextlib.contextmanager
11 @contextlib.contextmanager
12 def mocktimer(incr=0.1, *additional_targets):
12 def mocktimer(incr=0.1, *additional_targets):
13 """Replaces util.timer and additional_targets with a mock
13 """Replaces util.timer and additional_targets with a mock
14
14
15 The timer starts at 0. On each call the time incremented by the value
15 The timer starts at 0. On each call the time incremented by the value
16 of incr. If incr is an iterable, then the time is incremented by the
16 of incr. If incr is an iterable, then the time is incremented by the
17 next value from that iterable, looping in a cycle when reaching the end.
17 next value from that iterable, looping in a cycle when reaching the end.
18
18
19 additional_targets must be a sequence of (object, attribute_name) tuples;
19 additional_targets must be a sequence of (object, attribute_name) tuples;
20 the mock is set with setattr(object, attribute_name, mock).
20 the mock is set with setattr(object, attribute_name, mock).
21
21
22 """
22 """
23 time = [0]
23 time = [0]
24 try:
24 try:
25 incr = itertools.cycle(incr)
25 incr = itertools.cycle(incr)
26 except TypeError:
26 except TypeError:
27 incr = itertools.repeat(incr)
27 incr = itertools.repeat(incr)
28
28
29 def timer():
29 def timer():
30 time[0] += next(incr)
30 time[0] += next(incr)
31 return time[0]
31 return time[0]
32
32
33 # record original values
33 # record original values
34 orig = util.timer
34 orig = util.timer
35 additional_origs = [(o, a, getattr(o, a)) for o, a in additional_targets]
35 additional_origs = [(o, a, getattr(o, a)) for o, a in additional_targets]
36
36
37 # mock out targets
37 # mock out targets
38 util.timer = timer
38 util.timer = timer
39 for obj, attr in additional_targets:
39 for obj, attr in additional_targets:
40 setattr(obj, attr, timer)
40 setattr(obj, attr, timer)
41
41
42 try:
42 try:
43 yield
43 yield
44 finally:
44 finally:
45 # restore originals
45 # restore originals
46 util.timer = orig
46 util.timer = orig
47 for args in additional_origs:
47 for args in additional_origs:
48 setattr(*args)
48 setattr(*args)
49
49
50
50
51 # attr.s default factory for util.timedstats.start binds the timer we
51 # attr.s default factory for util.timedstats.start binds the timer we
52 # need to mock out.
52 # need to mock out.
53 _start_default = (util.timedcmstats.start.default, 'factory')
53 _start_default = (util.timedcmstats.__attrs_attrs__.start.default, 'factory')
54
54
55
55
56 @contextlib.contextmanager
56 @contextlib.contextmanager
57 def capturestderr():
57 def capturestderr():
58 """Replace utils.procutil.stderr with an io.BytesIO instance
58 """Replace utils.procutil.stderr with an io.BytesIO instance
59
59
60 The instance is made available as the return value of __enter__.
60 The instance is made available as the return value of __enter__.
61
61
62 This contextmanager is reentrant.
62 This contextmanager is reentrant.
63
63
64 """
64 """
65 orig = utils.procutil.stderr
65 orig = utils.procutil.stderr
66 utils.procutil.stderr = io.BytesIO()
66 utils.procutil.stderr = io.BytesIO()
67 try:
67 try:
68 yield utils.procutil.stderr
68 yield utils.procutil.stderr
69 finally:
69 finally:
70 utils.procutil.stderr = orig
70 utils.procutil.stderr = orig
71
71
72
72
73 class timedtests(unittest.TestCase):
73 class timedtests(unittest.TestCase):
74 def testtimedcmstatsstr(self):
74 def testtimedcmstatsstr(self):
75 stats = util.timedcmstats()
75 stats = util.timedcmstats()
76 self.assertEqual(str(stats), '<unknown>')
76 self.assertEqual(str(stats), '<unknown>')
77 self.assertEqual(bytes(stats), b'<unknown>')
77 self.assertEqual(bytes(stats), b'<unknown>')
78 stats.elapsed = 12.34
78 stats.elapsed = 12.34
79 self.assertEqual(str(stats), pycompat.sysstr(util.timecount(12.34)))
79 self.assertEqual(str(stats), pycompat.sysstr(util.timecount(12.34)))
80 self.assertEqual(bytes(stats), util.timecount(12.34))
80 self.assertEqual(bytes(stats), util.timecount(12.34))
81
81
82 def testtimedcmcleanexit(self):
82 def testtimedcmcleanexit(self):
83 # timestamps 1, 4, elapsed time of 4 - 1 = 3
83 # timestamps 1, 4, elapsed time of 4 - 1 = 3
84 with mocktimer([1, 3], _start_default):
84 with mocktimer([1, 3], _start_default):
85 with util.timedcm('pass') as stats:
85 with util.timedcm('pass') as stats:
86 # actual context doesn't matter
86 # actual context doesn't matter
87 pass
87 pass
88
88
89 self.assertEqual(stats.start, 1)
89 self.assertEqual(stats.start, 1)
90 self.assertEqual(stats.elapsed, 3)
90 self.assertEqual(stats.elapsed, 3)
91 self.assertEqual(stats.level, 1)
91 self.assertEqual(stats.level, 1)
92
92
93 def testtimedcmnested(self):
93 def testtimedcmnested(self):
94 # timestamps 1, 3, 6, 10, elapsed times of 6 - 3 = 3 and 10 - 1 = 9
94 # timestamps 1, 3, 6, 10, elapsed times of 6 - 3 = 3 and 10 - 1 = 9
95 with mocktimer([1, 2, 3, 4], _start_default):
95 with mocktimer([1, 2, 3, 4], _start_default):
96 with util.timedcm('outer') as outer_stats:
96 with util.timedcm('outer') as outer_stats:
97 with util.timedcm('inner') as inner_stats:
97 with util.timedcm('inner') as inner_stats:
98 # actual context doesn't matter
98 # actual context doesn't matter
99 pass
99 pass
100
100
101 self.assertEqual(outer_stats.start, 1)
101 self.assertEqual(outer_stats.start, 1)
102 self.assertEqual(outer_stats.elapsed, 9)
102 self.assertEqual(outer_stats.elapsed, 9)
103 self.assertEqual(outer_stats.level, 1)
103 self.assertEqual(outer_stats.level, 1)
104
104
105 self.assertEqual(inner_stats.start, 3)
105 self.assertEqual(inner_stats.start, 3)
106 self.assertEqual(inner_stats.elapsed, 3)
106 self.assertEqual(inner_stats.elapsed, 3)
107 self.assertEqual(inner_stats.level, 2)
107 self.assertEqual(inner_stats.level, 2)
108
108
109 def testtimedcmexception(self):
109 def testtimedcmexception(self):
110 # timestamps 1, 4, elapsed time of 4 - 1 = 3
110 # timestamps 1, 4, elapsed time of 4 - 1 = 3
111 with mocktimer([1, 3], _start_default):
111 with mocktimer([1, 3], _start_default):
112 try:
112 try:
113 with util.timedcm('exceptional') as stats:
113 with util.timedcm('exceptional') as stats:
114 raise ValueError()
114 raise ValueError()
115 except ValueError:
115 except ValueError:
116 pass
116 pass
117
117
118 self.assertEqual(stats.start, 1)
118 self.assertEqual(stats.start, 1)
119 self.assertEqual(stats.elapsed, 3)
119 self.assertEqual(stats.elapsed, 3)
120 self.assertEqual(stats.level, 1)
120 self.assertEqual(stats.level, 1)
121
121
122 def testtimeddecorator(self):
122 def testtimeddecorator(self):
123 @util.timed
123 @util.timed
124 def testfunc(callcount=1):
124 def testfunc(callcount=1):
125 callcount -= 1
125 callcount -= 1
126 if callcount:
126 if callcount:
127 testfunc(callcount)
127 testfunc(callcount)
128
128
129 # timestamps 1, 2, 3, 4, elapsed time of 3 - 2 = 1 and 4 - 1 = 3
129 # timestamps 1, 2, 3, 4, elapsed time of 3 - 2 = 1 and 4 - 1 = 3
130 with mocktimer(1, _start_default):
130 with mocktimer(1, _start_default):
131 with capturestderr() as out:
131 with capturestderr() as out:
132 testfunc(2)
132 testfunc(2)
133
133
134 self.assertEqual(
134 self.assertEqual(
135 out.getvalue(),
135 out.getvalue(),
136 (b' testfunc: 1.000 s\n' b' testfunc: 3.000 s\n'),
136 (b' testfunc: 1.000 s\n' b' testfunc: 3.000 s\n'),
137 )
137 )
138
138
139
139
140 if __name__ == '__main__':
140 if __name__ == '__main__':
141 import silenttestrunner
141 import silenttestrunner
142
142
143 silenttestrunner.main(__name__)
143 silenttestrunner.main(__name__)
General Comments 0
You need to be logged in to leave comments. Login now