2 import os |
2 import os |
3 import stat |
3 import stat |
4 import subprocess |
4 import subprocess |
5 import sys |
5 import sys |
6 |
6 |
7 if subprocess.call(['python', '%s/hghave' % os.environ['TESTDIR'], |
7 if subprocess.call( |
8 'cacheable']): |
8 ['python', '%s/hghave' % os.environ['TESTDIR'], 'cacheable'] |
|
9 ): |
9 sys.exit(80) |
10 sys.exit(80) |
10 |
11 |
11 print_ = print |
12 print_ = print |
|
13 |
|
14 |
12 def print(*args, **kwargs): |
15 def print(*args, **kwargs): |
13 """print() wrapper that flushes stdout buffers to avoid py3 buffer issues |
16 """print() wrapper that flushes stdout buffers to avoid py3 buffer issues |
14 |
17 |
15 We could also just write directly to sys.stdout.buffer the way the |
18 We could also just write directly to sys.stdout.buffer the way the |
16 ui object will, but this was easier for porting the test. |
19 ui object will, but this was easier for porting the test. |
17 """ |
20 """ |
18 print_(*args, **kwargs) |
21 print_(*args, **kwargs) |
19 sys.stdout.flush() |
22 sys.stdout.flush() |
|
23 |
20 |
24 |
21 from mercurial import ( |
25 from mercurial import ( |
22 extensions, |
26 extensions, |
23 hg, |
27 hg, |
24 localrepo, |
28 localrepo, |
135 |
140 |
136 repo.invalidate() |
141 repo.invalidate() |
137 print("* both files changed inode") |
142 print("* both files changed inode") |
138 repo.cached |
143 repo.cached |
139 |
144 |
|
145 |
140 def fakeuncacheable(): |
146 def fakeuncacheable(): |
141 def wrapcacheable(orig, *args, **kwargs): |
147 def wrapcacheable(orig, *args, **kwargs): |
142 return False |
148 return False |
143 |
149 |
144 def wrapinit(orig, *args, **kwargs): |
150 def wrapinit(orig, *args, **kwargs): |
145 pass |
151 pass |
146 |
152 |
147 originit = extensions.wrapfunction(util.cachestat, '__init__', wrapinit) |
153 originit = extensions.wrapfunction(util.cachestat, '__init__', wrapinit) |
148 origcacheable = extensions.wrapfunction(util.cachestat, 'cacheable', |
154 origcacheable = extensions.wrapfunction( |
149 wrapcacheable) |
155 util.cachestat, 'cacheable', wrapcacheable |
|
156 ) |
150 |
157 |
151 for fn in ['x', 'y']: |
158 for fn in ['x', 'y']: |
152 try: |
159 try: |
153 os.remove(fn) |
160 os.remove(fn) |
154 except OSError: |
161 except OSError: |
156 |
163 |
157 basic(fakerepo()) |
164 basic(fakerepo()) |
158 |
165 |
159 util.cachestat.cacheable = origcacheable |
166 util.cachestat.cacheable = origcacheable |
160 util.cachestat.__init__ = originit |
167 util.cachestat.__init__ = originit |
|
168 |
161 |
169 |
162 def test_filecache_synced(): |
170 def test_filecache_synced(): |
163 # test old behavior that caused filecached properties to go out of sync |
171 # test old behavior that caused filecached properties to go out of sync |
164 os.system('hg init && echo a >> a && hg ci -qAm.') |
172 os.system('hg init && echo a >> a && hg ci -qAm.') |
165 repo = hg.repository(uimod.ui.load()) |
173 repo = hg.repository(uimod.ui.load()) |
172 # but since changelog isn't under the filecache control anymore, we don't |
180 # but since changelog isn't under the filecache control anymore, we don't |
173 # see that it changed, and return the old changelog without reconstructing |
181 # see that it changed, and return the old changelog without reconstructing |
174 # it |
182 # it |
175 repo.commit(b'.') |
183 repo.commit(b'.') |
176 |
184 |
|
185 |
177 def setbeforeget(repo): |
186 def setbeforeget(repo): |
178 os.remove('x') |
187 os.remove('x') |
179 os.remove('y') |
188 os.remove('y') |
180 repo.__class__.cached.set(repo, 'string set externally') |
189 repo.__class__.cached.set(repo, 'string set externally') |
181 repo.invalidate() |
190 repo.invalidate() |
234 # timestamp ambiguity was naturally avoided while repetition |
244 # timestamp ambiguity was naturally avoided while repetition |
235 continue |
245 continue |
236 |
246 |
237 # st_mtime should be advanced "repetition * 2" times, because |
247 # st_mtime should be advanced "repetition * 2" times, because |
238 # all changes occurred at same time (in sec) |
248 # all changes occurred at same time (in sec) |
239 expected = (oldstat[stat.ST_MTIME] + repetition * 2) & 0x7fffffff |
249 expected = (oldstat[stat.ST_MTIME] + repetition * 2) & 0x7FFFFFFF |
240 if newstat[stat.ST_MTIME] != expected: |
250 if newstat[stat.ST_MTIME] != expected: |
241 print("'newstat[stat.ST_MTIME] %s is not %s (as %s + %s * 2)" % |
251 print( |
242 (newstat[stat.ST_MTIME], expected, |
252 "'newstat[stat.ST_MTIME] %s is not %s (as %s + %s * 2)" |
243 oldstat[stat.ST_MTIME], repetition)) |
253 % ( |
|
254 newstat[stat.ST_MTIME], |
|
255 expected, |
|
256 oldstat[stat.ST_MTIME], |
|
257 repetition, |
|
258 ) |
|
259 ) |
244 |
260 |
245 # no more examination is needed regardless of result |
261 # no more examination is needed regardless of result |
246 break |
262 break |
247 else: |
263 else: |
248 # This platform seems too slow to examine anti-ambiguity |
264 # This platform seems too slow to examine anti-ambiguity |
249 # of file timestamp (or test happened to be executed at |
265 # of file timestamp (or test happened to be executed at |
250 # bad timing). Exit silently in this case, because running |
266 # bad timing). Exit silently in this case, because running |
251 # on other faster platforms can detect problems |
267 # on other faster platforms can detect problems |
252 pass |
268 pass |
253 |
269 |
|
270 |
254 print('basic:') |
271 print('basic:') |
255 print() |
272 print() |
256 basic(fakerepo()) |
273 basic(fakerepo()) |
257 print() |
274 print() |
258 print('fakeuncacheable:') |
275 print('fakeuncacheable:') |