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