bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 
1845.1.2
by mbp at sourcefrog
 Use larger time window on hashcache to be safe with fractional times  | 
1  | 
# Copyright (C) 2005, 2006 Canonical Ltd
 | 
| 
1887.1.1
by Adeodato Simó
 Do not separate paragraphs in the copyright statement with blank lines,  | 
2  | 
#
 | 
| 
846
by Martin Pool
 - start adding refactored/simplified hash cache  | 
3  | 
# This program is free software; you can redistribute it and/or modify
 | 
4  | 
# it under the terms of the GNU General Public License as published by
 | 
|
5  | 
# the Free Software Foundation; either version 2 of the License, or
 | 
|
6  | 
# (at your option) any later version.
 | 
|
| 
1887.1.1
by Adeodato Simó
 Do not separate paragraphs in the copyright statement with blank lines,  | 
7  | 
#
 | 
| 
846
by Martin Pool
 - start adding refactored/simplified hash cache  | 
8  | 
# This program is distributed in the hope that it will be useful,
 | 
9  | 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
|
10  | 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
|
11  | 
# GNU General Public License for more details.
 | 
|
| 
1887.1.1
by Adeodato Simó
 Do not separate paragraphs in the copyright statement with blank lines,  | 
12  | 
#
 | 
| 
846
by Martin Pool
 - start adding refactored/simplified hash cache  | 
13  | 
# You should have received a copy of the GNU General Public License
 | 
14  | 
# along with this program; if not, write to the Free Software
 | 
|
15  | 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | 
|
16  | 
||
| 
1185.1.40
by Robert Collins
 Merge what applied of Alexander Belchenko's win32 patch.  | 
17  | 
import os  | 
| 
1534.4.51
by Robert Collins
 Test the disk layout of format3 working trees.  | 
18  | 
import sha  | 
| 
1845.1.3
by Martin Pool
 Improvements to hashcache testing:  | 
19  | 
import stat  | 
| 
1185.38.8
by John Arbash Meinel
 [patch] testhashcache delay for win32 and cygwin  | 
20  | 
import sys  | 
| 
1185.1.40
by Robert Collins
 Merge what applied of Alexander Belchenko's win32 patch.  | 
21  | 
import time  | 
| 
1534.4.51
by Robert Collins
 Test the disk layout of format3 working trees.  | 
22  | 
|
23  | 
from bzrlib.errors import BzrError  | 
|
24  | 
from bzrlib.hashcache import HashCache  | 
|
| 
1845.1.3
by Martin Pool
 Improvements to hashcache testing:  | 
25  | 
from bzrlib.tests import TestCaseInTempDir, TestSkipped, TestCase  | 
| 
846
by Martin Pool
 - start adding refactored/simplified hash cache  | 
26  | 
|
27  | 
||
28  | 
def sha1(t):  | 
|
29  | 
return sha.new(t).hexdigest()  | 
|
30  | 
||
31  | 
||
32  | 
def pause():  | 
|
| 
1845.1.2
by mbp at sourcefrog
 Use larger time window on hashcache to be safe with fractional times  | 
33  | 
time.sleep(5.0)  | 
| 
1185.33.109
by Denys Duchier
 test_hashcache: catch no exceptions  | 
34  | 
|
35  | 
||
| 
1141
by Martin Pool
 - rename FunctionalTest to TestCaseInTempDir  | 
36  | 
class TestHashCache(TestCaseInTempDir):  | 
| 
1845.1.3
by Martin Pool
 Improvements to hashcache testing:  | 
37  | 
"""Test the hashcache against a real directory"""  | 
| 
1102
by Martin Pool
 - merge test refactoring from robertc  | 
38  | 
|
| 
1845.1.1
by mbp at sourcefrog
 Refactor and improve hashcache tests  | 
39  | 
def make_hashcache(self):  | 
| 
866
by Martin Pool
 - use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.  | 
40  | 
        # make a dummy bzr directory just to hold the cache
 | 
