]> arthur.barton.de Git - bup.git/blob - test/int/test_client.py
Move t*.py tests to test_*.py for pytest autodetection
[bup.git] / test / int / test_client.py
1
2 from __future__ import absolute_import
3 import sys, os, stat, time, random, subprocess, glob
4
5 from wvtest import *
6
7 from bup import client, git, path
8 from bup.compat import bytes_from_uint, environ, range
9 from bup.helpers import mkdirp
10 from buptest import no_lingering_errors, test_tempdir
11
12
13 def randbytes(sz):
14     s = b''
15     for i in range(sz):
16         s += bytes_from_uint(random.randrange(0,256))
17     return s
18
19
20 s1 = randbytes(10000)
21 s2 = randbytes(10000)
22 s3 = randbytes(10000)
23
24 IDX_PAT = b'/*.idx'
25     
26
27 @wvtest
28 def test_server_split_with_indexes():
29     with no_lingering_errors():
30         with test_tempdir(b'bup-tclient-') as tmpdir:
31             environ[b'BUP_DIR'] = bupdir = tmpdir
32             git.init_repo(bupdir)
33             lw = git.PackWriter()
34             c = client.Client(bupdir, create=True)
35             rw = c.new_packwriter()
36
37             lw.new_blob(s1)
38             lw.close()
39
40             rw.new_blob(s2)
41             rw.breakpoint()
42             rw.new_blob(s1)
43             rw.close()
44     
45
46 @wvtest
47 def test_multiple_suggestions():
48     with no_lingering_errors():
49         with test_tempdir(b'bup-tclient-') as tmpdir:
50             environ[b'BUP_DIR'] = bupdir = tmpdir
51             git.init_repo(bupdir)
52
53             lw = git.PackWriter()
54             lw.new_blob(s1)
55             lw.close()
56             lw = git.PackWriter()
57             lw.new_blob(s2)
58             lw.close()
59             WVPASSEQ(len(glob.glob(git.repo(b'objects/pack'+IDX_PAT))), 2)
60
61             c = client.Client(bupdir, create=True)
62             WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 0)
63             rw = c.new_packwriter()
64             s1sha = rw.new_blob(s1)
65             WVPASS(rw.exists(s1sha))
66             s2sha = rw.new_blob(s2)
67
68             # This is a little hacky, but ensures that we test the
69             # code under test. First, flush to ensure that we've
70             # actually sent all the command ('receive-objects-v2')
71             # and their data to the server. This may be needed if
72             # the output buffer size is bigger than the data (both
73             # command and objects) we're writing. To see the need
74             # for this, change the object sizes at the beginning
75             # of this file to be very small (e.g. 10 instead of 10k)
76             c.conn.outp.flush()
77
78             # Then, check if we've already received the idx files.
79             # This may happen if we're preempted just after writing
80             # the data, then the server runs and suggests, and only
81             # then we continue in PackWriter_Remote::_raw_write()
82             # and check the has_input(), in that case we'll receive
83             # the idx still in the rw.new_blob() calls above.
84             #
85             # In most cases though, that doesn't happen, and we'll
86             # get past the has_input() check before the server has
87             # a chance to respond - it has to actually hash the new
88             # object here, so it takes some time. So also break out
89             # of the loop if the server has sent something on the
90             # connection.
91             #
92             # Finally, abort this after a little while (about one
93             # second) just in case something's actually broken.
94             n = 0
95             while (len(glob.glob(c.cachedir+IDX_PAT)) < 2 and
96                    not c.conn.has_input() and n < 10):
97                 time.sleep(0.1)
98                 n += 1
99             WVPASS(len(glob.glob(c.cachedir+IDX_PAT)) == 2 or c.conn.has_input())
100             rw.new_blob(s2)
101             WVPASS(rw.objcache.exists(s1sha))
102             WVPASS(rw.objcache.exists(s2sha))
103             rw.new_blob(s3)
104             WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 2)
105             rw.close()
106             WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 3)
107
108
109 @wvtest
110 def test_dumb_client_server():
111     with no_lingering_errors():
112         with test_tempdir(b'bup-tclient-') as tmpdir:
113             environ[b'BUP_DIR'] = bupdir = tmpdir
114             git.init_repo(bupdir)
115             open(git.repo(b'bup-dumb-server'), 'w').close()
116
117             lw = git.PackWriter()
118             lw.new_blob(s1)
119             lw.close()
120
121             c = client.Client(bupdir, create=True)
122             rw = c.new_packwriter()
123             WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 1)
124             rw.new_blob(s1)
125             WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 1)
126             rw.new_blob(s2)
127             rw.close()
128             WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 2)
129
130
131 @wvtest
132 def test_midx_refreshing():
133     with no_lingering_errors():
134         with test_tempdir(b'bup-tclient-') as tmpdir:
135             environ[b'BUP_DIR'] = bupdir = tmpdir
136             git.init_repo(bupdir)
137             c = client.Client(bupdir, create=True)
138             rw = c.new_packwriter()
139             rw.new_blob(s1)
140             p1base = rw.breakpoint()
141             p1name = os.path.join(c.cachedir, p1base)
142             s1sha = rw.new_blob(s1)  # should not be written; it's already in p1
143             s2sha = rw.new_blob(s2)
144             p2base = rw.close()
145             p2name = os.path.join(c.cachedir, p2base)
146             del rw
147
148             pi = git.PackIdxList(bupdir + b'/objects/pack')
149             WVPASSEQ(len(pi.packs), 2)
150             pi.refresh()
151             WVPASSEQ(len(pi.packs), 2)
152             WVPASSEQ(sorted([os.path.basename(i.name) for i in pi.packs]),
153                      sorted([p1base, p2base]))
154
155             p1 = git.open_idx(p1name)
156             WVPASS(p1.exists(s1sha))
157             p2 = git.open_idx(p2name)
158             WVFAIL(p2.exists(s1sha))
159             WVPASS(p2.exists(s2sha))
160
161             subprocess.call([path.exe(), b'midx', b'-f'])
162             pi.refresh()
163             WVPASSEQ(len(pi.packs), 1)
164             pi.refresh(skip_midx=True)
165             WVPASSEQ(len(pi.packs), 2)
166             pi.refresh(skip_midx=False)
167             WVPASSEQ(len(pi.packs), 1)
168
169
170 @wvtest
171 def test_remote_parsing():
172     with no_lingering_errors():
173         tests = (
174             (b':/bup', (b'file', None, None, b'/bup')),
175             (b'file:///bup', (b'file', None, None, b'/bup')),
176             (b'192.168.1.1:/bup', (b'ssh', b'192.168.1.1', None, b'/bup')),
177             (b'ssh://192.168.1.1:2222/bup', (b'ssh', b'192.168.1.1', b'2222', b'/bup')),
178             (b'ssh://[ff:fe::1]:2222/bup', (b'ssh', b'ff:fe::1', b'2222', b'/bup')),
179             (b'bup://foo.com:1950', (b'bup', b'foo.com', b'1950', None)),
180             (b'bup://foo.com:1950/bup', (b'bup', b'foo.com', b'1950', b'/bup')),
181             (b'bup://[ff:fe::1]/bup', (b'bup', b'ff:fe::1', None, b'/bup')),)
182         for remote, values in tests:
183             WVPASSEQ(client.parse_remote(remote), values)
184         try:
185             client.parse_remote(b'http://asdf.com/bup')
186             WVFAIL()
187         except client.ClientError:
188             WVPASS()