Merge b785d95f66
into 2b4c3619d6
This commit is contained in:
commit
eba93c0964
12 changed files with 175 additions and 44 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -17,6 +17,7 @@ develop-eggs
|
||||||
pip-log.txt
|
pip-log.txt
|
||||||
|
|
||||||
# Unit test / coverage reports
|
# Unit test / coverage reports
|
||||||
|
htmlcov
|
||||||
.coverage
|
.coverage
|
||||||
.tox
|
.tox
|
||||||
|
|
||||||
|
|
65
.jenkins.sh
Executable file
65
.jenkins.sh
Executable file
|
@ -0,0 +1,65 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
result=0
|
||||||
|
|
||||||
|
function run_test {
|
||||||
|
printf '\e[0;36m'
|
||||||
|
echo "running test: $command $@"
|
||||||
|
printf '\e[0m'
|
||||||
|
|
||||||
|
$command "$@"
|
||||||
|
status=$?
|
||||||
|
if [ $status -ne 0 ]; then
|
||||||
|
printf '\e[0;31m'
|
||||||
|
echo "test failed: $command $@"
|
||||||
|
printf '\e[0m'
|
||||||
|
echo
|
||||||
|
result=1
|
||||||
|
else
|
||||||
|
printf '\e[0;32m'
|
||||||
|
echo OK
|
||||||
|
printf '\e[0m'
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
coverage erase
|
||||||
|
mkdir tmp
|
||||||
|
run_test pep8 .
|
||||||
|
run_test pyflakes .
|
||||||
|
run_test coverage run tests/nose_plugin.py -v
|
||||||
|
run_test python setup.py sdist
|
||||||
|
run_test tests/test_daemon.sh
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/aes.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/aes-ctr.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/aes-cfb1.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/aes-cfb8.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/rc4-md5.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/salsa20.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/chacha20.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/salsa20-ctr.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/table.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/server-multi-ports.json
|
||||||
|
run_test python tests/test.py --with-coverage -s tests/server-multi-passwd.json -c tests/server-multi-passwd-client-side.json
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/workers.json
|
||||||
|
run_test python tests/test.py --with-coverage -s tests/ipv6.json -c tests/ipv6-client-side.json
|
||||||
|
run_test python tests/test.py --with-coverage -b "-m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388" -a "-m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -l 1081"
|
||||||
|
run_test python tests/test.py --with-coverage -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081"
|
||||||
|
|
||||||
|
if [ -f /proc/sys/net/ipv4/tcp_fastopen ] ; then
|
||||||
|
if [ 3 -eq `cat /proc/sys/net/ipv4/tcp_fastopen` ] ; then
|
||||||
|
run_test python tests/test.py --with-coverage -c tests/fastopen.json
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
run_test tests/test_large_file.sh
|
||||||
|
|
||||||
|
coverage combine && coverage report --include=shadowsocks/*
|
||||||
|
rm -rf htmlcov
|
||||||
|
rm -rf tmp
|
||||||
|
coverage html --include=shadowsocks/*
|
||||||
|
|
||||||
|
coverage report --include=shadowsocks/* | tail -n1 | rev | cut -d' ' -f 1 | rev > /tmp/shadowsocks-coverage
|
||||||
|
|
||||||
|
exit $result
|
27
.travis.yml
27
.travis.yml
|
@ -9,29 +9,12 @@ cache:
|
||||||
- dante-1.4.0
|
- dante-1.4.0
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -qq build-essential libssl-dev swig python-m2crypto python-numpy dnsutils
|
- sudo apt-get install -qq build-essential libssl-dev swig python-m2crypto python-numpy dnsutils iproute nginx
|
||||||
|
- sudo dd if=/dev/urandom of=/usr/share/nginx/www/file bs=1M count=10
|
||||||
|
- sudo service nginx restart
|
||||||
- pip install m2crypto salsa20 pep8 pyflakes nose coverage
|
- pip install m2crypto salsa20 pep8 pyflakes nose coverage
|
||||||
- sudo tests/socksify/install.sh
|
- sudo tests/socksify/install.sh
|
||||||
- sudo tests/libsodium/install.sh
|
- sudo tests/libsodium/install.sh
|
||||||
|
- sudo tests/setup_tc.sh
|
||||||
script:
|
script:
|
||||||
- pep8 .
|
- ./.jenkins.sh
|
||||||
- pyflakes .
|
|
||||||
- coverage run tests/nose_plugin.py -v
|
|
||||||
- python setup.py sdist
|
|
||||||
- tests/test_daemon.sh
|
|
||||||
- python tests/test.py --with-coverage -c tests/aes.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/aes-ctr.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/aes-cfb1.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/aes-cfb8.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/rc4-md5.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/salsa20.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/chacha20.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/salsa20-ctr.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/table.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/server-multi-ports.json
|
|
||||||
- python tests/test.py --with-coverage -s tests/server-multi-passwd.json -c tests/server-multi-passwd-client-side.json
|
|
||||||
- python tests/test.py --with-coverage -c tests/workers.json
|
|
||||||
- python tests/test.py --with-coverage -s tests/ipv6.json -c tests/ipv6-client-side.json
|
|
||||||
- python tests/test.py --with-coverage -b "-m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388" -a "-m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -l 1081"
|
|
||||||
- python tests/test.py --with-coverage -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081"
|
|
||||||
- coverage combine && coverage report --include=shadowsocks/*
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
shadowsocks
|
shadowsocks
|
||||||
===========
|
===========
|
||||||
|
|
||||||
[![PyPI version]][PyPI] [![Build Status]][Travis CI]
|
[![PyPI version]][PyPI]
|
||||||
|
[![Build Status]][Travis CI]
|
||||||
|
[![Coverage Status]][Coverage]
|
||||||
|
|
||||||
A fast tunnel proxy that helps you bypass firewalls.
|
A fast tunnel proxy that helps you bypass firewalls.
|
||||||
|
|
||||||
|
@ -119,6 +121,8 @@ Bugs and Issues
|
||||||
[Android]: https://github.com/clowwindy/shadowsocks/wiki/Ports-and-Clients#android
|
[Android]: https://github.com/clowwindy/shadowsocks/wiki/Ports-and-Clients#android
|
||||||
[Build Status]: https://img.shields.io/travis/clowwindy/shadowsocks/master.svg?style=flat
|
[Build Status]: https://img.shields.io/travis/clowwindy/shadowsocks/master.svg?style=flat
|
||||||
[Chinese Readme]: https://github.com/clowwindy/shadowsocks/wiki/Shadowsocks-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
|
[Chinese Readme]: https://github.com/clowwindy/shadowsocks/wiki/Shadowsocks-%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E
|
||||||
|
[Coverage Status]: http://192.81.132.184/result/shadowsocks
|
||||||
|
[Coverage]: http://192.81.132.184/job/Shadowsocks/ws/htmlcov/index.html
|
||||||
[Debian sid]: https://packages.debian.org/unstable/python/shadowsocks
|
[Debian sid]: https://packages.debian.org/unstable/python/shadowsocks
|
||||||
[the package]: https://pypi.python.org/pypi/shadowsocks
|
[the package]: https://pypi.python.org/pypi/shadowsocks
|
||||||
[Encryption]: https://github.com/clowwindy/shadowsocks/wiki/Encryption
|
[Encryption]: https://github.com/clowwindy/shadowsocks/wiki/Encryption
|
||||||
|
|
|
@ -100,19 +100,21 @@ def freopen(f, mode, stream):
|
||||||
|
|
||||||
|
|
||||||
def daemon_start(pid_file, log_file):
|
def daemon_start(pid_file, log_file):
|
||||||
# fork only once because we are sure parent will exit
|
|
||||||
pid = os.fork()
|
|
||||||
assert pid != -1
|
|
||||||
|
|
||||||
def handle_exit(signum, _):
|
def handle_exit(signum, _):
|
||||||
if signum == signal.SIGTERM:
|
if signum == signal.SIGTERM:
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if pid > 0:
|
|
||||||
# parent waits for its child
|
|
||||||
signal.signal(signal.SIGINT, handle_exit)
|
signal.signal(signal.SIGINT, handle_exit)
|
||||||
signal.signal(signal.SIGTERM, handle_exit)
|
signal.signal(signal.SIGTERM, handle_exit)
|
||||||
|
|
||||||
|
# fork only once because we are sure parent will exit
|
||||||
|
pid = os.fork()
|
||||||
|
assert pid != -1
|
||||||
|
|
||||||
|
if pid > 0:
|
||||||
|
# parent waits for its child
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
|
@ -135,7 +137,6 @@ def daemon_start(pid_file, log_file):
|
||||||
freopen(log_file, 'a', sys.stderr)
|
freopen(log_file, 'a', sys.stderr)
|
||||||
except IOError as e:
|
except IOError as e:
|
||||||
logging.error(e)
|
logging.error(e)
|
||||||
os.kill(ppid, signal.SIGINT)
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,11 @@ def main():
|
||||||
tcp_server.close(next_tick=True)
|
tcp_server.close(next_tick=True)
|
||||||
udp_server.close(next_tick=True)
|
udp_server.close(next_tick=True)
|
||||||
signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler)
|
signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler)
|
||||||
|
|
||||||
|
def int_handler(signum, _):
|
||||||
|
sys.exit(1)
|
||||||
|
signal.signal(signal.SIGINT, int_handler)
|
||||||
|
|
||||||
loop.run()
|
loop.run()
|
||||||
except (KeyboardInterrupt, IOError, OSError) as e:
|
except (KeyboardInterrupt, IOError, OSError) as e:
|
||||||
logging.error(e)
|
logging.error(e)
|
||||||
|
|
|
@ -77,6 +77,11 @@ def main():
|
||||||
tcp_servers + udp_servers))
|
tcp_servers + udp_servers))
|
||||||
signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM),
|
signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM),
|
||||||
child_handler)
|
child_handler)
|
||||||
|
|
||||||
|
def int_handler(signum, _):
|
||||||
|
sys.exit(1)
|
||||||
|
signal.signal(signal.SIGINT, int_handler)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
loop = eventloop.EventLoop()
|
loop = eventloop.EventLoop()
|
||||||
dns_resolver.add_to_loop(loop)
|
dns_resolver.add_to_loop(loop)
|
||||||
|
@ -113,6 +118,7 @@ def main():
|
||||||
sys.exit()
|
sys.exit()
|
||||||
signal.signal(signal.SIGTERM, handler)
|
signal.signal(signal.SIGTERM, handler)
|
||||||
signal.signal(signal.SIGQUIT, handler)
|
signal.signal(signal.SIGQUIT, handler)
|
||||||
|
signal.signal(signal.SIGINT, handler)
|
||||||
|
|
||||||
# master
|
# master
|
||||||
for a_tcp_server in tcp_servers:
|
for a_tcp_server in tcp_servers:
|
||||||
|
|
23
tests/coverage_server.py
Normal file
23
tests/coverage_server.py
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
import tornado.ioloop
|
||||||
|
import tornado.web
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
class MainHandler(tornado.web.RequestHandler):
|
||||||
|
def get(self):
|
||||||
|
with open('/tmp/shadowsocks-coverage', 'rb') as f:
|
||||||
|
coverage = f.read().strip()
|
||||||
|
self.redirect(('https://img.shields.io/badge/'
|
||||||
|
'coverage-%s-brightgreen.svg'
|
||||||
|
'?style=flat') %
|
||||||
|
urllib.quote(coverage))
|
||||||
|
|
||||||
|
application = tornado.web.Application([
|
||||||
|
(r"/shadowsocks", MainHandler),
|
||||||
|
])
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
application.listen(8888, address='127.0.0.1')
|
||||||
|
tornado.ioloop.IOLoop.instance().start()
|
18
tests/setup_tc.sh
Executable file
18
tests/setup_tc.sh
Executable file
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DEV=lo
|
||||||
|
PORT=8388
|
||||||
|
DELAY=100ms
|
||||||
|
|
||||||
|
type tc 2> /dev/null && (
|
||||||
|
tc qdisc add dev $DEV root handle 1: htb
|
||||||
|
tc class add dev $DEV parent 1: classid 1:1 htb rate 2mbps
|
||||||
|
tc class add dev $DEV parent 1:1 classid 1:6 htb rate 2mbps ceil 1mbps prio 0
|
||||||
|
tc filter add dev $DEV parent 1:0 prio 0 protocol ip handle 6 fw flowid 1:6
|
||||||
|
|
||||||
|
tc filter add dev $DEV parent 1:0 protocol ip u32 match ip dport $PORT 0xffff flowid 1:6
|
||||||
|
tc filter add dev $DEV parent 1:0 protocol ip u32 match ip sport $PORT 0xffff flowid 1:6
|
||||||
|
|
||||||
|
tc qdisc show dev lo
|
||||||
|
)
|
||||||
|
|
|
@ -138,7 +138,7 @@ try:
|
||||||
finally:
|
finally:
|
||||||
for p in [p1, p2]:
|
for p in [p1, p2]:
|
||||||
try:
|
try:
|
||||||
os.kill(p.pid, signal.SIGQUIT)
|
os.kill(p.pid, signal.SIGINT)
|
||||||
os.waitpid(p.pid, 0)
|
os.waitpid(p.pid, 0)
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
function test {
|
function run_test {
|
||||||
expected=$1
|
expected=$1
|
||||||
shift
|
shift
|
||||||
echo "running test: $command $@"
|
echo "running test: $command $@"
|
||||||
|
@ -20,23 +20,24 @@ do
|
||||||
|
|
||||||
command="coverage run -p -a shadowsocks/$module.py"
|
command="coverage run -p -a shadowsocks/$module.py"
|
||||||
|
|
||||||
test 0 -c tests/aes.json -d stop --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
mkdir -p tmp
|
||||||
|
|
||||||
test 0 -c tests/aes.json -d start --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
test 0 -c tests/aes.json -d stop --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
|
||||||
|
|
||||||
test 0 -c tests/aes.json -d start --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
run_test 0 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
test 1 -c tests/aes.json -d start --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
test 0 -c tests/aes.json -d stop --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
|
||||||
|
|
||||||
test 0 -c tests/aes.json -d start --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
run_test 0 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
test 0 -c tests/aes.json -d restart --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
run_test 1 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
test 0 -c tests/aes.json -d stop --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
|
|
||||||
test 0 -c tests/aes.json -d restart --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
run_test 0 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
test 0 -c tests/aes.json -d stop --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
run_test 0 -c tests/aes.json -d restart --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
|
run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
|
|
||||||
test 1 -c tests/aes.json -d start --pid-file /tmp/not_exist/shadowsocks.pid --log-file /tmp/shadowsocks.log
|
run_test 0 -c tests/aes.json -d restart --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
test 1 -c tests/aes.json -d start --pid-file /tmp/shadowsocks.pid --log-file /tmp/not_exist/shadowsocks.log
|
run_test 0 -c tests/aes.json -d stop --pid-file tmp/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
|
|
||||||
|
run_test 1 -c tests/aes.json -d start --pid-file tmp/not_exist/shadowsocks.pid --log-file tmp/shadowsocks.log
|
||||||
|
|
||||||
done
|
done
|
||||||
|
|
24
tests/test_large_file.sh
Executable file
24
tests/test_large_file.sh
Executable file
|
@ -0,0 +1,24 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
PYTHON="coverage run -p -a"
|
||||||
|
URL=http://127.0.0.1/file
|
||||||
|
|
||||||
|
mkdir -p tmp
|
||||||
|
|
||||||
|
$PYTHON shadowsocks/local.py -c tests/aes.json &
|
||||||
|
LOCAL=$!
|
||||||
|
|
||||||
|
$PYTHON shadowsocks/server.py -c tests/aes.json &
|
||||||
|
SERVER=$!
|
||||||
|
|
||||||
|
sleep 3
|
||||||
|
|
||||||
|
time curl -o tmp/expected $URL
|
||||||
|
time curl -o tmp/result --socks5-hostname 127.0.0.1:1081 $URL
|
||||||
|
|
||||||
|
kill -s SIGINT $LOCAL
|
||||||
|
kill -s SIGINT $SERVER
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
diff tmp/expected tmp/result || exit 1
|
Loading…
Add table
Add a link
Reference in a new issue