41  | 
os.mkdir('.bzr')  | 
|
| 
1534.4.51
by Robert Collins
 Test the disk layout of format3 working trees.  | 
42  | 
hc = HashCache('.', '.bzr/stat-cache')  | 
| 
1845.1.1
by mbp at sourcefrog
 Refactor and improve hashcache tests  | 
43  | 
return hc  | 
44  | 
||
45  | 
def reopen_hashcache(self):  | 
|
46  | 
hc = HashCache('.', '.bzr/stat-cache')  | 
|
47  | 
hc.read()  | 
|
48  | 
return hc  | 
|
49  | 
||
50  | 
def test_hashcache_initial_miss(self):  | 
|
51  | 
"""Get correct hash from an empty hashcache"""  | 
|
52  | 
hc = self.make_hashcache()  | 
|
53  | 
self.build_tree_contents([('foo', 'hello')])  | 
|
54  | 
self.assertEquals(hc.get_sha1('foo'),  | 
|
55  | 
'aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d')  | 
|
56  | 
self.assertEquals(hc.miss_count, 1)  | 
|
57  | 
self.assertEquals(hc.hit_count, 0)  | 
|
58  | 
||
59  | 
def test_hashcache_new_file(self):  | 
|
60  | 
hc = self.make_hashcache()  | 
|
61  | 
self.build_tree_contents([('foo', 'goodbye')])  | 
|
62  | 
        # now read without pausing; it may not be possible to cache it as its
 | 
|
63  | 
        # so new
 | 
|
64  | 
self.assertEquals(hc.get_sha1('foo'), sha1('goodbye'))  | 
|
65  | 
||
66  | 
def test_hashcache_nonexistent_file(self):  | 
|
67  | 
hc = self.make_hashcache()  | 
|
68  | 
self.assertEquals(hc.get_sha1('no-name-yet'), None)  | 
|
69  | 
||
70  | 
def test_hashcache_replaced_file(self):  | 
|
71  | 
hc = self.make_hashcache()  | 
|
72  | 
self.build_tree_contents([('foo', 'goodbye')])  | 
|
73  | 
self.assertEquals(hc.get_sha1('foo'), sha1('goodbye'))  | 
|
74  | 
os.remove('foo')  | 
|
75  | 
self.assertEquals(hc.get_sha1('foo'), None)  | 
|
76  | 
self.build_tree_contents([('foo', 'new content')])  | 
|
77  | 
self.assertEquals(hc.get_sha1('foo'), sha1('new content'))  | 
|
78  | 
||
79  | 
def test_hashcache_not_file(self):  | 
|
80  | 
hc = self.make_hashcache()  | 
|
81  | 
self.build_tree(['subdir/'])  | 
|
| 
846
by Martin Pool
 - start adding refactored/simplified hash cache  | 
82  | 
self.assertEquals(hc.get_sha1('subdir'), None)  | 
| 
848
by Martin Pool
 doc  | 
83  | 
|
| 
1845.1.1
by mbp at sourcefrog
 Refactor and improve hashcache tests  | 
84  | 
def test_hashcache_load(self):  | 
85  | 
hc = self.make_hashcache()  | 
|
86  | 
self.build_tree_contents([('foo', 'contents')])  | 
|
| 
861
by Martin Pool
 - more hash-cache tests  | 
87  | 
pause()  | 
| 
1845.1.1
by mbp at sourcefrog
 Refactor and improve hashcache tests  | 
88  | 
self.assertEquals(hc.get_sha1('foo'), sha1('contents'))  | 
| 
866
by Martin Pool
 - use new path-based hashcache for WorkingTree- squash mtime/ctime to whole seconds- update and if necessary write out hashcache when WorkingTree object is created.  | 
89  | 
hc.write()  | 
| 
1845.1.1
by mbp at sourcefrog
 Refactor and improve hashcache tests  | 
90  | 
hc = self.reopen_hashcache()  | 
91  | 
self.assertEquals(hc.get_sha1('foo'), sha1('contents'))  | 
|
| 
1185.60.5
by Aaron Bentley
 Reactivated hashcache tests  | 
