]> arthur.barton.de Git - bup.git/blob - lib/bup/t/tindex.py
3ec4939e5a4b415a039d97284f2b295d5fd79ebf
[bup.git] / lib / bup / t / tindex.py
1 import os
2 import time, tempfile
3 from bup import index, metadata
4 from bup.helpers import *
5 import bup.xstat as xstat
6 from wvtest import *
7
8 lib_t_dir = os.getcwd()
9 bup_tmp = os.path.realpath('../../../t/tmp')
10 mkdirp(bup_tmp)
11
12 @wvtest
13 def index_basic():
14     cd = os.path.realpath('../../../t')
15     WVPASS(cd)
16     sd = os.path.realpath(cd + '/sampledata')
17     WVPASSEQ(index.realpath(cd + '/sampledata'), sd)
18     WVPASSEQ(os.path.realpath(cd + '/sampledata/x'), sd + '/x')
19     WVPASSEQ(os.path.realpath(cd + '/sampledata/abs-symlink'),
20              sd + '/abs-symlink-target')
21     WVPASSEQ(index.realpath(cd + '/sampledata/abs-symlink'),
22              sd + '/abs-symlink')
23
24
25 @wvtest
26 def index_writer():
27     initial_failures = wvfailure_count()
28     tmpdir = tempfile.mkdtemp(dir=bup_tmp, prefix='bup-tindex-')
29     orig_cwd = os.getcwd()
30     try:
31         os.chdir(tmpdir)
32         ds = xstat.stat('.')
33         fs = xstat.stat(lib_t_dir + '/tindex.py')
34         ms = index.MetaStoreWriter('index.meta.tmp');
35         tmax = (time.time() - 1) * 10**9
36         w = index.Writer('index.tmp', ms, tmax)
37         w.add('/var/tmp/sporky', fs, 0)
38         w.add('/etc/passwd', fs, 0)
39         w.add('/etc/', ds, 0)
40         w.add('/', ds, 0)
41         ms.close()
42         w.close()
43     finally:
44         os.chdir(orig_cwd)
45     if wvfailure_count() == initial_failures:
46         subprocess.call(['rm', '-rf', tmpdir])
47
48
49 def dump(m):
50     for e in list(m):
51         print '%s%s %s' % (e.is_valid() and ' ' or 'M',
52                            e.is_fake() and 'F' or ' ',
53                            e.name)
54
55 def fake_validate(*l):
56     for i in l:
57         for e in i:
58             e.validate(0100644, index.FAKE_SHA)
59             e.repack()
60
61 def eget(l, ename):
62     for e in l:
63         if e.name == ename:
64             return e
65
66 @wvtest
67 def index_negative_timestamps():
68     initial_failures = wvfailure_count()
69     tmpdir = tempfile.mkdtemp(dir=bup_tmp, prefix='bup-tindex-')
70     # Makes 'foo' exist
71     foopath = tmpdir + '/foo'
72     f = file(foopath, 'wb')
73     f.close()
74
75     # Dec 31, 1969
76     os.utime(foopath, (-86400, -86400))
77     ns_per_sec = 10**9
78     tstart = time.time() * ns_per_sec
79     tmax = tstart - ns_per_sec
80     e = index.BlankNewEntry(foopath, 0, tmax)
81     e.from_stat(xstat.stat(foopath), 0, tstart)
82     assert len(e.packed())
83     WVPASS()
84
85     # Jun 10, 1893
86     os.utime(foopath, (-0x80000000, -0x80000000))
87     e = index.BlankNewEntry(foopath, 0, tmax)
88     e.from_stat(xstat.stat(foopath), 0, tstart)
89     assert len(e.packed())
90     WVPASS()
91     if wvfailure_count() == initial_failures:
92         subprocess.call(['rm', '-rf', tmpdir])
93
94
95 @wvtest
96 def index_dirty():
97     initial_failures = wvfailure_count()
98     orig_cwd = os.getcwd()
99     tmpdir = tempfile.mkdtemp(dir=bup_tmp, prefix='bup-tindex-')
100     try:
101         os.chdir(tmpdir)
102         default_meta = metadata.Metadata()
103         ms1 = index.MetaStoreWriter('index.meta.tmp')
104         ms2 = index.MetaStoreWriter('index2.meta.tmp')
105         ms3 = index.MetaStoreWriter('index3.meta.tmp')
106         meta_ofs1 = ms1.store(default_meta)
107         meta_ofs2 = ms2.store(default_meta)
108         meta_ofs3 = ms3.store(default_meta)
109
110         ds = xstat.stat(lib_t_dir)
111         fs = xstat.stat(lib_t_dir + '/tindex.py')
112         tmax = (time.time() - 1) * 10**9
113
114         w1 = index.Writer('index.tmp', ms1, tmax)
115         w1.add('/a/b/x', fs, meta_ofs1)
116         w1.add('/a/b/c', fs, meta_ofs1)
117         w1.add('/a/b/', ds, meta_ofs1)
118         w1.add('/a/', ds, meta_ofs1)
119         #w1.close()
120         WVPASS()
121
122         w2 = index.Writer('index2.tmp', ms2, tmax)
123         w2.add('/a/b/n/2', fs, meta_ofs2)
124         #w2.close()
125         WVPASS()
126
127         w3 = index.Writer('index3.tmp', ms3, tmax)
128         w3.add('/a/c/n/3', fs, meta_ofs3)
129         #w3.close()
130         WVPASS()
131
132         r1 = w1.new_reader()
133         r2 = w2.new_reader()
134         r3 = w3.new_reader()
135         WVPASS()
136
137         r1all = [e.name for e in r1]
138         WVPASSEQ(r1all,
139                  ['/a/b/x', '/a/b/c', '/a/b/', '/a/', '/'])
140         r2all = [e.name for e in r2]
141         WVPASSEQ(r2all,
142                  ['/a/b/n/2', '/a/b/n/', '/a/b/', '/a/', '/'])
143         r3all = [e.name for e in r3]
144         WVPASSEQ(r3all,
145                  ['/a/c/n/3', '/a/c/n/', '/a/c/', '/a/', '/'])
146         all = [e.name for e in index.merge(r2, r1, r3)]
147         WVPASSEQ(all,
148                  ['/a/c/n/3', '/a/c/n/', '/a/c/',
149                   '/a/b/x', '/a/b/n/2', '/a/b/n/', '/a/b/c',
150                   '/a/b/', '/a/', '/'])
151         fake_validate(r1)
152         dump(r1)
153
154         print [hex(e.flags) for e in r1]
155         WVPASSEQ([e.name for e in r1 if e.is_valid()], r1all)
156         WVPASSEQ([e.name for e in r1 if not e.is_valid()], [])
157         WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()],
158                  ['/a/c/n/3', '/a/c/n/', '/a/c/',
159                   '/a/b/n/2', '/a/b/n/', '/a/b/', '/a/', '/'])
160
161         expect_invalid = ['/'] + r2all + r3all
162         expect_real = (set(r1all) - set(r2all) - set(r3all)) \
163                         | set(['/a/b/n/2', '/a/c/n/3'])
164         dump(index.merge(r2, r1, r3))
165         for e in index.merge(r2, r1, r3):
166             print e.name, hex(e.flags), e.ctime
167             eiv = e.name in expect_invalid
168             er  = e.name in expect_real
169             WVPASSEQ(eiv, not e.is_valid())
170             WVPASSEQ(er, e.is_real())
171         fake_validate(r2, r3)
172         dump(index.merge(r2, r1, r3))
173         WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()], [])
174
175         e = eget(index.merge(r2, r1, r3), '/a/b/c')
176         e.invalidate()
177         e.repack()
178         dump(index.merge(r2, r1, r3))
179         WVPASSEQ([e.name for e in index.merge(r2, r1, r3) if not e.is_valid()],
180                  ['/a/b/c', '/a/b/', '/a/', '/'])        
181         w1.close()
182         w2.close()
183         w3.close()
184     finally:
185         os.chdir(orig_cwd)
186     if wvfailure_count() == initial_failures:
187         subprocess.call(['rm', '-rf', tmpdir])