##// END OF EJS Templates
streaming: actually change default
Matt Mackall -
r10414:1a8df80d default
parent child Browse files
Show More
@@ -1,70 +1,70 b''
1 # streamclone.py - streaming clone server support for mercurial
1 # streamclone.py - streaming clone server support for mercurial
2 #
2 #
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
3 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import util, error
8 import util, error
9 from i18n import _
9 from i18n import _
10
10
11 from mercurial import store
11 from mercurial import store
12
12
13 class StreamException(Exception):
13 class StreamException(Exception):
14 def __init__(self, code):
14 def __init__(self, code):
15 Exception.__init__(self)
15 Exception.__init__(self)
16 self.code = code
16 self.code = code
17 def __str__(self):
17 def __str__(self):
18 return '%i\n' % self.code
18 return '%i\n' % self.code
19
19
20 # if server supports streaming clone, it advertises "stream"
20 # if server supports streaming clone, it advertises "stream"
21 # capability with value that is version+flags of repo it is serving.
21 # capability with value that is version+flags of repo it is serving.
22 # client only streams if it can read that repo format.
22 # client only streams if it can read that repo format.
23
23
24 # stream file format is simple.
24 # stream file format is simple.
25 #
25 #
26 # server writes out line that says how many files, how many total
26 # server writes out line that says how many files, how many total
27 # bytes. separator is ascii space, byte counts are strings.
27 # bytes. separator is ascii space, byte counts are strings.
28 #
28 #
29 # then for each file:
29 # then for each file:
30 #
30 #
31 # server writes out line that says filename, how many bytes in
31 # server writes out line that says filename, how many bytes in
32 # file. separator is ascii nul, byte count is string.
32 # file. separator is ascii nul, byte count is string.
33 #
33 #
34 # server writes out raw file data.
34 # server writes out raw file data.
35
35
36 def allowed(ui):
36 def allowed(ui):
37 return ui.configbool('server', 'uncompressed', untrusted=True)
37 return ui.configbool('server', 'uncompressed', True, untrusted=True)
38
38
39 def stream_out(repo):
39 def stream_out(repo):
40 '''stream out all metadata files in repository.
40 '''stream out all metadata files in repository.
41 writes to file-like object, must support write() and optional flush().'''
41 writes to file-like object, must support write() and optional flush().'''
42
42
43 if not allowed(repo.ui):
43 if not allowed(repo.ui):
44 raise StreamException(1)
44 raise StreamException(1)
45
45
46 entries = []
46 entries = []
47 total_bytes = 0
47 total_bytes = 0
48 try:
48 try:
49 # get consistent snapshot of repo, lock during scan
49 # get consistent snapshot of repo, lock during scan
50 lock = repo.lock()
50 lock = repo.lock()
51 try:
51 try:
52 repo.ui.debug('scanning\n')
52 repo.ui.debug('scanning\n')
53 for name, ename, size in repo.store.walk():
53 for name, ename, size in repo.store.walk():
54 entries.append((name, size))
54 entries.append((name, size))
55 total_bytes += size
55 total_bytes += size
56 finally:
56 finally:
57 lock.release()
57 lock.release()
58 except error.LockError:
58 except error.LockError:
59 raise StreamException(2)
59 raise StreamException(2)
60
60
61 yield '0\n'
61 yield '0\n'
62 repo.ui.debug('%d files, %d bytes to transfer\n' %
62 repo.ui.debug('%d files, %d bytes to transfer\n' %
63 (len(entries), total_bytes))
63 (len(entries), total_bytes))
64 yield '%d %d\n' % (len(entries), total_bytes)
64 yield '%d %d\n' % (len(entries), total_bytes)
65 for name, size in entries:
65 for name, size in entries:
66 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
66 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
67 # partially encode name over the wire for backwards compat
67 # partially encode name over the wire for backwards compat
68 yield '%s\0%d\n' % (store.encodedir(name), size)
68 yield '%s\0%d\n' % (store.encodedir(name), size)
69 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
69 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
70 yield chunk
70 yield chunk
@@ -1,64 +1,64 b''
1 #!/bin/sh
1 #!/bin/sh
2 # An attempt at more fully testing the hgweb web interface.
2 # An attempt at more fully testing the hgweb web interface.
3 # The following things are tested elsewhere and are therefore omitted:
3 # The following things are tested elsewhere and are therefore omitted:
4 # - archive, tested in test-archive
4 # - archive, tested in test-archive
5 # - unbundle, tested in test-push-http
5 # - unbundle, tested in test-push-http
6 # - changegroupsubset, tested in test-pull
6 # - changegroupsubset, tested in test-pull
7
7
8 echo % Set up the repo
8 echo % Set up the repo
9 hg init test
9 hg init test
10 cd test
10 cd test
11 mkdir da
11 mkdir da
12 echo foo > da/foo
12 echo foo > da/foo
13 echo foo > foo
13 echo foo > foo
14 hg ci -Ambase
14 hg ci -Ambase
15 hg tag 1.0
15 hg tag 1.0
16 echo another > foo
16 echo another > foo
17 hg branch stable
17 hg branch stable
18 hg ci -Ambranch
18 hg ci -Ambranch
19 hg serve -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
19 hg serve --config server.uncompressed=False -n test -p $HGPORT -d --pid-file=hg.pid -E errors.log
20 cat hg.pid >> $DAEMON_PIDS
20 cat hg.pid >> $DAEMON_PIDS
21
21
22 echo % Logs and changes
22 echo % Logs and changes
23 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//"
23 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//"
24 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//"
24 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//"
25 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/foo/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//"
25 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log/1/foo/?style=atom' | sed "s/http:\/\/[^/]*\//http:\/\/127.0.0.1\//"
26 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/shortlog/'
26 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/shortlog/'
27 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/0/'
27 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/0/'
28 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/1/?style=raw'
28 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/rev/1/?style=raw'
29 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log?rev=base'
29 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/log?rev=base'
30
30
31 echo % File-related
31 echo % File-related
32 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo/?style=raw'
32 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo/?style=raw'
33 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/annotate/1/foo/?style=raw'
33 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/annotate/1/foo/?style=raw'
34 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/?style=raw'
34 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/?style=raw'
35 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo'
35 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/file/1/foo'
36 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/filediff/1/foo/?style=raw'
36 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/filediff/1/foo/?style=raw'
37
37
38 echo % Overviews
38 echo % Overviews
39 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-tags'
39 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-tags'
40 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-branches'
40 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/raw-branches'
41 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb'
41 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/summary/?style=gitweb'
42 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb'
42 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/graph/?style=gitweb'
43
43
44 echo % capabilities
44 echo % capabilities
45 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'
45 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=capabilities'
46 echo % heads
46 echo % heads
47 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=heads'
47 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=heads'
48 echo % lookup
48 echo % lookup
49 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=lookup&node=1'
49 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=lookup&node=1'
50 echo % branches
50 echo % branches
51 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=branches'
51 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=branches'
52 echo % changegroup
52 echo % changegroup
53 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup' \
53 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=changegroup' \
54 | $TESTDIR/printrepr.py
54 | $TESTDIR/printrepr.py
55 echo % stream_out
55 echo % stream_out
56 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=stream_out'
56 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=stream_out'
57 echo % failing unbundle, requires POST request
57 echo % failing unbundle, requires POST request
58 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=unbundle'
58 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '?cmd=unbundle'
59
59
60 echo % Static files
60 echo % Static files
61 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/static/style.css'
61 "$TESTDIR/get-with-headers.py" 127.0.0.1:$HGPORT '/static/style.css'
62
62
63 echo % ERRORS ENCOUNTERED
63 echo % ERRORS ENCOUNTERED
64 cat errors.log
64 cat errors.log
@@ -1,43 +1,43 b''
1 #!/bin/sh
1 #!/bin/sh
2
2
3 cp "$TESTDIR"/printenv.py .
3 cp "$TESTDIR"/printenv.py .
4
4
5 hg init test
5 hg init test
6 cd test
6 cd test
7 echo foo>foo
7 echo foo>foo
8 mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
8 mkdir foo.d foo.d/bAr.hg.d foo.d/baR.d.hg
9 echo foo>foo.d/foo
9 echo foo>foo.d/foo
10 echo bar>foo.d/bAr.hg.d/BaR
10 echo bar>foo.d/bAr.hg.d/BaR
11 echo bar>foo.d/baR.d.hg/bAR
11 echo bar>foo.d/baR.d.hg/bAR
12
12
13 hg commit -A -m 1
13 hg commit -A -m 1
14 hg --config server.uncompressed=True serve -p $HGPORT -d --pid-file=../hg1.pid
14 hg serve -p $HGPORT -d --pid-file=../hg1.pid
15 hg serve -p $HGPORT1 -d --pid-file=../hg2.pid
15 hg --config server.uncompressed=False serve -p $HGPORT1 -d --pid-file=../hg2.pid
16 # Test server address cannot be reused
16 # Test server address cannot be reused
17 hg serve -p $HGPORT1 2>&1 | sed -e "s/abort: cannot start server at ':$HGPORT1':.*/abort: cannot start server at ':\$HGPORT1':/"
17 hg serve -p $HGPORT1 2>&1 | sed -e "s/abort: cannot start server at ':$HGPORT1':.*/abort: cannot start server at ':\$HGPORT1':/"
18 cd ..
18 cd ..
19 cat hg1.pid hg2.pid >> $DAEMON_PIDS
19 cat hg1.pid hg2.pid >> $DAEMON_PIDS
20
20
21 echo % clone via stream
21 echo % clone via stream
22 hg clone --uncompressed http://localhost:$HGPORT/ copy 2>&1 | \
22 hg clone --uncompressed http://localhost:$HGPORT/ copy 2>&1 | \
23 sed -e 's/[0-9][0-9.]*/XXX/g' -e 's/[KM]\(B\/sec\)/X\1/'
23 sed -e 's/[0-9][0-9.]*/XXX/g' -e 's/[KM]\(B\/sec\)/X\1/'
24 hg verify -R copy
24 hg verify -R copy
25
25
26 echo % try to clone via stream, should use pull instead
26 echo % try to clone via stream, should use pull instead
27 hg clone --uncompressed http://localhost:$HGPORT1/ copy2
27 hg clone --uncompressed http://localhost:$HGPORT1/ copy2
28
28
29 echo % clone via pull
29 echo % clone via pull
30 hg clone http://localhost:$HGPORT1/ copy-pull
30 hg clone http://localhost:$HGPORT1/ copy-pull
31 hg verify -R copy-pull
31 hg verify -R copy-pull
32
32
33 cd test
33 cd test
34 echo bar > bar
34 echo bar > bar
35 hg commit -A -d '1 0' -m 2
35 hg commit -A -d '1 0' -m 2
36 cd ..
36 cd ..
37
37
38 echo % pull
38 echo % pull
39 cd copy-pull
39 cd copy-pull
40 echo '[hooks]' >> .hg/hgrc
40 echo '[hooks]' >> .hg/hgrc
41 echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc
41 echo 'changegroup = python ../printenv.py changegroup' >> .hg/hgrc
42 hg pull | sed -e "s,:$HGPORT1/,:\$HGPORT1/,"
42 hg pull | sed -e "s,:$HGPORT1/,:\$HGPORT1/,"
43 cd ..
43 cd ..
General Comments 0
You need to be logged in to leave comments. Login now