92  | 
self.assertEquals(hc.hit_count, 1)  | 
| 
1845.1.1
by mbp at sourcefrog
 Refactor and improve hashcache tests  | 
93  | 
|
94  | 
def test_hammer_hashcache(self):  | 
|
95  | 
hc = self.make_hashcache()  | 
|
| 
1845.1.2
by mbp at sourcefrog
 Use larger time window on hashcache to be safe with fractional times  | 
96  | 
for i in xrange(10000):  | 
97  | 
self.log('start writing at %s', time.time())  | 
|
| 
1845.1.1
by mbp at sourcefrog
 Refactor and improve hashcache tests  | 
98  | 
f = file('foo', 'w')  | 
99  | 
try:  | 
|
100  | 
last_content = '%08x' % i  | 
|
101  | 
f.write(last_content)  | 
|
102  | 
finally:  | 
|
103  | 
f.close()  | 
|
| 
1845.1.2
by mbp at sourcefrog
 Use larger time window on hashcache to be safe with fractional times  | 
104  | 
last_sha1 = sha1(last_content)  | 
105  | 
self.log("iteration %d: %r -> %r",  | 
|
106  | 
i, last_content, last_sha1)  | 
|
107  | 
got_sha1 = hc.get_sha1('foo')  | 
|
108  | 
self.assertEquals(got_sha1, last_sha1)  | 
|
| 
1845.1.1
by mbp at sourcefrog
 Refactor and improve hashcache tests  | 
109  | 
hc.write()  | 
110  | 
hc = self.reopen_hashcache()  | 
|
| 
1185.33.106
by Denys Duchier
 check that hashcache can raise BzrError  | 
111  | 
|
112  | 
def test_hashcache_raise(self):  | 
|
113  | 
"""check that hashcache can raise BzrError"""  | 
|
| 
1845.1.1
by mbp at sourcefrog
 Refactor and improve hashcache tests  | 
114  | 
hc = self.make_hashcache()  | 
| 
1963.2.6
by Robey Pointer
 pychecker is on crack; go back to using 'is None'.  | 
115  | 
if getattr(os, 'mkfifo', None) is None:  | 
| 
1845.1.2
by mbp at sourcefrog
 Use larger time window on hashcache to be safe with fractional times  | 
116  | 
raise TestSkipped('filesystem fifos not supported on this system')  | 
117  | 
os.mkfifo('a')  | 
|
118  | 
        # It's possible that the system supports fifos but the filesystem
 | 
|
119  | 
        # can't.  In that case we should skip at this point.  But in fact
 | 
|
120  | 
        # such combinations don't usually occur for the filesystem where
 | 
|
121  | 
        # people test bzr.
 | 
|
122  | 
self.assertRaises(BzrError, hc.get_sha1, 'a')  | 
|
| 
1845.1.3
by Martin Pool
 Improvements to hashcache testing:  | 
123  | 
|
124  | 
||
125  | 
class FakeHashCache(HashCache):  | 
|
126  | 
"""Hashcache that consults a fake clock rather than the real one.  | 
|
127  | 
||
128  | 
    This lets us examine how old or new files would be handled, without
 | 
|
129  | 
    actually having to wait for time to pass.
 | 
|
130  | 
    """
 | 
|
131  | 
def __init__(self):  | 
|
132  | 
        # set root and cache file name to none to make sure we won't touch the
 | 
|
133  | 
        # real filesystem
 | 
|
134  | 
HashCache.__init__(self, '.', 'hashcache')  | 
|
135  | 
self._files = {}  | 
|
136  | 
        # simulated clock running forward as operations happen
 | 
