]> arthur.barton.de Git - bup.git/blob - lib/bup/t/tgit.py
Check saved_errors before and after every test
[bup.git] / lib / bup / t / tgit.py
1
2 from subprocess import check_call
3 import struct, os, time
4
5 from wvtest import *
6
7 from bup import git
8 from bup.helpers import localtime, log, mkdirp, readpipe
9 from buptest import no_lingering_errors, test_tempdir
10
11
12 top_dir = os.path.realpath('../../..')
13 bup_exe = top_dir + '/bup'
14
15
16 def exc(*cmd):
17     cmd_str = ' '.join(cmd)
18     print >> sys.stderr, cmd_str
19     check_call(cmd)
20
21
22 def exo(*cmd):
23     cmd_str = ' '.join(cmd)
24     print >> sys.stderr, cmd_str
25     return readpipe(cmd)
26
27
28 @wvtest
29 def testmangle():
30     with no_lingering_errors():
31         afile  = 0100644
32         afile2 = 0100770
33         alink  = 0120000
34         adir   = 0040000
35         adir2  = 0040777
36         WVPASSEQ(git.mangle_name("a", adir2, adir), "a")
37         WVPASSEQ(git.mangle_name(".bup", adir2, adir), ".bup.bupl")
38         WVPASSEQ(git.mangle_name("a.bupa", adir2, adir), "a.bupa.bupl")
39         WVPASSEQ(git.mangle_name("b.bup", alink, alink), "b.bup.bupl")
40         WVPASSEQ(git.mangle_name("b.bu", alink, alink), "b.bu")
41         WVPASSEQ(git.mangle_name("f", afile, afile2), "f")
42         WVPASSEQ(git.mangle_name("f.bup", afile, afile2), "f.bup.bupl")
43         WVPASSEQ(git.mangle_name("f.bup", afile, adir), "f.bup.bup")
44         WVPASSEQ(git.mangle_name("f", afile, adir), "f.bup")
45
46         WVPASSEQ(git.demangle_name("f.bup", afile), ("f", git.BUP_CHUNKED))
47         WVPASSEQ(git.demangle_name("f.bupl", afile), ("f", git.BUP_NORMAL))
48         WVPASSEQ(git.demangle_name("f.bup.bupl", afile), ("f.bup", git.BUP_NORMAL))
49
50         WVPASSEQ(git.demangle_name(".bupm", afile), ('', git.BUP_NORMAL))
51         WVPASSEQ(git.demangle_name(".bupm", adir), ('', git.BUP_CHUNKED))
52
53         # for safety, we ignore .bup? suffixes we don't recognize.  Future
54         # versions might implement a .bup[a-z] extension as something other
55         # than BUP_NORMAL.
56         WVPASSEQ(git.demangle_name("f.bupa", afile), ("f.bupa", git.BUP_NORMAL))
57
58
59 @wvtest
60 def testencode():
61     with no_lingering_errors():
62         s = 'hello world'
63         looseb = ''.join(git._encode_looseobj('blob', s))
64         looset = ''.join(git._encode_looseobj('tree', s))
65         loosec = ''.join(git._encode_looseobj('commit', s))
66         packb = ''.join(git._encode_packobj('blob', s))
67         packt = ''.join(git._encode_packobj('tree', s))
68         packc = ''.join(git._encode_packobj('commit', s))
69         WVPASSEQ(git._decode_looseobj(looseb), ('blob', s))
70         WVPASSEQ(git._decode_looseobj(looset), ('tree', s))
71         WVPASSEQ(git._decode_looseobj(loosec), ('commit', s))
72         WVPASSEQ(git._decode_packobj(packb), ('blob', s))
73         WVPASSEQ(git._decode_packobj(packt), ('tree', s))
74         WVPASSEQ(git._decode_packobj(packc), ('commit', s))
75
76
77 @wvtest
78 def testpacks():
79     with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir:
80         os.environ['BUP_MAIN_EXE'] = bup_exe
81         os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup"
82         git.init_repo(bupdir)
83         git.verbose = 1
84
85         w = git.PackWriter()
86         w.new_blob(os.urandom(100))
87         w.new_blob(os.urandom(100))
88         w.abort()
89
90         w = git.PackWriter()
91         hashes = []
92         nobj = 1000
93         for i in range(nobj):
94             hashes.append(w.new_blob(str(i)))
95         log('\n')
96         nameprefix = w.close()
97         print repr(nameprefix)
98         WVPASS(os.path.exists(nameprefix + '.pack'))
99         WVPASS(os.path.exists(nameprefix + '.idx'))
100
101         r = git.open_idx(nameprefix + '.idx')
102         print repr(r.fanout)
103
104         for i in range(nobj):
105             WVPASS(r.find_offset(hashes[i]) > 0)
106         WVPASS(r.exists(hashes[99]))
107         WVFAIL(r.exists('\0'*20))
108
109         pi = iter(r)
110         for h in sorted(hashes):
111             WVPASSEQ(str(pi.next()).encode('hex'), h.encode('hex'))
112
113         WVFAIL(r.find_offset('\0'*20))
114
115         r = git.PackIdxList(bupdir + '/objects/pack')
116         WVPASS(r.exists(hashes[5]))
117         WVPASS(r.exists(hashes[6]))
118         WVFAIL(r.exists('\0'*20))
119
120
121 @wvtest
122 def test_pack_name_lookup():
123     with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir:
124         os.environ['BUP_MAIN_EXE'] = bup_exe
125         os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup"
126         git.init_repo(bupdir)
127         git.verbose = 1
128         packdir = git.repo('objects/pack')
129
130         idxnames = []
131         hashes = []
132
133         for start in range(0,28,2):
134             w = git.PackWriter()
135             for i in range(start, start+2):
136                 hashes.append(w.new_blob(str(i)))
137             log('\n')
138             idxnames.append(os.path.basename(w.close() + '.idx'))
139
140         r = git.PackIdxList(packdir)
141         WVPASSEQ(len(r.packs), 2)
142         for e,idxname in enumerate(idxnames):
143             for i in range(e*2, (e+1)*2):
144                 WVPASSEQ(r.exists(hashes[i], want_source=True), idxname)
145
146
147 @wvtest
148 def test_long_index():
149     with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir:
150         os.environ['BUP_MAIN_EXE'] = bup_exe
151         os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup"
152         git.init_repo(bupdir)
153         w = git.PackWriter()
154         obj_bin = struct.pack('!IIIII',
155                 0x00112233, 0x44556677, 0x88990011, 0x22334455, 0x66778899)
156         obj2_bin = struct.pack('!IIIII',
157                 0x11223344, 0x55667788, 0x99001122, 0x33445566, 0x77889900)
158         obj3_bin = struct.pack('!IIIII',
159                 0x22334455, 0x66778899, 0x00112233, 0x44556677, 0x88990011)
160         pack_bin = struct.pack('!IIIII',
161                 0x99887766, 0x55443322, 0x11009988, 0x77665544, 0x33221100)
162         idx = list(list() for i in xrange(256))
163         idx[0].append((obj_bin, 1, 0xfffffffff))
164         idx[0x11].append((obj2_bin, 2, 0xffffffffff))
165         idx[0x22].append((obj3_bin, 3, 0xff))
166         w.count = 3
167         name = tmpdir + '/tmp.idx'
168         r = w._write_pack_idx_v2(name, idx, pack_bin)
169         i = git.PackIdxV2(name, open(name, 'rb'))
170         WVPASSEQ(i.find_offset(obj_bin), 0xfffffffff)
171         WVPASSEQ(i.find_offset(obj2_bin), 0xffffffffff)
172         WVPASSEQ(i.find_offset(obj3_bin), 0xff)
173
174
175 @wvtest
176 def test_check_repo_or_die():
177     with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir:
178         os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup"
179         orig_cwd = os.getcwd()
180         try:
181             os.chdir(tmpdir)
182             git.init_repo(bupdir)
183             git.check_repo_or_die()
184             WVPASS('check_repo_or_die')  # if we reach this point the call above passed
185
186             os.rename(bupdir + '/objects/pack', bupdir + '/objects/pack.tmp')
187             open(bupdir + '/objects/pack', 'w').close()
188             try:
189                 git.check_repo_or_die()
190             except SystemExit as e:
191                 WVPASSEQ(e.code, 14)
192             else:
193                 WVFAIL()
194             os.unlink(bupdir + '/objects/pack')
195             os.rename(bupdir + '/objects/pack.tmp', bupdir + '/objects/pack')
196
197             try:
198                 git.check_repo_or_die('nonexistantbup.tmp')
199             except SystemExit as e:
200                 WVPASSEQ(e.code, 15)
201             else:
202                 WVFAIL()
203         finally:
204             os.chdir(orig_cwd)
205
206
207 @wvtest
208 def test_commit_parsing():
209
210     def restore_env_var(name, val):
211         if val is None:
212             del os.environ[name]
213         else:
214             os.environ[name] = val
215
216     def showval(commit, val):
217         return readpipe(['git', 'show', '-s',
218                          '--pretty=format:%s' % val, commit]).strip()
219
220     with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir:
221         orig_cwd = os.getcwd()
222         workdir = tmpdir + "/work"
223         repodir = workdir + '/.git'
224         orig_author_name = os.environ.get('GIT_AUTHOR_NAME')
225         orig_author_email = os.environ.get('GIT_AUTHOR_EMAIL')
226         orig_committer_name = os.environ.get('GIT_COMMITTER_NAME')
227         orig_committer_email = os.environ.get('GIT_COMMITTER_EMAIL')
228         os.environ['GIT_AUTHOR_NAME'] = 'bup test'
229         os.environ['GIT_COMMITTER_NAME'] = os.environ['GIT_AUTHOR_NAME']
230         os.environ['GIT_AUTHOR_EMAIL'] = 'bup@a425bc70a02811e49bdf73ee56450e6f'
231         os.environ['GIT_COMMITTER_EMAIL'] = os.environ['GIT_AUTHOR_EMAIL']
232         try:
233             readpipe(['git', 'init', workdir])
234             os.environ['GIT_DIR'] = os.environ['BUP_DIR'] = repodir
235             git.check_repo_or_die(repodir)
236             os.chdir(workdir)
237             with open('foo', 'w') as f:
238                 print >> f, 'bar'
239             readpipe(['git', 'add', '.'])
240             readpipe(['git', 'commit', '-am', 'Do something',
241                       '--author', 'Someone <someone@somewhere>',
242                       '--date', 'Sat Oct 3 19:48:49 2009 -0400'])
243             commit = readpipe(['git', 'show-ref', '-s', 'master']).strip()
244             parents = showval(commit, '%P')
245             tree = showval(commit, '%T')
246             cname = showval(commit, '%cn')
247             cmail = showval(commit, '%ce')
248             cdate = showval(commit, '%ct')
249             coffs = showval(commit, '%ci')
250             coffs = coffs[-5:]
251             coff = (int(coffs[-4:-2]) * 60 * 60) + (int(coffs[-2:]) * 60)
252             if coffs[-5] == '-':
253                 coff = - coff
254             commit_items = git.get_commit_items(commit, git.cp())
255             WVPASSEQ(commit_items.parents, [])
256             WVPASSEQ(commit_items.tree, tree)
257             WVPASSEQ(commit_items.author_name, 'Someone')
258             WVPASSEQ(commit_items.author_mail, 'someone@somewhere')
259             WVPASSEQ(commit_items.author_sec, 1254613729)
260             WVPASSEQ(commit_items.author_offset, -(4 * 60 * 60))
261             WVPASSEQ(commit_items.committer_name, cname)
262             WVPASSEQ(commit_items.committer_mail, cmail)
263             WVPASSEQ(commit_items.committer_sec, int(cdate))
264             WVPASSEQ(commit_items.committer_offset, coff)
265             WVPASSEQ(commit_items.message, 'Do something\n')
266             with open('bar', 'w') as f:
267                 print >> f, 'baz'
268             readpipe(['git', 'add', '.'])
269             readpipe(['git', 'commit', '-am', 'Do something else'])
270             child = readpipe(['git', 'show-ref', '-s', 'master']).strip()
271             parents = showval(child, '%P')
272             commit_items = git.get_commit_items(child, git.cp())
273             WVPASSEQ(commit_items.parents, [commit])
274         finally:
275             os.chdir(orig_cwd)
276             restore_env_var('GIT_AUTHOR_NAME', orig_author_name)
277             restore_env_var('GIT_AUTHOR_EMAIL', orig_author_email)
278             restore_env_var('GIT_COMMITTER_NAME', orig_committer_name)
279             restore_env_var('GIT_COMMITTER_EMAIL', orig_committer_email)
280
281
282 @wvtest
283 def test_new_commit():
284     with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir:
285         os.environ['BUP_MAIN_EXE'] = bup_exe
286         os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup"
287         git.init_repo(bupdir)
288         git.verbose = 1
289
290         w = git.PackWriter()
291         tree = os.urandom(20)
292         parent = os.urandom(20)
293         author_name = 'Author'
294         author_mail = 'author@somewhere'
295         adate_sec = 1439657836
296         cdate_sec = adate_sec + 1
297         committer_name = 'Committer'
298         committer_mail = 'committer@somewhere'
299         adate_tz_sec = cdate_tz_sec = None
300         commit = w.new_commit(tree, parent,
301                               '%s <%s>' % (author_name, author_mail),
302                               adate_sec, adate_tz_sec,
303                               '%s <%s>' % (committer_name, committer_mail),
304                               cdate_sec, cdate_tz_sec,
305                               'There is a small mailbox here')
306         adate_tz_sec = -60 * 60
307         cdate_tz_sec = 120 * 60
308         commit_off = w.new_commit(tree, parent,
309                                   '%s <%s>' % (author_name, author_mail),
310                                   adate_sec, adate_tz_sec,
311                                   '%s <%s>' % (committer_name, committer_mail),
312                                   cdate_sec, cdate_tz_sec,
313                                   'There is a small mailbox here')
314         w.close()
315
316         commit_items = git.get_commit_items(commit.encode('hex'), git.cp())
317         local_author_offset = localtime(adate_sec).tm_gmtoff
318         local_committer_offset = localtime(cdate_sec).tm_gmtoff
319         WVPASSEQ(tree, commit_items.tree.decode('hex'))
320         WVPASSEQ(1, len(commit_items.parents))
321         WVPASSEQ(parent, commit_items.parents[0].decode('hex'))
322         WVPASSEQ(author_name, commit_items.author_name)
323         WVPASSEQ(author_mail, commit_items.author_mail)
324         WVPASSEQ(adate_sec, commit_items.author_sec)
325         WVPASSEQ(local_author_offset, commit_items.author_offset)
326         WVPASSEQ(committer_name, commit_items.committer_name)
327         WVPASSEQ(committer_mail, commit_items.committer_mail)
328         WVPASSEQ(cdate_sec, commit_items.committer_sec)
329         WVPASSEQ(local_committer_offset, commit_items.committer_offset)
330
331         commit_items = git.get_commit_items(commit_off.encode('hex'), git.cp())
332         WVPASSEQ(tree, commit_items.tree.decode('hex'))
333         WVPASSEQ(1, len(commit_items.parents))
334         WVPASSEQ(parent, commit_items.parents[0].decode('hex'))
335         WVPASSEQ(author_name, commit_items.author_name)
336         WVPASSEQ(author_mail, commit_items.author_mail)
337         WVPASSEQ(adate_sec, commit_items.author_sec)
338         WVPASSEQ(adate_tz_sec, commit_items.author_offset)
339         WVPASSEQ(committer_name, commit_items.committer_name)
340         WVPASSEQ(committer_mail, commit_items.committer_mail)
341         WVPASSEQ(cdate_sec, commit_items.committer_sec)
342         WVPASSEQ(cdate_tz_sec, commit_items.committer_offset)
343
344
345 @wvtest
346 def test_list_refs():
347     with no_lingering_errors(), test_tempdir('bup-tgit-') as tmpdir:
348         os.environ['BUP_MAIN_EXE'] = bup_exe
349         os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup"
350         src = tmpdir + '/src'
351         mkdirp(src)
352         with open(src + '/1', 'w+') as f:
353             print f, 'something'
354         with open(src + '/2', 'w+') as f:
355             print f, 'something else'
356         git.init_repo(bupdir)
357         emptyset = frozenset()
358         WVPASSEQ(frozenset(git.list_refs()), emptyset)
359         WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset)
360         WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), emptyset)
361         exc(bup_exe, 'index', src)
362         exc(bup_exe, 'save', '-n', 'src', '--strip', src)
363         src_hash = exo('git', '--git-dir', bupdir,
364                        'rev-parse', 'src').strip().split('\n')
365         assert(len(src_hash) == 1)
366         src_hash = src_hash[0].decode('hex')
367         tree_hash = exo('git', '--git-dir', bupdir,
368                        'rev-parse', 'src:').strip().split('\n')[0].decode('hex')
369         blob_hash = exo('git', '--git-dir', bupdir,
370                        'rev-parse', 'src:1').strip().split('\n')[0].decode('hex')
371         WVPASSEQ(frozenset(git.list_refs()),
372                  frozenset([('refs/heads/src', src_hash)]))
373         WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), emptyset)
374         WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)),
375                  frozenset([('refs/heads/src', src_hash)]))
376         exc('git', '--git-dir', bupdir, 'tag', 'commit-tag', 'src')
377         WVPASSEQ(frozenset(git.list_refs()),
378                  frozenset([('refs/heads/src', src_hash),
379                             ('refs/tags/commit-tag', src_hash)]))
380         WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)),
381                  frozenset([('refs/tags/commit-tag', src_hash)]))
382         WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)),
383                  frozenset([('refs/heads/src', src_hash)]))
384         exc('git', '--git-dir', bupdir, 'tag', 'tree-tag', 'src:')
385         exc('git', '--git-dir', bupdir, 'tag', 'blob-tag', 'src:1')
386         os.unlink(bupdir + '/refs/heads/src')
387         expected_tags = frozenset([('refs/tags/commit-tag', src_hash),
388                                    ('refs/tags/tree-tag', tree_hash),
389                                    ('refs/tags/blob-tag', blob_hash)])
390         WVPASSEQ(frozenset(git.list_refs()), expected_tags)
391         WVPASSEQ(frozenset(git.list_refs(limit_to_heads=True)), frozenset([]))
392         WVPASSEQ(frozenset(git.list_refs(limit_to_tags=True)), expected_tags)
393
394
395 def test__git_date_str():
396     with no_lingering_errors():
397         WVPASSEQ('0 +0000', git._git_date_str(0, 0))
398         WVPASSEQ('0 -0130', git._git_date_str(0, -90 * 60))
399         WVPASSEQ('0 +0130', git._git_date_str(0, 90 * 60))