From be2ab378ffd8c4e234b42cf7602d764ef6ef5398 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 22 Dec 2014 16:33:23 +0800 Subject: [PATCH 01/13] add jenkins --- .gitignore | 1 + .jenkins.sh | 53 ++++++++++++++++++++++++++++++++++++++++++++ .travis.yml | 22 +----------------- tests/test_daemon.sh | 28 +++++++++++------------ 4 files changed, 69 insertions(+), 35 deletions(-) create mode 100755 .jenkins.sh diff --git a/.gitignore b/.gitignore index 357232f..fb96264 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ develop-eggs pip-log.txt # Unit test / coverage reports +htmlcov .coverage .tox diff --git a/.jenkins.sh b/.jenkins.sh new file mode 100755 index 0000000..1206b00 --- /dev/null +++ b/.jenkins.sh @@ -0,0 +1,53 @@ +#!/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 +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" +coverage combine && coverage report --include=shadowsocks/* +coverage combine && coverage report --include=shadowsocks/* +rm -rf htmlcov +coverage html --include=shadowsocks/* + +exit $result diff --git a/.travis.yml b/.travis.yml index 1ceac69..3b094f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,24 +14,4 @@ before_install: - sudo tests/socksify/install.sh - sudo tests/libsodium/install.sh script: - - pep8 . - - 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/* + - ./.jenkins.sh diff --git a/tests/test_daemon.sh b/tests/test_daemon.sh index b05208d..fdfe517 100755 --- a/tests/test_daemon.sh +++ b/tests/test_daemon.sh @@ -1,6 +1,6 @@ #!/bin/bash -function test { +function run_test { expected=$1 shift echo "running test: $command $@" @@ -20,23 +20,23 @@ do 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 +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 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 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 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 -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 start --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 +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 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 -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 start --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 0 -c tests/aes.json -d restart --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 -test 1 -c tests/aes.json -d start --pid-file /tmp/shadowsocks.pid --log-file /tmp/not_exist/shadowsocks.log +run_test 1 -c tests/aes.json -d start --pid-file /tmp/not_exist/shadowsocks.pid --log-file /tmp/shadowsocks.log +run_test 1 -c tests/aes.json -d start --pid-file /tmp/shadowsocks.pid --log-file /tmp/not_exist/shadowsocks.log done From c7b5a5a0110e8090a226e8af329c57bfb8af4cc2 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 22 Dec 2014 16:45:46 +0800 Subject: [PATCH 02/13] fix ci --- .jenkins.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.jenkins.sh b/.jenkins.sh index 1206b00..256fe38 100755 --- a/.jenkins.sh +++ b/.jenkins.sh @@ -7,7 +7,7 @@ function run_test { echo "running test: $command $@" printf '\e[0m' - $command $@ + $command "$@" status=$? if [ $status -ne 0 ]; then printf '\e[0;31m' @@ -46,7 +46,6 @@ run_test python tests/test.py --with-coverage -s tests/ipv6.json -c tests/ipv6-c 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" coverage combine && coverage report --include=shadowsocks/* -coverage combine && coverage report --include=shadowsocks/* rm -rf htmlcov coverage html --include=shadowsocks/* From 536b7d1ee637f9fbc78eb923656838cb3219673e Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 22 Dec 2014 17:09:37 +0800 Subject: [PATCH 03/13] use SIGINT instead in tests Conflicts: tests/test.py --- shadowsocks/local.py | 5 +++++ shadowsocks/server.py | 5 +++++ tests/test.py | 4 +++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/shadowsocks/local.py b/shadowsocks/local.py index 6a97f07..994b6d8 100755 --- a/shadowsocks/local.py +++ b/shadowsocks/local.py @@ -68,6 +68,11 @@ def main(): tcp_server.close(next_tick=True) udp_server.close(next_tick=True) signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler) + + def int_handler(signum, _): + sys.exit(1) + signal.signal(signal.SIGINT, int_handler) + loop.run() except (KeyboardInterrupt, IOError, OSError) as e: logging.error(e) diff --git a/shadowsocks/server.py b/shadowsocks/server.py index e7acc5e..c5a00ca 100755 --- a/shadowsocks/server.py +++ b/shadowsocks/server.py @@ -77,6 +77,11 @@ def main(): tcp_servers + udp_servers)) signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), child_handler) + + def int_handler(signum, _): + sys.exit(1) + signal.signal(signal.SIGINT, int_handler) + try: loop = eventloop.EventLoop() dns_resolver.add_to_loop(loop) diff --git a/tests/test.py b/tests/test.py index 5314d6e..721d484 100755 --- a/tests/test.py +++ b/tests/test.py @@ -138,7 +138,9 @@ try: finally: for p in [p1, p2]: try: - os.kill(p.pid, signal.SIGQUIT) + print('kill', file=sys.stderr) + os.kill(p.pid, signal.SIGINT) + print('waitpid', file=sys.stderr) os.waitpid(p.pid, 0) except OSError: pass From be1d1d50323f0f67dc58e33dc76e24b22907e1a1 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 22 Dec 2014 17:29:58 +0800 Subject: [PATCH 04/13] add SIGINT in workers --- shadowsocks/server.py | 1 + 1 file changed, 1 insertion(+) diff --git a/shadowsocks/server.py b/shadowsocks/server.py index c5a00ca..8eed4ad 100755 --- a/shadowsocks/server.py +++ b/shadowsocks/server.py @@ -118,6 +118,7 @@ def main(): sys.exit() signal.signal(signal.SIGTERM, handler) signal.signal(signal.SIGQUIT, handler) + signal.signal(signal.SIGINT, handler) # master for a_tcp_server in tcp_servers: From 072afd68f2a8a98fe6d6706dafb7ff1f7093a602 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 22 Dec 2014 17:39:52 +0800 Subject: [PATCH 05/13] use local tmp dir --- .jenkins.sh | 2 ++ tests/test_daemon.sh | 28 +++++++++++++++------------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/.jenkins.sh b/.jenkins.sh index 256fe38..a67f606 100755 --- a/.jenkins.sh +++ b/.jenkins.sh @@ -25,6 +25,7 @@ function run_test { } coverage erase +mkdir tmp run_test pep8 . run_test pyflakes . run_test coverage run tests/nose_plugin.py -v @@ -47,6 +48,7 @@ run_test python tests/test.py --with-coverage -b "-m rc4-md5 -k testrc4 -s 127.0 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" coverage combine && coverage report --include=shadowsocks/* rm -rf htmlcov +rm -rf tmp coverage html --include=shadowsocks/* exit $result diff --git a/tests/test_daemon.sh b/tests/test_daemon.sh index fdfe517..02c6cf0 100755 --- a/tests/test_daemon.sh +++ b/tests/test_daemon.sh @@ -20,23 +20,25 @@ do command="coverage run -p -a shadowsocks/$module.py" -run_test 0 -c tests/aes.json -d stop --pid-file /tmp/shadowsocks.pid --log-file /tmp/shadowsocks.log +mkdir -p tmp -run_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 +run_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 start --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 -run_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 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 -run_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 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 +run_test 0 -c tests/aes.json -d start --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 +run_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 +run_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 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 -run_test 1 -c tests/aes.json -d start --pid-file /tmp/not_exist/shadowsocks.pid --log-file /tmp/shadowsocks.log -run_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 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 + +run_test 1 -c tests/aes.json -d start --pid-file tmp/not_exist/shadowsocks.pid --log-file tmp/shadowsocks.log +run_test 1 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/not_exist/shadowsocks.log done From 5ea8403e56043ea0ad50efbd8c255d32119a1b59 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Mon, 22 Dec 2014 17:58:12 +0800 Subject: [PATCH 06/13] fix daemon and add fastopen tests --- .jenkins.sh | 7 +++++++ shadowsocks/daemon.py | 13 +++++++------ tests/test.py | 2 -- tests/test_daemon.sh | 1 - 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/.jenkins.sh b/.jenkins.sh index a67f606..a8bdf15 100755 --- a/.jenkins.sh +++ b/.jenkins.sh @@ -46,6 +46,13 @@ 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 + coverage combine && coverage report --include=shadowsocks/* rm -rf htmlcov rm -rf tmp diff --git a/shadowsocks/daemon.py b/shadowsocks/daemon.py index ec6676c..d206ccf 100644 --- a/shadowsocks/daemon.py +++ b/shadowsocks/daemon.py @@ -100,19 +100,21 @@ def freopen(f, mode, stream): 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, _): if signum == signal.SIGTERM: sys.exit(0) sys.exit(1) + signal.signal(signal.SIGINT, 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 - signal.signal(signal.SIGINT, handle_exit) - signal.signal(signal.SIGTERM, handle_exit) time.sleep(5) sys.exit(0) @@ -135,7 +137,6 @@ def daemon_start(pid_file, log_file): freopen(log_file, 'a', sys.stderr) except IOError as e: logging.error(e) - os.kill(ppid, signal.SIGINT) sys.exit(1) diff --git a/tests/test.py b/tests/test.py index 721d484..0b63a18 100755 --- a/tests/test.py +++ b/tests/test.py @@ -138,9 +138,7 @@ try: finally: for p in [p1, p2]: try: - print('kill', file=sys.stderr) os.kill(p.pid, signal.SIGINT) - print('waitpid', file=sys.stderr) os.waitpid(p.pid, 0) except OSError: pass diff --git a/tests/test_daemon.sh b/tests/test_daemon.sh index 02c6cf0..40f35ef 100755 --- a/tests/test_daemon.sh +++ b/tests/test_daemon.sh @@ -39,6 +39,5 @@ run_test 0 -c tests/aes.json -d restart --pid-file tmp/shadowsocks.pid --log-fil 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 -run_test 1 -c tests/aes.json -d start --pid-file tmp/shadowsocks.pid --log-file tmp/not_exist/shadowsocks.log done From f1b084be060f5a3129e7fff4fab2c6aee7696ebf Mon Sep 17 00:00:00 2001 From: clowwindy Date: Tue, 23 Dec 2014 13:09:51 +0800 Subject: [PATCH 07/13] add large file test --- .jenkins.sh | 2 ++ .travis.yml | 4 +++- tests/test_large_file.sh | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) create mode 100755 tests/test_large_file.sh diff --git a/.jenkins.sh b/.jenkins.sh index a8bdf15..bae7f79 100755 --- a/.jenkins.sh +++ b/.jenkins.sh @@ -53,6 +53,8 @@ if [ -f /proc/sys/net/ipv4/tcp_fastopen ] ; then fi fi +run_test tests/test_large_file.sh + coverage combine && coverage report --include=shadowsocks/* rm -rf htmlcov rm -rf tmp diff --git a/.travis.yml b/.travis.yml index 3b094f2..2f9bd13 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,9 @@ cache: - dante-1.4.0 before_install: - 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 - sudo tests/socksify/install.sh - sudo tests/libsodium/install.sh diff --git a/tests/test_large_file.sh b/tests/test_large_file.sh new file mode 100755 index 0000000..3124ac9 --- /dev/null +++ b/tests/test_large_file.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +DEV=lo +PORT=8388 +DELAY=100ms + +PYTHON="coverage run -p -a" +URL=http://127.0.0.1/file + +mkdir -p tmp + +type tc > /dev/null && ( + tc qdisc add dev $DEV root handle 1: prio + tc qdisc add dev $DEV parent 1:3 handle 30: netem delay $DELAY + tc filter add dev $DEV parent 1:0 protocol ip u32 match ip dport $PORT 0xffff flowid 1:3 + tc filter add dev $DEV parent 1:0 protocol ip u32 match ip sport $PORT 0xffff flowid 1:3 + tc qdisc show dev lo +) + +$PYTHON shadowsocks/local.py -c tests/aes.json & +LOCAL=$! + +$PYTHON shadowsocks/server.py -c tests/aes.json & +SERVER=$! + +sleep 3 + +curl -o tmp/expected $URL +curl -o tmp/result --socks5-hostname 127.0.0.1:1081 $URL + +kill $LOCAL +kill $SERVER + +type tc > /dev/null && tc qdisc del dev lo root + +sleep 2 + +diff tmp/expected tmp/result || exit 1 From 9b3944c954326fd40ef4f641ea92137ae9d1feef Mon Sep 17 00:00:00 2001 From: clowwindy Date: Tue, 23 Dec 2014 13:18:30 +0800 Subject: [PATCH 08/13] fix large file test --- tests/test_large_file.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_large_file.sh b/tests/test_large_file.sh index 3124ac9..66cc13d 100755 --- a/tests/test_large_file.sh +++ b/tests/test_large_file.sh @@ -9,7 +9,7 @@ URL=http://127.0.0.1/file mkdir -p tmp -type tc > /dev/null && ( +type tc 2> /dev/null && ( tc qdisc add dev $DEV root handle 1: prio tc qdisc add dev $DEV parent 1:3 handle 30: netem delay $DELAY tc filter add dev $DEV parent 1:0 protocol ip u32 match ip dport $PORT 0xffff flowid 1:3 @@ -25,13 +25,13 @@ SERVER=$! sleep 3 -curl -o tmp/expected $URL -curl -o tmp/result --socks5-hostname 127.0.0.1:1081 $URL +time curl -o tmp/expected $URL +time curl -o tmp/result --socks5-hostname 127.0.0.1:1081 $URL kill $LOCAL kill $SERVER -type tc > /dev/null && tc qdisc del dev lo root +type tc 2> /dev/null && tc qdisc del dev lo root sleep 2 From 2cc7ee5053bc89f18377c754f348c5cf735d1a6f Mon Sep 17 00:00:00 2001 From: clowwindy Date: Tue, 23 Dec 2014 13:57:31 +0800 Subject: [PATCH 09/13] alter tc rule --- tests/test_large_file.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tests/test_large_file.sh b/tests/test_large_file.sh index 66cc13d..66e4f94 100755 --- a/tests/test_large_file.sh +++ b/tests/test_large_file.sh @@ -10,10 +10,17 @@ URL=http://127.0.0.1/file mkdir -p tmp type tc 2> /dev/null && ( - tc qdisc add dev $DEV root handle 1: prio - tc qdisc add dev $DEV parent 1:3 handle 30: netem delay $DELAY - tc filter add dev $DEV parent 1:0 protocol ip u32 match ip dport $PORT 0xffff flowid 1:3 - tc filter add dev $DEV parent 1:0 protocol ip u32 match ip sport $PORT 0xffff flowid 1:3 + 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 + +# iptables -D OUTPUT -t mangle -p tcp --sport 8388 -j MARK --set-mark 6 +# iptables -A OUTPUT -t mangle -p tcp --sport 8388 -j MARK --set-mark 6 + tc qdisc show dev lo ) From cd07001471fede6f5e3fab2fdfbc8b2d0843e51d Mon Sep 17 00:00:00 2001 From: clowwindy Date: Tue, 23 Dec 2014 14:05:20 +0800 Subject: [PATCH 10/13] use SIGINT instead in large file test --- tests/test_large_file.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_large_file.sh b/tests/test_large_file.sh index 66e4f94..14d3002 100755 --- a/tests/test_large_file.sh +++ b/tests/test_large_file.sh @@ -35,8 +35,8 @@ sleep 3 time curl -o tmp/expected $URL time curl -o tmp/result --socks5-hostname 127.0.0.1:1081 $URL -kill $LOCAL -kill $SERVER +kill -s SIGINT $LOCAL +kill -s SIGINT $SERVER type tc 2> /dev/null && tc qdisc del dev lo root From 9cfffa360e2194f7cc6ae1b88c79057acff1b54e Mon Sep 17 00:00:00 2001 From: clowwindy Date: Tue, 23 Dec 2014 14:20:46 +0800 Subject: [PATCH 11/13] sudo tc setup --- .travis.yml | 1 + tests/setup_tc.sh | 18 ++++++++++++++++++ tests/test_large_file.sh | 21 --------------------- 3 files changed, 19 insertions(+), 21 deletions(-) create mode 100755 tests/setup_tc.sh diff --git a/.travis.yml b/.travis.yml index 2f9bd13..4a88b77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,5 +15,6 @@ before_install: - pip install m2crypto salsa20 pep8 pyflakes nose coverage - sudo tests/socksify/install.sh - sudo tests/libsodium/install.sh + - sudo tests/setup_tc.sh script: - ./.jenkins.sh diff --git a/tests/setup_tc.sh b/tests/setup_tc.sh new file mode 100755 index 0000000..1a5fa20 --- /dev/null +++ b/tests/setup_tc.sh @@ -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 +) + diff --git a/tests/test_large_file.sh b/tests/test_large_file.sh index 14d3002..e8acd79 100755 --- a/tests/test_large_file.sh +++ b/tests/test_large_file.sh @@ -1,29 +1,10 @@ #!/bin/bash -DEV=lo -PORT=8388 -DELAY=100ms - PYTHON="coverage run -p -a" URL=http://127.0.0.1/file mkdir -p tmp -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 - -# iptables -D OUTPUT -t mangle -p tcp --sport 8388 -j MARK --set-mark 6 -# iptables -A OUTPUT -t mangle -p tcp --sport 8388 -j MARK --set-mark 6 - - tc qdisc show dev lo -) - $PYTHON shadowsocks/local.py -c tests/aes.json & LOCAL=$! @@ -38,8 +19,6 @@ time curl -o tmp/result --socks5-hostname 127.0.0.1:1081 $URL kill -s SIGINT $LOCAL kill -s SIGINT $SERVER -type tc 2> /dev/null && tc qdisc del dev lo root - sleep 2 diff tmp/expected tmp/result || exit 1 From 1d0c8b1800c6775b4bad02bcbb4529848d334d1a Mon Sep 17 00:00:00 2001 From: clowwindy Date: Wed, 24 Dec 2014 16:47:14 +0800 Subject: [PATCH 12/13] add coverage --- .jenkins.sh | 2 ++ README.md | 6 +++++- tests/coverage_server.py | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/coverage_server.py diff --git a/.jenkins.sh b/.jenkins.sh index bae7f79..5630511 100755 --- a/.jenkins.sh +++ b/.jenkins.sh @@ -60,4 +60,6 @@ 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 diff --git a/README.md b/README.md index 7a37b26..621d2d9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ 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. @@ -119,6 +121,8 @@ Bugs and Issues [Android]: https://github.com/clowwindy/shadowsocks/wiki/Ports-and-Clients#android [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 +[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 [the package]: https://pypi.python.org/pypi/shadowsocks [Encryption]: https://github.com/clowwindy/shadowsocks/wiki/Encryption diff --git a/tests/coverage_server.py b/tests/coverage_server.py new file mode 100644 index 0000000..4bb53df --- /dev/null +++ b/tests/coverage_server.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +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() From b785d95f66b08ba6308567ac5143ffdcc62b9947 Mon Sep 17 00:00:00 2001 From: clowwindy Date: Wed, 24 Dec 2014 17:06:15 +0800 Subject: [PATCH 13/13] fix tests --- tests/coverage_server.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/coverage_server.py b/tests/coverage_server.py index 4bb53df..7a135c5 100644 --- a/tests/coverage_server.py +++ b/tests/coverage_server.py @@ -1,23 +1,23 @@ #!/usr/bin/env python -import tornado.ioloop -import tornado.web -import urllib +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)) -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), + ]) -application = tornado.web.Application([ - (r"/shadowsocks", MainHandler), -]) - -if __name__ == "__main__": - application.listen(8888, address='127.0.0.1') - tornado.ioloop.IOLoop.instance().start() + if __name__ == "__main__": + application.listen(8888, address='127.0.0.1') + tornado.ioloop.IOLoop.instance().start()