]> arthur.barton.de Git - bup.git/blob - lib/bup/t/tmetadata.py
Remove MetadataAcquireError and make error handling finer-grained
[bup.git] / lib / bup / t / tmetadata.py
1 import grp
2 import pwd
3 import stat
4 import subprocess
5 import tempfile
6 from bup import metadata
7 from bup.helpers import detect_fakeroot, saved_errors
8 from wvtest import *
9
10
11 @wvtest
12 def test_clean_up_archive_path():
13     cleanup = metadata._clean_up_path_for_archive
14     WVPASSEQ(cleanup('foo'), 'foo')
15     WVPASSEQ(cleanup('/foo'), 'foo')
16     WVPASSEQ(cleanup('///foo'), 'foo')
17     WVPASSEQ(cleanup('/foo/bar'), 'foo/bar')
18     WVPASSEQ(cleanup('foo/./bar'), 'foo/bar')
19     WVPASSEQ(cleanup('/foo/./bar'), 'foo/bar')
20     WVPASSEQ(cleanup('/foo/./bar/././baz'), 'foo/bar/baz')
21     WVPASSEQ(cleanup('/foo/./bar///././baz'), 'foo/bar/baz')
22     WVPASSEQ(cleanup('//./foo/./bar///././baz/.///'), 'foo/bar/baz/')
23     WVPASSEQ(cleanup('./foo/./.bar'), 'foo/.bar')
24     WVPASSEQ(cleanup('./foo/.'), 'foo')
25     WVPASSEQ(cleanup('./foo/..'), '.')
26     WVPASSEQ(cleanup('//./..//.../..//.'), '.')
27     WVPASSEQ(cleanup('//./..//..././/.'), '...')
28     WVPASSEQ(cleanup('/////.'), '.')
29     WVPASSEQ(cleanup('/../'), '.')
30     WVPASSEQ(cleanup(''), '.')
31
32
33 @wvtest
34 def test_risky_path():
35     risky = metadata._risky_path
36     WVPASS(risky('/foo'))
37     WVPASS(risky('///foo'))
38     WVPASS(risky('/../foo'))
39     WVPASS(risky('../foo'))
40     WVPASS(risky('foo/..'))
41     WVPASS(risky('foo/../'))
42     WVPASS(risky('foo/../bar'))
43     WVFAIL(risky('foo'))
44     WVFAIL(risky('foo/'))
45     WVFAIL(risky('foo///'))
46     WVFAIL(risky('./foo'))
47     WVFAIL(risky('foo/.'))
48     WVFAIL(risky('./foo/.'))
49     WVFAIL(risky('foo/bar'))
50     WVFAIL(risky('foo/./bar'))
51
52
53 @wvtest
54 def test_clean_up_extract_path():
55     cleanup = metadata._clean_up_extract_path
56     WVPASSEQ(cleanup('/foo'), 'foo')
57     WVPASSEQ(cleanup('///foo'), 'foo')
58     WVFAIL(cleanup('/../foo'))
59     WVFAIL(cleanup('../foo'))
60     WVFAIL(cleanup('foo/..'))
61     WVFAIL(cleanup('foo/../'))
62     WVFAIL(cleanup('foo/../bar'))
63     WVPASSEQ(cleanup('foo'), 'foo')
64     WVPASSEQ(cleanup('foo/'), 'foo/')
65     WVPASSEQ(cleanup('foo///'), 'foo///')
66     WVPASSEQ(cleanup('./foo'), './foo')
67     WVPASSEQ(cleanup('foo/.'), 'foo/.')
68     WVPASSEQ(cleanup('./foo/.'), './foo/.')
69     WVPASSEQ(cleanup('foo/bar'), 'foo/bar')
70     WVPASSEQ(cleanup('foo/./bar'), 'foo/./bar')
71     WVPASSEQ(cleanup('/'), '.')
72     WVPASSEQ(cleanup('./'), './')
73     WVPASSEQ(cleanup('///foo/bar'), 'foo/bar')
74     WVPASSEQ(cleanup('///foo/bar'), 'foo/bar')
75
76
77 @wvtest
78 def test_from_path_error():
79     if os.geteuid == 0 or detect_fakeroot():
80         return
81     tmpdir = tempfile.mkdtemp(prefix='bup-tmetadata-')
82     try:
83         path = tmpdir + '/foo'
84         subprocess.call(['mkdir', path])
85         m = metadata.from_path(path, archive_path=path, save_symlinks=True)
86         WVPASSEQ(m.path, path)
87         subprocess.call(['chmod', '000', path])
88         metadata.from_path(path, archive_path=path, save_symlinks=True)
89         WVPASS(saved_errors
90                and saved_errors[0].startswith('bup: unable to read Linux attr'))
91     finally:
92         subprocess.call(['rm', '-rf', tmpdir])
93
94
95 @wvtest
96 def test_apply_to_path_error():
97     if os.geteuid == 0 or detect_fakeroot():
98         return
99     tmpdir = tempfile.mkdtemp(prefix='bup-tmetadata-')
100     try:
101         path = tmpdir + '/foo'
102         subprocess.call(['mkdir', path])
103         m = metadata.from_path(path, archive_path=path, save_symlinks=True)
104         WVPASSEQ(m.path, path)
105         subprocess.call(['chmod', '000', tmpdir])
106         WVEXCEPT(metadata.MetadataApplyError,
107                  m.apply_to_path, path)
108         subprocess.call(['chmod', '700', tmpdir])
109     finally:
110         subprocess.call(['rm', '-rf', tmpdir])
111
112
113 @wvtest
114 def test_restore_restricted_user_group():
115     if os.geteuid == 0 or detect_fakeroot():
116         return
117     tmpdir = tempfile.mkdtemp(prefix='bup-tmetadata-')
118     try:
119         path = tmpdir + '/foo'
120         subprocess.call(['mkdir', path])
121         m = metadata.from_path(path, archive_path=path, save_symlinks=True)
122         WVPASSEQ(m.path, path)
123         WVPASSEQ(m.apply_to_path(path), None)
124         orig_uid = m.uid
125         m.uid = 0;
126         WVEXCEPT(metadata.MetadataApplyError,
127                  m.apply_to_path, path, restore_numeric_ids=True)
128         m.uid = orig_uid
129         m.gid = 0;
130         WVEXCEPT(metadata.MetadataApplyError,
131                  m.apply_to_path, path, restore_numeric_ids=True)
132     finally:
133         subprocess.call(['rm', '-rf', tmpdir])
134
135
136 @wvtest
137 def test_restore_nonexistent_user_group():
138     tmpdir = tempfile.mkdtemp(prefix='bup-tmetadata-')
139     try:
140         path = tmpdir + '/foo'
141         subprocess.call(['mkdir', path])
142         m = metadata.from_path(path, archive_path=path, save_symlinks=True)
143         WVPASSEQ(m.path, path)
144         m.owner = max([x.pw_name for x in pwd.getpwall()], key=len) + 'x'
145         m.group = max([x.gr_name for x in grp.getgrall()], key=len) + 'x'
146         WVPASSEQ(m.apply_to_path(path, restore_numeric_ids=True), None)
147         WVPASSEQ(os.stat(path).st_uid, m.uid)
148         WVPASSEQ(os.stat(path).st_gid, m.gid)
149         WVPASSEQ(m.apply_to_path(path, restore_numeric_ids=False), None)
150         WVPASSEQ(os.stat(path).st_uid, os.geteuid())
151         WVPASSEQ(os.stat(path).st_uid, os.getgid())
152     finally:
153         subprocess.call(['rm', '-rf', tmpdir])
154
155
156 @wvtest
157 def test_restore_over_existing_target():
158     tmpdir = tempfile.mkdtemp(prefix='bup-tmetadata-')
159     try:
160         path = tmpdir + '/foo'
161         os.mkdir(path)
162         dir_m = metadata.from_path(path, archive_path=path, save_symlinks=True)
163         os.rmdir(path)
164         open(path, 'w').close()
165         file_m = metadata.from_path(path, archive_path=path, save_symlinks=True)
166         # Restore dir over file.
167         WVPASSEQ(dir_m.create_path(path, create_symlinks=True), None)
168         WVPASS(stat.S_ISDIR(os.stat(path).st_mode))
169         # Restore dir over dir.
170         WVPASSEQ(dir_m.create_path(path, create_symlinks=True), None)
171         WVPASS(stat.S_ISDIR(os.stat(path).st_mode))
172         # Restore file over dir.
173         WVPASSEQ(file_m.create_path(path, create_symlinks=True), None)
174         WVPASS(stat.S_ISREG(os.stat(path).st_mode))
175         # Restore file over file.
176         WVPASSEQ(file_m.create_path(path, create_symlinks=True), None)
177         WVPASS(stat.S_ISREG(os.stat(path).st_mode))
178         # Restore file over non-empty dir.
179         os.remove(path)
180         os.mkdir(path)
181         open(path + '/bar', 'w').close()
182         WVEXCEPT(Exception, file_m.create_path, path, create_symlinks=True)
183         # Restore dir over non-empty dir.
184         os.remove(path + '/bar')
185         os.mkdir(path + '/bar')
186         WVEXCEPT(Exception, dir_m.create_path, path, create_symlinks=True)
187     finally:
188         subprocess.call(['rm', '-rf', tmpdir])