]> arthur.barton.de Git - bup.git/blob - test/int/test_git.py
Remove Client __del__ in favor of context management
[bup.git] / test / int / test_git.py
1
2 from __future__ import absolute_import, print_function
3 import sys
4 from binascii import hexlify, unhexlify
5 from subprocess import check_call
6 from functools import partial
7 import struct, os
8 import pytest
9
10 from wvpytest import *
11
12 from bup import git, path
13 from bup.compat import bytes_from_byte, environ, range
14 from bup.helpers import localtime, log, mkdirp, readpipe
15
16
17 bup_exe = path.exe()
18
19
20 def exc(*cmd):
21     print(repr(cmd), file=sys.stderr)
22     check_call(cmd)
23
24
25 def exo(*cmd):
26     print(repr(cmd), file=sys.stderr)
27     return readpipe(cmd)
28
29
30 def test_git_version_detection():
31     # Test version types from git's tag history
32     for expected, ver in \
33         (('insufficient', b'git version 0.99'),
34          ('insufficient', b'git version 0.99.1'),
35          ('insufficient', b'git version 0.99.7a'),
36          ('insufficient', b'git version 1.0rc1'),
37          ('insufficient', b'git version 1.0.1'),
38          ('insufficient', b'git version 1.4.2.1'),
39          ('insufficient', b'git version 1.5.5'),
40          ('insufficient', b'git version 1.5.6-rc0'),
41          ('suitable', b'git version 1.5.6'),
42          ('suitable', b'git version 1.5.6.1'),
43          ('suitable', b'git version 2.14.0-rc0'),
44          ('suitable', b'git version 2.14.0 (something ...)'),
45          ('suitable', b'git version 111.222.333.444-rc555'),
46          ('unrecognized', b'huh?')):
47         assert expected == git.is_suitable_git(ver_str=ver)
48         try:
49             if expected == 'insufficient':
50                 with pytest.raises(SystemExit):
51                     git.require_suitable_git(ver)
52             elif expected == 'suitable':
53                 git.require_suitable_git(ver_str=ver)
54             elif expected == 'unrecognized':
55                 with pytest.raises(git.GitError):
56                     git.require_suitable_git(ver)
57             else:
58                 assert False
59         finally:
60             git._git_great = None
61         try:
62             environ[b'BUP_GIT_VERSION_IS_FINE'] = b'true'
63             git.require_suitable_git(ver_str=ver)
64         finally:
65             del environ[b'BUP_GIT_VERSION_IS_FINE']
66             git._git_great = None
67
68
69 def test_mangle():
70     afile  = 0o100644
71     afile2 = 0o100770
72     alink  = 0o120000
73     adir   = 0o040000
74     adir2  = 0o040777
75     assert git.mangle_name(b'a', adir2, adir) == b'a'
76     assert git.mangle_name(b'.bup', adir2, adir) == b'.bup.bupl'
77     assert git.mangle_name(b'a.bupa', adir2, adir) == b'a.bupa.bupl'
78     WVPASSEQ(git.mangle_name(b'b.bup', alink, alink), b'b.bup.bupl')
79     WVPASSEQ(git.mangle_name(b'b.bu', alink, alink), b'b.bu')
80     WVPASSEQ(git.mangle_name(b'f', afile, afile2), b'f')
81     WVPASSEQ(git.mangle_name(b'f.bup', afile, afile2), b'f.bup.bupl')
82     WVPASSEQ(git.mangle_name(b'f.bup', afile, adir), b'f.bup.bup')
83     WVPASSEQ(git.mangle_name(b'f', afile, adir), b'f.bup')
84
85     WVPASSEQ(git.demangle_name(b'f.bup', afile), (b'f', git.BUP_CHUNKED))
86     WVPASSEQ(git.demangle_name(b'f.bupl', afile), (b'f', git.BUP_NORMAL))
87     WVPASSEQ(git.demangle_name(b'f.bup.bupl', afile), (b'f.bup', git.BUP_NORMAL))
88
89     WVPASSEQ(git.demangle_name(b'.bupm', afile), (b'', git.BUP_NORMAL))
90     WVPASSEQ(git.demangle_name(b'.bupm', adir), (b'', git.BUP_CHUNKED))
91
92     # for safety, we ignore .bup? suffixes we don't recognize.  Future
93     # versions might implement a .bup[a-z] extension as something other
94     # than BUP_NORMAL.
95     WVPASSEQ(git.demangle_name(b'f.bupa', afile), (b'f.bupa', git.BUP_NORMAL))
96
97
98 def test_encode():
99     s = b'hello world'
100     packb = b''.join(git._encode_packobj(b'blob', s))
101     packt = b''.join(git._encode_packobj(b'tree', s))
102     packc = b''.join(git._encode_packobj(b'commit', s))
103     packlb = b''.join(git._encode_packobj(b'blob', s * 200))
104     WVPASSEQ(git._decode_packobj(packb), (b'blob', s))
105     WVPASSEQ(git._decode_packobj(packt), (b'tree', s))
106     WVPASSEQ(git._decode_packobj(packc), (b'commit', s))
107     WVPASSEQ(git._decode_packobj(packlb), (b'blob', s * 200))
108     def encode_pobj(n):
109         return b''.join(git._encode_packobj(b'blob', s, compression_level=n))
110     WVEXCEPT(ValueError, encode_pobj, -1)
111     WVEXCEPT(ValueError, encode_pobj, 10)
112     WVEXCEPT(ValueError, encode_pobj, b'x')
113
114
115 def test_packs(tmpdir):
116     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
117     git.init_repo(bupdir)
118     git.verbose = 1
119
120     w = git.PackWriter()
121     w.new_blob(os.urandom(100))
122     w.new_blob(os.urandom(100))
123     w.abort()
124
125     w = git.PackWriter()
126     hashes = []
127     nobj = 1000
128     for i in range(nobj):
129         hashes.append(w.new_blob(b'%d' % i))
130     log('\n')
131     nameprefix = w.close()
132     print(repr(nameprefix))
133     WVPASS(os.path.exists(nameprefix + b'.pack'))
134     WVPASS(os.path.exists(nameprefix + b'.idx'))
135
136     r = git.open_idx(nameprefix + b'.idx')
137     print(repr(r.fanout))
138
139     for i in range(nobj):
140         WVPASS(r.find_offset(hashes[i]) > 0)
141     WVPASS(r.exists(hashes[99]))
142     WVFAIL(r.exists(b'\0'*20))
143
144     pi = iter(r)
145     for h in sorted(hashes):
146         WVPASSEQ(hexlify(next(pi)), hexlify(h))
147
148     WVFAIL(r.find_offset(b'\0'*20))
149
150     r = git.PackIdxList(bupdir + b'/objects/pack')
151     WVPASS(r.exists(hashes[5]))
152     WVPASS(r.exists(hashes[6]))
153     WVFAIL(r.exists(b'\0'*20))
154
155
156 def test_pack_name_lookup(tmpdir):
157     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
158     git.init_repo(bupdir)
159     git.verbose = 1
160     packdir = git.repo(b'objects/pack')
161
162     idxnames = []
163     hashes = []
164
165     for start in range(0,28,2):
166         w = git.PackWriter()
167         for i in range(start, start+2):
168             hashes.append(w.new_blob(b'%d' % i))
169         log('\n')
170         idxnames.append(os.path.basename(w.close() + b'.idx'))
171
172     r = git.PackIdxList(packdir)
173     WVPASSEQ(len(r.packs), 2)
174     for e,idxname in enumerate(idxnames):
175         for i in range(e*2, (e+1)*2):
176             WVPASSEQ(idxname, r.exists(hashes[i], want_source=True))
177
178
179 def test_long_index(tmpdir):
180     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
181     git.init_repo(bupdir)
182     idx = git.PackIdxV2Writer()
183     obj_bin = struct.pack('!IIIII',
184             0x00112233, 0x44556677, 0x88990011, 0x22334455, 0x66778899)
185     obj2_bin = struct.pack('!IIIII',
186             0x11223344, 0x55667788, 0x99001122, 0x33445566, 0x77889900)
187     obj3_bin = struct.pack('!IIIII',
188             0x22334455, 0x66778899, 0x00112233, 0x44556677, 0x88990011)
189     pack_bin = struct.pack('!IIIII',
190             0x99887766, 0x55443322, 0x11009988, 0x77665544, 0x33221100)
191     idx.add(obj_bin, 1, 0xfffffffff)
192     idx.add(obj2_bin, 2, 0xffffffffff)
193     idx.add(obj3_bin, 3, 0xff)
194     name = tmpdir + b'/tmp.idx'
195     r = idx.write(name, pack_bin)
196     i = git.PackIdxV2(name, open(name, 'rb'))
197     WVPASSEQ(i.find_offset(obj_bin), 0xfffffffff)
198     WVPASSEQ(i.find_offset(obj2_bin), 0xffffffffff)
199     WVPASSEQ(i.find_offset(obj3_bin), 0xff)
200
201
202 def test_check_repo_or_die(tmpdir):
203     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
204     orig_cwd = os.getcwd()
205     try:
206         os.chdir(tmpdir)
207         git.init_repo(bupdir)
208         git.check_repo_or_die()
209         # if we reach this point the call above passed
210         WVPASS('check_repo_or_die')
211
212         os.rename(bupdir + b'/objects/pack',
213                   bupdir + b'/objects/pack.tmp')
214         open(bupdir + b'/objects/pack', 'w').close()
215         try:
216             git.check_repo_or_die()
217         except SystemExit as e:
218             WVPASSEQ(e.code, 14)
219         else:
220             WVFAIL()
221         os.unlink(bupdir + b'/objects/pack')
222         os.rename(bupdir + b'/objects/pack.tmp',
223                   bupdir + b'/objects/pack')
224
225         try:
226             git.check_repo_or_die(b'nonexistantbup.tmp')
227         except SystemExit as e:
228             WVPASSEQ(e.code, 15)
229         else:
230             WVFAIL()
231     finally:
232         os.chdir(orig_cwd)
233
234
235 def test_commit_parsing(tmpdir):
236     def restore_env_var(name, val):
237         if val is None:
238             del environ[name]
239         else:
240             environ[name] = val
241
242     def showval(commit, val):
243         return readpipe([b'git', b'show', b'-s',
244                          b'--pretty=format:%s' % val, commit]).strip()
245
246     orig_cwd = os.getcwd()
247     workdir = tmpdir + b'/work'
248     repodir = workdir + b'/.git'
249     orig_author_name = environ.get(b'GIT_AUTHOR_NAME')
250     orig_author_email = environ.get(b'GIT_AUTHOR_EMAIL')
251     orig_committer_name = environ.get(b'GIT_COMMITTER_NAME')
252     orig_committer_email = environ.get(b'GIT_COMMITTER_EMAIL')
253     environ[b'GIT_AUTHOR_NAME'] = b'bup test'
254     environ[b'GIT_COMMITTER_NAME'] = environ[b'GIT_AUTHOR_NAME']
255     environ[b'GIT_AUTHOR_EMAIL'] = b'bup@a425bc70a02811e49bdf73ee56450e6f'
256     environ[b'GIT_COMMITTER_EMAIL'] = environ[b'GIT_AUTHOR_EMAIL']
257     try:
258         environ[b'GIT_DIR'] = environ[b'BUP_DIR'] = repodir
259         readpipe([b'git', b'init', workdir])
260         exc(b'git', b'symbolic-ref', b'HEAD', b'refs/heads/main')
261         git.check_repo_or_die(repodir)
262         os.chdir(workdir)
263         with open('foo', 'w') as f:
264             print('bar', file=f)
265         readpipe([b'git', b'add', b'.'])
266         readpipe([b'git', b'commit', b'-am', b'Do something',
267                   b'--author', b'Someone <someone@somewhere>',
268                   b'--date', b'Sat Oct 3 19:48:49 2009 -0400'])
269         commit = readpipe([b'git', b'show-ref', b'-s', b'main']).strip()
270         parents = showval(commit, b'%P')
271         tree = showval(commit, b'%T')
272         cname = showval(commit, b'%cn')
273         cmail = showval(commit, b'%ce')
274         cdate = showval(commit, b'%ct')
275         coffs = showval(commit, b'%ci')
276         coffs = coffs[-5:]
277         coff = (int(coffs[-4:-2]) * 60 * 60) + (int(coffs[-2:]) * 60)
278         if bytes_from_byte(coffs[-5]) == b'-':
279             coff = - coff
280         commit_items = git.get_commit_items(commit, git.cp())
281         WVPASSEQ(commit_items.parents, [])
282         WVPASSEQ(commit_items.tree, tree)
283         WVPASSEQ(commit_items.author_name, b'Someone')
284         WVPASSEQ(commit_items.author_mail, b'someone@somewhere')
285         WVPASSEQ(commit_items.author_sec, 1254613729)
286         WVPASSEQ(commit_items.author_offset, -(4 * 60 * 60))
287         WVPASSEQ(commit_items.committer_name, cname)
288         WVPASSEQ(commit_items.committer_mail, cmail)
289         WVPASSEQ(commit_items.committer_sec, int(cdate))
290         WVPASSEQ(commit_items.committer_offset, coff)
291         WVPASSEQ(commit_items.message, b'Do something\n')
292         with open(b'bar', 'wb') as f:
293             f.write(b'baz\n')
294         readpipe([b'git', b'add', '.'])
295         readpipe([b'git', b'commit', b'-am', b'Do something else'])
296         child = readpipe([b'git', b'show-ref', b'-s', b'main']).strip()
297         parents = showval(child, b'%P')
298         commit_items = git.get_commit_items(child, git.cp())
299         WVPASSEQ(commit_items.parents, [commit])
300     finally:
301         os.chdir(orig_cwd)
302         restore_env_var(b'GIT_AUTHOR_NAME', orig_author_name)
303         restore_env_var(b'GIT_AUTHOR_EMAIL', orig_author_email)
304         restore_env_var(b'GIT_COMMITTER_NAME', orig_committer_name)
305         restore_env_var(b'GIT_COMMITTER_EMAIL', orig_committer_email)
306
307
308 gpgsig_example_1 = b'''tree 3fab08ade2fbbda60bef180bb8e0cc5724d6bd4d
309 parent 36db87b46a95ca5079f43dfe9b72220acab7c731
310 author Rob Browning <rlb@defaultvalue.org> 1633397238 -0500
311 committer Rob Browning <rlb@defaultvalue.org> 1633397238 -0500
312 gpgsig -----BEGIN PGP SIGNATURE-----
313  
314  ...
315  -----END PGP SIGNATURE-----
316
317 Sample signed commit.
318 '''
319
320 gpgsig_example_2 = b'''tree 3fab08ade2fbbda60bef180bb8e0cc5724d6bd4d
321 parent 36db87b46a95ca5079f43dfe9b72220acab7c731
322 author Rob Browning <rlb@defaultvalue.org> 1633397238 -0500
323 committer Rob Browning <rlb@defaultvalue.org> 1633397238 -0500
324 gpgsig -----BEGIN PGP SIGNATURE-----
325  
326  ...
327  -----END PGP SIGNATURE-----
328  
329
330 Sample signed commit.
331 '''
332
333 def test_commit_gpgsig_parsing():
334     c = git.parse_commit(gpgsig_example_1)
335     assert c.gpgsig
336     assert c.gpgsig.startswith(b'-----BEGIN PGP SIGNATURE-----\n')
337     assert c.gpgsig.endswith(b'\n-----END PGP SIGNATURE-----\n')
338     c = git.parse_commit(gpgsig_example_2)
339     assert c.gpgsig
340     assert c.gpgsig.startswith(b'-----BEGIN PGP SIGNATURE-----')
341     assert c.gpgsig.endswith(b'\n-----END PGP SIGNATURE-----\n\n')
342
343
344 def test_new_commit(tmpdir):
345     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
346     git.init_repo(bupdir)
347     git.verbose = 1
348
349     w = git.PackWriter()
350     tree = os.urandom(20)
351     parent = os.urandom(20)
352     author_name = b'Author'
353     author_mail = b'author@somewhere'
354     adate_sec = 1439657836
355     cdate_sec = adate_sec + 1
356     committer_name = b'Committer'
357     committer_mail = b'committer@somewhere'
358     adate_tz_sec = cdate_tz_sec = None
359     commit = w.new_commit(tree, parent,
360                           b'%s <%s>' % (author_name, author_mail),
361                           adate_sec, adate_tz_sec,
362                           b'%s <%s>' % (committer_name, committer_mail),
363                           cdate_sec, cdate_tz_sec,
364                           b'There is a small mailbox here')
365     adate_tz_sec = -60 * 60
366     cdate_tz_sec = 120 * 60
367     commit_off = w.new_commit(tree, parent,
368                               b'%s <%s>' % (author_name, author_mail),
369                               adate_sec, adate_tz_sec,
370                               b'%s <%s>' % (committer_name, committer_mail),
371                               cdate_sec, cdate_tz_sec,
372                               b'There is a small mailbox here')
373     w.close()
374
375     commit_items = git.get_commit_items(hexlify(commit), git.cp())
376     local_author_offset = localtime(adate_sec).tm_gmtoff
377     local_committer_offset = localtime(cdate_sec).tm_gmtoff
378     WVPASSEQ(tree, unhexlify(commit_items.tree))
379     WVPASSEQ(1, len(commit_items.parents))
380     WVPASSEQ(parent, unhexlify(commit_items.parents[0]))
381     WVPASSEQ(author_name, commit_items.author_name)
382     WVPASSEQ(author_mail, commit_items.author_mail)
383     WVPASSEQ(adate_sec, commit_items.author_sec)
384     WVPASSEQ(local_author_offset, commit_items.author_offset)
385     WVPASSEQ(committer_name, commit_items.committer_name)
386     WVPASSEQ(committer_mail, commit_items.committer_mail)
387     WVPASSEQ(cdate_sec, commit_items.committer_sec)
388     WVPASSEQ(local_committer_offset, commit_items.committer_offset)
389
390     commit_items = git.get_commit_items(hexlify(commit_off), git.cp())
391     WVPASSEQ(tree, unhexlify(commit_items.tree))
392     WVPASSEQ(1, len(commit_items.parents))
393     WVPASSEQ(parent, unhexlify(commit_items.parents[0]))
394     WVPASSEQ(author_name, commit_items.author_name)
395     WVPASSEQ(author_mail, commit_items.author_mail)
396     WVPASSEQ(adate_sec, commit_items.author_sec)
397     WVPASSEQ(adate_tz_sec, commit_items.author_offset)
398     WVPASSEQ(committer_name, commit_items.committer_name)
399     WVPASSEQ(committer_mail, commit_items.committer_mail)
400     WVPASSEQ(cdate_sec, commit_items.committer_sec)
401     WVPASSEQ(cdate_tz_sec, commit_items.committer_offset)
402
403
404 def test_list_refs(tmpdir):
405     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
406     src = tmpdir + b'/src'
407     mkdirp(src)
408     with open(src + b'/1', 'wb+') as f:
409         f.write(b'something\n')
410     with open(src + b'/2', 'wb+') as f:
411         f.write(b'something else\n')
412     git.init_repo(bupdir)
413     emptyset = frozenset()
414     WVPASSEQ(frozenset(git.list_refs()), emptyset)
415     WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset)
416     WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), emptyset)
417     exc(bup_exe, b'index', src)
418     exc(bup_exe, b'save', b'-n', b'src', b'--strip', src)
419     src_hash = exo(b'git', b'--git-dir', bupdir,
420                    b'rev-parse', b'src').strip().split(b'\n')
421     assert(len(src_hash) == 1)
422     src_hash = unhexlify(src_hash[0])
423     tree_hash = unhexlify(exo(b'git', b'--git-dir', bupdir,
424                               b'rev-parse',
425                               b'src:').strip().split(b'\n')[0])
426     blob_hash = unhexlify(exo(b'git', b'--git-dir', bupdir,
427                               b'rev-parse',
428                               b'src:1').strip().split(b'\n')[0])
429     WVPASSEQ(frozenset(git.list_refs()),
430              frozenset([(b'refs/heads/src', src_hash)]))
431     WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset)
432     WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)),
433              frozenset([(b'refs/heads/src', src_hash)]))
434     exc(b'git', b'--git-dir', bupdir, b'tag', b'commit-tag', b'src')
435     WVPASSEQ(frozenset(git.list_refs()),
436              frozenset([(b'refs/heads/src', src_hash),
437                         (b'refs/tags/commit-tag', src_hash)]))
438     WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)),
439              frozenset([(b'refs/tags/commit-tag', src_hash)]))
440     WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)),
441              frozenset([(b'refs/heads/src', src_hash)]))
442     exc(b'git', b'--git-dir', bupdir, b'tag', b'tree-tag', b'src:')
443     exc(b'git', b'--git-dir', bupdir, b'tag', b'blob-tag', b'src:1')
444     os.unlink(bupdir + b'/refs/heads/src')
445     expected_tags = frozenset([(b'refs/tags/commit-tag', src_hash),
446                                (b'refs/tags/tree-tag', tree_hash),
447                                (b'refs/tags/blob-tag', blob_hash)])
448     WVPASSEQ(frozenset(git.list_refs()), expected_tags)
449     WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([]))
450     WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), expected_tags)
451
452
453 def test_git_date_str():
454     WVPASSEQ(b'0 +0000', git._git_date_str(0, 0))
455     WVPASSEQ(b'0 -0130', git._git_date_str(0, -90 * 60))
456     WVPASSEQ(b'0 +0130', git._git_date_str(0, 90 * 60))
457
458
459 def test_cat_pipe(tmpdir):
460     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
461     src = tmpdir + b'/src'
462     mkdirp(src)
463     with open(src + b'/1', 'wb+') as f:
464         f.write(b'something\n')
465     with open(src + b'/2', 'wb+') as f:
466         f.write(b'something else\n')
467     git.init_repo(bupdir)
468     exc(bup_exe, b'index', src)
469     oidx = exo(bup_exe, b'save', b'-cn', b'src', b'--strip',
470                src).strip()
471     typ = exo(b'git', b'--git-dir', bupdir,
472               b'cat-file', b'-t', b'src').strip()
473     size = int(exo(b'git', b'--git-dir', bupdir,
474                        b'cat-file', b'-s', b'src'))
475     it = git.cp().get(b'src')
476     get_info = next(it)
477     for buf in next(it):
478         pass
479     WVPASSEQ((oidx, typ, size), get_info)
480
481 def _create_idx(d, i):
482     idx = git.PackIdxV2Writer()
483     # add 255 vaguely reasonable entries
484     for s in range(255):
485         idx.add(struct.pack('18xBB', i, s), s, 100 * s)
486     packbin = struct.pack('B19x', i)
487     packname = os.path.join(d, b'pack-%s.idx' % hexlify(packbin))
488     idx.write(packname, packbin)
489
490 def test_midx_close(tmpdir):
491     fddir = b'/proc/self/fd'
492     try:
493         os.listdir(fddir)
494     except Exception:
495         # not supported, not Linux, I guess
496         return
497
498     def openfiles():
499         for fd in os.listdir(fddir):
500             try:
501                 yield os.readlink(os.path.join(fddir, fd))
502             except OSError:
503                 pass
504
505     def force_midx(objdir):
506         args = [path.exe(), b'midx', b'--auto', b'--dir', objdir]
507         check_call(args)
508
509     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
510     git.init_repo(bupdir)
511     # create a few dummy idxes
512     for i in range(10):
513         _create_idx(tmpdir, i)
514     git.auto_midx(tmpdir)
515     l = git.PackIdxList(tmpdir)
516     # this doesn't exist (yet)
517     WVPASSEQ(None, l.exists(struct.pack('18xBB', 10, 0)))
518     for i in range(10, 15):
519         _create_idx(tmpdir, i)
520     # delete the midx ...
521     # TODO: why do we need to? git.auto_midx() below doesn't?!
522     for fn in os.listdir(tmpdir):
523         if fn.endswith(b'.midx'):
524             os.unlink(os.path.join(tmpdir, fn))
525     # and make a new one
526     git.auto_midx(tmpdir)
527     # check it still doesn't exist - we haven't refreshed
528     WVPASSEQ(None, l.exists(struct.pack('18xBB', 10, 0)))
529     # check that we still have the midx open, this really
530     # just checks more for the kernel API ('deleted' string)
531     for fn in openfiles():
532         if not b'midx-' in fn:
533             continue
534         WVPASSEQ(True, b'deleted' in fn)
535     # refresh the PackIdxList
536     l.refresh()
537     # and check that an object in pack 10 exists now
538     WVPASSEQ(True, l.exists(struct.pack('18xBB', 10, 0)))
539     for fn in openfiles():
540         if not b'midx-' in fn:
541             continue
542         # check that we don't have it open anymore
543         WVPASSEQ(False, b'deleted' in fn)
544
545 def test_config():
546     cfg_file = os.path.join(os.path.dirname(__file__), 'sample.conf')
547     no_such_file = os.path.join(os.path.dirname(__file__), 'nosuch.conf')
548     git_config_get = partial(git.git_config_get, cfg_file=cfg_file)
549     WVPASSEQ(git_config_get(b'bup.foo'), b'bar')
550     WVPASSEQ(git_config_get(b'bup.bup'), b'is great')
551     WVPASSEQ(git_config_get(b'bup.end'), b'end')
552     WVPASSEQ(git_config_get(b'bup.comments'), None)
553     WVPASSEQ(git_config_get(b'bup.;comments'), None)
554     WVPASSEQ(git_config_get(b'bup.and'), None)
555     WVPASSEQ(git_config_get(b'bup.#and'), None)
556
557     WVPASSEQ(git.git_config_get(b'bup.foo', cfg_file=no_such_file), None)
558
559     WVEXCEPT(git.GitError, git_config_get, b'bup.isbad', opttype='bool')
560     WVEXCEPT(git.GitError, git_config_get, b'bup.isbad', opttype='int')
561     WVPASSEQ(git_config_get(b'bup.isbad'), b'ok')
562     WVPASSEQ(True, git_config_get(b'bup.istrue1', opttype='bool'))
563     WVPASSEQ(True, git_config_get(b'bup.istrue2', opttype='bool'))
564     WVPASSEQ(True, git_config_get(b'bup.istrue3', opttype='bool'))
565     WVPASSEQ(False, git_config_get(b'bup.isfalse1', opttype='bool'))
566     WVPASSEQ(False, git_config_get(b'bup.isfalse2', opttype='bool'))
567     WVPASSEQ(None, git_config_get(b'bup.nosuchkey', opttype='bool'))
568     WVPASSEQ(1, git_config_get(b'bup.istrue1', opttype='int'))
569     WVPASSEQ(2, git_config_get(b'bup.istrue2', opttype='int'))
570     WVPASSEQ(0, git_config_get(b'bup.isfalse2', opttype='int'))
571     WVPASSEQ(0x777, git_config_get(b'bup.hex', opttype='int'))