|
137  | 
self._clock = 0  | 
|
138  | 
||
139  | 
def put_file(self, filename, file_contents):  | 
|
140  | 
abspath = './' + filename  | 
|
141  | 
self._files[abspath] = (file_contents, self._clock)  | 
|
142  | 
||
143  | 
def _fingerprint(self, abspath):  | 
|
144  | 
entry = self._files[abspath]  | 
|
145  | 
return (len(entry[0]),  | 
|
146  | 
entry[1], entry[1],  | 
|
147  | 
10, 20,  | 
|
148  | 
stat.S_IFREG | 0600)  | 
|
149  | 
||
150  | 
def _really_sha1_file(self, abspath):  | 
|
151  | 
if abspath in self._files:  | 
|
152  | 
return sha1(self._files[abspath][0])  | 
|
153  | 
else:  | 
|
154  | 
return None  | 
|
155  | 
||
156  | 
def _cutoff_time(self):  | 
|
157  | 
return self._clock - 2  | 
|
158  | 
||
159  | 
def pretend_to_sleep(self, secs):  | 
|
160  | 
self._clock += secs  | 
|
161  | 
||
162  | 
||
163  | 
class TestHashCacheFakeFilesystem(TestCaseInTempDir):  | 
|
164  | 
"""Tests the hashcache using a simulated OS.  | 
|
165  | 
    """
 | 
|
166  | 
||
167  | 
def make_hashcache(self):  | 
|
168  | 
return FakeHashCache()  | 
|
169  | 
||
170  | 
def test_hashcache_miss_new_file(self):  | 
|
171  | 
"""A new file gives the right sha1 but misses"""  | 
|
172  | 
hc = self.make_hashcache()  | 
|
173  | 
hc.put_file('foo', 'hello')  | 
|
174  | 
self.assertEquals(hc.get_sha1('foo'), sha1('hello'))  | 
|
175  | 
self.assertEquals(hc.miss_count, 1)  | 
|
176  | 
self.assertEquals(hc.hit_count, 0)  | 
|
177  | 
        # if we try again it's still too new; 
 | 
|
178  | 
self.assertEquals(hc.get_sha1('foo'), sha1('hello'))  | 
|
179  | 
self.assertEquals(hc.miss_count, 2)  | 
|
180  | 
self.assertEquals(hc.hit_count, 0)  | 
|
181  | 
||
182  | 
def test_hashcache_old_file(self):  | 
|
183  | 
"""An old file gives the right sha1 and hits"""  | 
|
184  | 
hc = self.make_hashcache()  | 
|
185  | 
hc.put_file('foo', 'hello')  | 
|
186  | 
hc.pretend_to_sleep(20)  | 
|
187  | 
        # file is new; should get the correct hash but miss
 | 
|
188  | 
self.assertEquals(hc.get_sha1('foo'), sha1('hello'))  | 
|
189  | 
self.assertEquals(hc.miss_count, 1)  | 
|
190  | 
self.assertEquals(hc.hit_count, 0)  | 
|
191  | 
        # and can now be hit
 | 
|
192  | 
self.assertEquals(hc.get_sha1('foo'), sha1('hello'))  | 
|
193  | 
self.assertEquals(hc.miss_count, 1)  | 
|
194  | 
self.assertEquals(hc.hit_count, 1)  | 
|
195  | 
hc.pretend_to_sleep(3)  | 
|
196  | 
        # and again
 | 
|
197  | 
self.assertEquals(hc.get_sha1('foo'), sha1('hello'))  | 
|
198  | 
self.assertEquals(hc.miss_count, 1)  | 
|
199  | 
self.assertEquals(hc.hit_count, 2)  | 
|
200  | 
||
201  | 
def test_hashcache_invalidates(self):  | 
|
202  | 
hc = self.make_hashcache()  | 
|
203  | 
hc.put_file('foo', 'hello')  | 
|
204  | 
hc.pretend_to_sleep(20)  | 
|
205  | 
hc.get_sha1('foo')  | 
|
206  | 
hc.put_file('foo', 'h1llo')  | 
|
207  | 
self.assertEquals(hc.get_sha1('foo'), sha1('h1llo'))  | 
|
208  | 
self.assertEquals(hc.miss_count, 2)  | 
|
209  | 
self.assertEquals(hc.hit_count, 0)  |