2 from __future__ import absolute_import
3 import sys, os, stat, time, random, subprocess, glob
6 from bup import client, git, path
7 from bup.compat import bytes_from_uint, environ, range
8 from bup.helpers import mkdirp
13 s += bytes_from_uint(random.randrange(0,256))
24 def test_server_split_with_indexes(tmpdir):
25 environ[b'BUP_DIR'] = bupdir = tmpdir
28 c = client.Client(bupdir, create=True)
29 rw = c.new_packwriter()
40 def test_multiple_suggestions(tmpdir):
41 environ[b'BUP_DIR'] = bupdir = tmpdir
50 assert len(glob.glob(git.repo(b'objects/pack'+IDX_PAT))) == 2
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)
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)
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.
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
83 # Finally, abort this after a little while (about one
84 # second) just in case something's actually broken.
86 while (len(glob.glob(c.cachedir+IDX_PAT)) < 2 and
87 not c.conn.has_input() and n < 10):
90 assert len(glob.glob(c.cachedir+IDX_PAT)) == 2 or c.conn.has_input()
92 assert rw.objcache.exists(s1sha)
93 assert rw.objcache.exists(s2sha)
95 assert len(glob.glob(c.cachedir+IDX_PAT)) == 2
97 assert len(glob.glob(c.cachedir+IDX_PAT)) == 3
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()
105 lw = git.PackWriter()
109 c = client.Client(bupdir, create=True)
110 rw = c.new_packwriter()
111 assert len(glob.glob(c.cachedir+IDX_PAT)) == 1
113 assert len(glob.glob(c.cachedir+IDX_PAT)) == 1
116 assert len(glob.glob(c.cachedir+IDX_PAT)) == 2
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()
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)
130 p2name = os.path.join(c.cachedir, p2base)
133 pi = git.PackIdxList(bupdir + b'/objects/pack')
134 assert len(pi.packs) == 2
136 assert len(pi.packs) == 2
137 assert sorted([os.path.basename(i.name) for i in pi.packs]) == sorted([p1base, p2base])
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)
145 subprocess.call([path.exe(), b'midx', b'-f'])
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
154 def test_remote_parsing():
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
167 with pytest.raises(client.ClientError):
168 client.parse_remote(b'http://asdf.com/bup')