annotate tests/test-util.py @ 51281:8f1983318455

common-pattern: cover "elapsed time" line These are perfect targets for the common-pattern matching.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Wed, 13 Dec 2023 13:46:28 +0100
parents 7e6f3c69c0fb
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
1 # unit tests for mercuril.util utilities
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
2
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
3 import contextlib
48873
5aafc3c5bdec py3: use io.BytesIO directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
4 import io
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
5 import itertools
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
6 import unittest
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
7
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
8 from mercurial import pycompat, util, utils
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
9
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
10
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
11 @contextlib.contextmanager
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
12 def mocktimer(incr=0.1, *additional_targets):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
13 """Replaces util.timer and additional_targets with a mock
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
14
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
15 The timer starts at 0. On each call the time incremented by the value
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
16 of incr. If incr is an iterable, then the time is incremented by the
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
17 next value from that iterable, looping in a cycle when reaching the end.
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
18
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
19 additional_targets must be a sequence of (object, attribute_name) tuples;
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
20 the mock is set with setattr(object, attribute_name, mock).
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
21
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
22 """
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
23 time = [0]
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
24 try:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
25 incr = itertools.cycle(incr)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
26 except TypeError:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
27 incr = itertools.repeat(incr)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
28
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
29 def timer():
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
30 time[0] += next(incr)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
31 return time[0]
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
32
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
33 # record original values
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
34 orig = util.timer
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
35 additional_origs = [(o, a, getattr(o, a)) for o, a in additional_targets]
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
36
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
37 # mock out targets
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
38 util.timer = timer
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
39 for obj, attr in additional_targets:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
40 setattr(obj, attr, timer)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
41
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
42 try:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
43 yield
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
44 finally:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
45 # restore originals
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
46 util.timer = orig
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
47 for args in additional_origs:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
48 setattr(*args)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
49
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
50
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
51 # attr.s default factory for util.timedstats.start binds the timer we
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
52 # need to mock out.
49642
7e6f3c69c0fb tests: update test-util.py for modern attrs package
Matt Harbison <matt_harbison@yahoo.com>
parents: 48875
diff changeset
53 _start_default = (util.timedcmstats.__attrs_attrs__.start.default, 'factory')
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
54
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
55
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
56 @contextlib.contextmanager
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
57 def capturestderr():
48873
5aafc3c5bdec py3: use io.BytesIO directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
58 """Replace utils.procutil.stderr with an io.BytesIO instance
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
59
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
60 The instance is made available as the return value of __enter__.
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
61
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
62 This contextmanager is reentrant.
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
63
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
64 """
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
65 orig = utils.procutil.stderr
48873
5aafc3c5bdec py3: use io.BytesIO directly
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43076
diff changeset
66 utils.procutil.stderr = io.BytesIO()
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
67 try:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
68 yield utils.procutil.stderr
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
69 finally:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
70 utils.procutil.stderr = orig
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
71
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
72
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
73 class timedtests(unittest.TestCase):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
74 def testtimedcmstatsstr(self):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
75 stats = util.timedcmstats()
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
76 self.assertEqual(str(stats), '<unknown>')
38812
9d49bb117dde util: make new timedcmstats class Python 3 compatible
Martijn Pieters <mj@zopatista.com>
parents: 38797
diff changeset
77 self.assertEqual(bytes(stats), b'<unknown>')
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
78 stats.elapsed = 12.34
38812
9d49bb117dde util: make new timedcmstats class Python 3 compatible
Martijn Pieters <mj@zopatista.com>
parents: 38797
diff changeset
79 self.assertEqual(str(stats), pycompat.sysstr(util.timecount(12.34)))
9d49bb117dde util: make new timedcmstats class Python 3 compatible
Martijn Pieters <mj@zopatista.com>
parents: 38797
diff changeset
80 self.assertEqual(bytes(stats), util.timecount(12.34))
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
81
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
82 def testtimedcmcleanexit(self):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
83 # timestamps 1, 4, elapsed time of 4 - 1 = 3
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
84 with mocktimer([1, 3], _start_default):
39258
331ab85e910b cleanup: make all uses of timedcm specify what they're timing
Augie Fackler <augie@google.com>
parents: 38812
diff changeset
85 with util.timedcm('pass') as stats:
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
86 # actual context doesn't matter
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
87 pass
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
88
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
89 self.assertEqual(stats.start, 1)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
90 self.assertEqual(stats.elapsed, 3)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
91 self.assertEqual(stats.level, 1)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
92
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
93 def testtimedcmnested(self):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
94 # timestamps 1, 3, 6, 10, elapsed times of 6 - 3 = 3 and 10 - 1 = 9
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
95 with mocktimer([1, 2, 3, 4], _start_default):
39258
331ab85e910b cleanup: make all uses of timedcm specify what they're timing
Augie Fackler <augie@google.com>
parents: 38812
diff changeset
96 with util.timedcm('outer') as outer_stats:
331ab85e910b cleanup: make all uses of timedcm specify what they're timing
Augie Fackler <augie@google.com>
parents: 38812
diff changeset
97 with util.timedcm('inner') as inner_stats:
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
98 # actual context doesn't matter
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
99 pass
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
100
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
101 self.assertEqual(outer_stats.start, 1)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
102 self.assertEqual(outer_stats.elapsed, 9)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
103 self.assertEqual(outer_stats.level, 1)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
104
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
105 self.assertEqual(inner_stats.start, 3)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
106 self.assertEqual(inner_stats.elapsed, 3)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
107 self.assertEqual(inner_stats.level, 2)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
108
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
109 def testtimedcmexception(self):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
110 # timestamps 1, 4, elapsed time of 4 - 1 = 3
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
111 with mocktimer([1, 3], _start_default):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
112 try:
39258
331ab85e910b cleanup: make all uses of timedcm specify what they're timing
Augie Fackler <augie@google.com>
parents: 38812
diff changeset
113 with util.timedcm('exceptional') as stats:
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
114 raise ValueError()
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
115 except ValueError:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
116 pass
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
117
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
118 self.assertEqual(stats.start, 1)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
119 self.assertEqual(stats.elapsed, 3)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
120 self.assertEqual(stats.level, 1)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
121
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
122 def testtimeddecorator(self):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
123 @util.timed
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
124 def testfunc(callcount=1):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
125 callcount -= 1
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
126 if callcount:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
127 testfunc(callcount)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
128
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
129 # timestamps 1, 2, 3, 4, elapsed time of 3 - 2 = 1 and 4 - 1 = 3
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
130 with mocktimer(1, _start_default):
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
131 with capturestderr() as out:
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
132 testfunc(2)
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
133
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
134 self.assertEqual(
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
135 out.getvalue(),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
136 (b' testfunc: 1.000 s\n' b' testfunc: 3.000 s\n'),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
137 )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
138
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
139
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
140 if __name__ == '__main__':
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
141 import silenttestrunner
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 39258
diff changeset
142
38797
8751d1e2a7ff util: create a context manager to handle timing
Martijn Pieters <mj@zopatista.com>
parents:
diff changeset
143 silenttestrunner.main(__name__)