2 from __future__ import absolute_import
3 import sys, os, stat, time, random, subprocess, glob
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
16 s += bytes_from_uint(random.randrange(0,256))
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
34 c = client.Client(bupdir, create=True)
35 rw = c.new_packwriter()
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
59 WVPASSEQ(len(glob.glob(git.repo(b'objects/pack'+IDX_PAT))), 2)
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)
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)
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.
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
92 # Finally, abort this after a little while (about one
93 # second) just in case something's actually broken.
95 while (len(glob.glob(c.cachedir+IDX_PAT)) < 2 and
96 not c.conn.has_input() and n < 10):
99 WVPASS(len(glob.glob(c.cachedir+IDX_PAT)) == 2 or c.conn.has_input())
101 WVPASS(rw.objcache.exists(s1sha))
102 WVPASS(rw.objcache.exists(s2sha))
104 WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 2)
106 WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 3)
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()
117 lw = git.PackWriter()
121 c = client.Client(bupdir, create=True)
122 rw = c.new_packwriter()
123 WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 1)
125 WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 1)
128 WVPASSEQ(len(glob.glob(c.cachedir+IDX_PAT)), 2)
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()
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)
145 p2name = os.path.join(c.cachedir, p2base)
148 pi = git.PackIdxList(bupdir + b'/objects/pack')
149 WVPASSEQ(len(pi.packs), 2)
151 WVPASSEQ(len(pi.packs), 2)
152 WVPASSEQ(sorted([os.path.basename(i.name) for i in pi.packs]),
153 sorted([p1base, p2base]))
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))
161 subprocess.call([path.exe(), b'midx', b'-f'])
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)
171 def test_remote_parsing():
172 with no_lingering_errors():
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)
185 client.parse_remote(b'http://asdf.com/bup')
187 except client.ClientError: