]> arthur.ath.cx Git - bup.git/blob - test/int/test_git.py
616fc6e70451cd7626383ec0c095f79ada36a634
[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     with git.PackWriter() as w:
121         w.new_blob(os.urandom(100))
122         w.new_blob(os.urandom(100))
123         w.abort()
124
125     with git.PackWriter() as w:
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     with git.open_idx(nameprefix + b'.idx') as r:
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     with git.PackIdxList(bupdir + b'/objects/pack') as r:
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         with git.PackWriter() as w:
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     with git.PackIdxList(packdir) as r:
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     with git.PackWriter() as w:
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
374     commit_items = git.get_commit_items(hexlify(commit), git.cp())
375     local_author_offset = localtime(adate_sec).tm_gmtoff
376     local_committer_offset = localtime(cdate_sec).tm_gmtoff
377     WVPASSEQ(tree, unhexlify(commit_items.tree))
378     WVPASSEQ(1, len(commit_items.parents))
379     WVPASSEQ(parent, unhexlify(commit_items.parents[0]))
380     WVPASSEQ(author_name, commit_items.author_name)
381     WVPASSEQ(author_mail, commit_items.author_mail)
382     WVPASSEQ(adate_sec, commit_items.author_sec)
383     WVPASSEQ(local_author_offset, commit_items.author_offset)
384     WVPASSEQ(committer_name, commit_items.committer_name)
385     WVPASSEQ(committer_mail, commit_items.committer_mail)
386     WVPASSEQ(cdate_sec, commit_items.committer_sec)
387     WVPASSEQ(local_committer_offset, commit_items.committer_offset)
388
389     commit_items = git.get_commit_items(hexlify(commit_off), git.cp())
390     WVPASSEQ(tree, unhexlify(commit_items.tree))
391     WVPASSEQ(1, len(commit_items.parents))
392     WVPASSEQ(parent, unhexlify(commit_items.parents[0]))
393     WVPASSEQ(author_name, commit_items.author_name)
394     WVPASSEQ(author_mail, commit_items.author_mail)
395     WVPASSEQ(adate_sec, commit_items.author_sec)
396     WVPASSEQ(adate_tz_sec, commit_items.author_offset)
397     WVPASSEQ(committer_name, commit_items.committer_name)
398     WVPASSEQ(committer_mail, commit_items.committer_mail)
399     WVPASSEQ(cdate_sec, commit_items.committer_sec)
400     WVPASSEQ(cdate_tz_sec, commit_items.committer_offset)
401
402
403 def test_list_refs(tmpdir):
404     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
405     src = tmpdir + b'/src'
406     mkdirp(src)
407     with open(src + b'/1', 'wb+') as f:
408         f.write(b'something\n')
409     with open(src + b'/2', 'wb+') as f:
410         f.write(b'something else\n')
411     git.init_repo(bupdir)
412     emptyset = frozenset()
413     WVPASSEQ(frozenset(git.list_refs()), emptyset)
414     WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset)
415     WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), emptyset)
416     exc(bup_exe, b'index', src)
417     exc(bup_exe, b'save', b'-n', b'src', b'--strip', src)
418     src_hash = exo(b'git', b'--git-dir', bupdir,
419                    b'rev-parse', b'src').strip().split(b'\n')
420     assert(len(src_hash) == 1)
421     src_hash = unhexlify(src_hash[0])
422     tree_hash = unhexlify(exo(b'git', b'--git-dir', bupdir,
423                               b'rev-parse',
424                               b'src:').strip().split(b'\n')[0])
425     blob_hash = unhexlify(exo(b'git', b'--git-dir', bupdir,
426                               b'rev-parse',
427                               b'src:1').strip().split(b'\n')[0])
428     WVPASSEQ(frozenset(git.list_refs()),
429              frozenset([(b'refs/heads/src', src_hash)]))
430     WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset)
431     WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)),
432              frozenset([(b'refs/heads/src', src_hash)]))
433     exc(b'git', b'--git-dir', bupdir, b'tag', b'commit-tag', b'src')
434     WVPASSEQ(frozenset(git.list_refs()),
435              frozenset([(b'refs/heads/src', src_hash),
436                         (b'refs/tags/commit-tag', src_hash)]))
437     WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)),
438              frozenset([(b'refs/tags/commit-tag', src_hash)]))
439     WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)),
440              frozenset([(b'refs/heads/src', src_hash)]))
441     exc(b'git', b'--git-dir', bupdir, b'tag', b'tree-tag', b'src:')
442     exc(b'git', b'--git-dir', bupdir, b'tag', b'blob-tag', b'src:1')
443     os.unlink(bupdir + b'/refs/heads/src')
444     expected_tags = frozenset([(b'refs/tags/commit-tag', src_hash),
445                                (b'refs/tags/tree-tag', tree_hash),
446                                (b'refs/tags/blob-tag', blob_hash)])
447     WVPASSEQ(frozenset(git.list_refs()), expected_tags)
448     WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([]))
449     WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), expected_tags)
450
451
452 def test_git_date_str():
453     WVPASSEQ(b'0 +0000', git._git_date_str(0, 0))
454     WVPASSEQ(b'0 -0130', git._git_date_str(0, -90 * 60))
455     WVPASSEQ(b'0 +0130', git._git_date_str(0, 90 * 60))
456
457
458 def test_cat_pipe(tmpdir):
459     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
460     src = tmpdir + b'/src'
461     mkdirp(src)
462     with open(src + b'/1', 'wb+') as f:
463         f.write(b'something\n')
464     with open(src + b'/2', 'wb+') as f:
465         f.write(b'something else\n')
466     git.init_repo(bupdir)
467     exc(bup_exe, b'index', src)
468     oidx = exo(bup_exe, b'save', b'-cn', b'src', b'--strip',
469                src).strip()
470     typ = exo(b'git', b'--git-dir', bupdir,
471               b'cat-file', b'-t', b'src').strip()
472     size = int(exo(b'git', b'--git-dir', bupdir,
473                        b'cat-file', b'-s', b'src'))
474     it = git.cp().get(b'src')
475     get_info = next(it)
476     for buf in next(it):
477         pass
478     WVPASSEQ((oidx, typ, size), get_info)
479
480 def _create_idx(d, i):
481     idx = git.PackIdxV2Writer()
482     # add 255 vaguely reasonable entries
483     for s in range(255):
484         idx.add(struct.pack('18xBB', i, s), s, 100 * s)
485     packbin = struct.pack('B19x', i)
486     packname = os.path.join(d, b'pack-%s.idx' % hexlify(packbin))
487     idx.write(packname, packbin)
488
489 def test_midx_close(tmpdir):
490     fddir = b'/proc/self/fd'
491     try:
492         os.listdir(fddir)
493     except Exception:
494         # not supported, not Linux, I guess
495         return
496
497     def openfiles():
498         for fd in os.listdir(fddir):
499             try:
500                 yield os.readlink(os.path.join(fddir, fd))
501             except OSError:
502                 pass
503
504     def force_midx(objdir):
505         args = [path.exe(), b'midx', b'--auto', b'--dir', objdir]
506         check_call(args)
507
508     environ[b'BUP_DIR'] = bupdir = tmpdir + b'/bup'
509     git.init_repo(bupdir)
510     # create a few dummy idxes
511     for i in range(10):
512         _create_idx(tmpdir, i)
513     git.auto_midx(tmpdir)
514     with git.PackIdxList(tmpdir) as l:
515     # this doesn't exist (yet)
516         WVPASSEQ(None, l.exists(struct.pack('18xBB', 10, 0)))
517         for i in range(10, 15):
518             _create_idx(tmpdir, i)
519         # delete the midx ...
520         # TODO: why do we need to? git.auto_midx() below doesn't?!
521         for fn in os.listdir(tmpdir):
522             if fn.endswith(b'.midx'):
523                 os.unlink(os.path.join(tmpdir, fn))
524         # and make a new one
525         git.auto_midx(tmpdir)
526         # check it still doesn't exist - we haven't refreshed
527         WVPASSEQ(None, l.exists(struct.pack('18xBB', 10, 0)))
528         # check that we still have the midx open, this really
529         # just checks more for the kernel API ('deleted' string)
530         for fn in openfiles():
531             if not b'midx-' in fn:
532                 continue
533             WVPASSEQ(True, b'deleted' in fn)
534         # refresh the PackIdxList
535         l.refresh()
536         # and check that an object in pack 10 exists now
537         WVPASSEQ(True, l.exists(struct.pack('18xBB', 10, 0)))
538         for fn in openfiles():
539             if not b'midx-' in fn:
540                 continue
541             # check that we don't have it open anymore
542             WVPASSEQ(False, b'deleted' in fn)
543
544 def test_config():
545     cfg_file = os.path.join(os.path.dirname(__file__), 'sample.conf')
546     no_such_file = os.path.join(os.path.dirname(__file__), 'nosuch.conf')
547     git_config_get = partial(git.git_config_get, cfg_file=cfg_file)
548     WVPASSEQ(git_config_get(b'bup.foo'), b'bar')
549     WVPASSEQ(git_config_get(b'bup.bup'), b'is great')
550     WVPASSEQ(git_config_get(b'bup.end'), b'end')
551     WVPASSEQ(git_config_get(b'bup.comments'), None)
552     WVPASSEQ(git_config_get(b'bup.;comments'), None)
553     WVPASSEQ(git_config_get(b'bup.and'), None)
554     WVPASSEQ(git_config_get(b'bup.#and'), None)
555
556     WVPASSEQ(git.git_config_get(b'bup.foo', cfg_file=no_such_file), None)
557
558     WVEXCEPT(git.GitError, git_config_get, b'bup.isbad', opttype='bool')
559     WVEXCEPT(git.GitError, git_config_get, b'bup.isbad', opttype='int')
560     WVPASSEQ(git_config_get(b'bup.isbad'), b'ok')
561     WVPASSEQ(True, git_config_get(b'bup.istrue1', opttype='bool'))
562     WVPASSEQ(True, git_config_get(b'bup.istrue2', opttype='bool'))
563     WVPASSEQ(True, git_config_get(b'bup.istrue3', opttype='bool'))
564     WVPASSEQ(False, git_config_get(b'bup.isfalse1', opttype='bool'))
565     WVPASSEQ(False, git_config_get(b'bup.isfalse2', opttype='bool'))
566     WVPASSEQ(None, git_config_get(b'bup.nosuchkey', opttype='bool'))
567     WVPASSEQ(1, git_config_get(b'bup.istrue1', opttype='int'))
568     WVPASSEQ(2, git_config_get(b'bup.istrue2', opttype='int'))
569     WVPASSEQ(0, git_config_get(b'bup.isfalse2', opttype='int'))
570     WVPASSEQ(0x777, git_config_get(b'bup.hex', opttype='int'))