mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-29 20:25:13 +08:00
🌴 Sync 2026-03-05 23:51:42
This commit is contained in:
1 parent
0d155c70be
commit
32600acc60
14258 files changed
+3954570
No files matched your search
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"aes_password",
|
||||
"timeout":60,
|
||||
"method":"aes-256-cfb1",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"aes_password",
|
||||
"timeout":60,
|
||||
"method":"aes-256-cfb8",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"aes_password",
|
||||
"timeout":60,
|
||||
"method":"aes-256-ctr",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"aes_password",
|
||||
"timeout":60,
|
||||
"method":"aes-256-cfb",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
#!/bin/bash
|
||||
# assert.sh 1.0 - bash unit testing framework
|
||||
# Copyright (C) 2009, 2010, 2011, 2012 Robert Lehmann
|
||||
#
|
||||
# http://github.com/lehmannro/assert.sh
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export DISCOVERONLY=${DISCOVERONLY:-}
|
||||
export DEBUG=${DEBUG:-}
|
||||
export STOP=${STOP:-}
|
||||
export INVARIANT=${INVARIANT:-}
|
||||
export CONTINUE=${CONTINUE:-}
|
||||
|
||||
args="$(getopt -n "$0" -l \
|
||||
verbose,help,stop,discover,invariant,continue vhxdic $*)" \
|
||||
|| exit -1
|
||||
for arg in $args; do
|
||||
case "$arg" in
|
||||
-h)
|
||||
echo "$0 [-vxidc]" \
|
||||
"[--verbose] [--stop] [--invariant] [--discover] [--continue]"
|
||||
echo "`sed 's/./ /g' <<< "$0"` [-h] [--help]"
|
||||
exit 0;;
|
||||
--help)
|
||||
cat <<EOF
|
||||
Usage: $0 [options]
|
||||
Language-agnostic unit tests for subprocesses.
|
||||
|
||||
Options:
|
||||
-v, --verbose generate output for every individual test case
|
||||
-x, --stop stop running tests after the first failure
|
||||
-i, --invariant do not measure timings to remain invariant between runs
|
||||
-d, --discover collect test suites only, do not run any tests
|
||||
-c, --continue do not modify exit code to test suite status
|
||||
-h show brief usage information and exit
|
||||
--help show this help message and exit
|
||||
EOF
|
||||
exit 0;;
|
||||
-v|--verbose)
|
||||
DEBUG=1;;
|
||||
-x|--stop)
|
||||
STOP=1;;
|
||||
-i|--invariant)
|
||||
INVARIANT=1;;
|
||||
-d|--discover)
|
||||
DISCOVERONLY=1;;
|
||||
-c|--continue)
|
||||
CONTINUE=1;;
|
||||
esac
|
||||
done
|
||||
|
||||
printf -v _indent "\n\t" # local format helper
|
||||
|
||||
_assert_reset() {
|
||||
tests_ran=0
|
||||
tests_failed=0
|
||||
tests_errors=()
|
||||
tests_starttime="$(date +%s.%N)" # seconds_since_epoch.nanoseconds
|
||||
}
|
||||
|
||||
assert_end() {
|
||||
# assert_end [suite ..]
|
||||
tests_endtime="$(date +%s.%N)"
|
||||
tests="$tests_ran ${*:+$* }tests"
|
||||
[[ -n "$DISCOVERONLY" ]] && echo "collected $tests." && _assert_reset && return
|
||||
[[ -n "$DEBUG" ]] && echo
|
||||
[[ -z "$INVARIANT" ]] && report_time=" in $(bc \
|
||||
<<< "${tests_endtime%.N} - ${tests_starttime%.N}" \
|
||||
| sed -e 's/\.\([0-9]\{0,3\}\)[0-9]*/.\1/' -e 's/^\./0./')s" \
|
||||
|| report_time=
|
||||
|
||||
if [[ "$tests_failed" -eq 0 ]]; then
|
||||
echo "all $tests passed$report_time."
|
||||
else
|
||||
for error in "${tests_errors[@]}"; do echo "$error"; done
|
||||
echo "$tests_failed of $tests failed$report_time."
|
||||
fi
|
||||
tests_failed_previous=$tests_failed
|
||||
[[ $tests_failed -gt 0 ]] && tests_suite_status=1
|
||||
_assert_reset
|
||||
return $tests_failed_previous
|
||||
}
|
||||
|
||||
assert() {
|
||||
# assert <command> <expected stdout> [stdin]
|
||||
(( tests_ran++ )) || :
|
||||
[[ -n "$DISCOVERONLY" ]] && return || true
|
||||
# printf required for formatting
|
||||
printf -v expected "x${2:-}" # x required to overwrite older results
|
||||
result="$(eval 2>/dev/null $1 <<< ${3:-})" || true
|
||||
# Note: $expected is already decorated
|
||||
if [[ "x$result" == "$expected" ]]; then
|
||||
[[ -n "$DEBUG" ]] && echo -n . || true
|
||||
return
|
||||
fi
|
||||
result="$(sed -e :a -e '$!N;s/\n/\\n/;ta' <<< "$result")"
|
||||
[[ -z "$result" ]] && result="nothing" || result="\"$result\""
|
||||
[[ -z "$2" ]] && expected="nothing" || expected="\"$2\""
|
||||
_assert_fail "expected $expected${_indent}got $result" "$1" "$3"
|
||||
}
|
||||
|
||||
assert_raises() {
|
||||
# assert_raises <command> <expected code> [stdin]
|
||||
(( tests_ran++ )) || :
|
||||
[[ -n "$DISCOVERONLY" ]] && return || true
|
||||
status=0
|
||||
(eval $1 <<< ${3:-}) > /dev/null 2>&1 || status=$?
|
||||
expected=${2:-0}
|
||||
if [[ "$status" -eq "$expected" ]]; then
|
||||
[[ -n "$DEBUG" ]] && echo -n . || true
|
||||
return
|
||||
fi
|
||||
_assert_fail "program terminated with code $status instead of $expected" "$1" "$3"
|
||||
}
|
||||
|
||||
_assert_fail() {
|
||||
# _assert_fail <failure> <command> <stdin>
|
||||
[[ -n "$DEBUG" ]] && echo -n X
|
||||
report="test #$tests_ran \"$2${3:+ <<< $3}\" failed:${_indent}$1"
|
||||
if [[ -n "$STOP" ]]; then
|
||||
[[ -n "$DEBUG" ]] && echo
|
||||
echo "$report"
|
||||
exit 1
|
||||
fi
|
||||
tests_errors[$tests_failed]="$report"
|
||||
(( tests_failed++ )) || :
|
||||
}
|
||||
|
||||
_assert_reset
|
||||
: ${tests_suite_status:=0} # remember if any of the tests failed so far
|
||||
_assert_cleanup() {
|
||||
local status=$?
|
||||
# modify exit code if it's not already non-zero
|
||||
[[ $status -eq 0 && -z $CONTINUE ]] && exit $tests_suite_status
|
||||
}
|
||||
trap _assert_cleanup EXIT
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"salsa20_password",
|
||||
"timeout":60,
|
||||
"method":"chacha20",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":["127.0.0.1", "127.0.0.1"],
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"aes_password",
|
||||
"timeout":60,
|
||||
"method":"aes-256-cfb",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2015 clowwindy
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
if __name__ == '__main__':
|
||||
import tornado.ioloop
|
||||
import tornado.web
|
||||
import urllib
|
||||
|
||||
class MainHandler(tornado.web.RequestHandler):
|
||||
def get(self, project):
|
||||
try:
|
||||
with open('/tmp/%s-coverage' % project, 'rb') as f:
|
||||
coverage = f.read().strip()
|
||||
n = int(coverage.strip('%'))
|
||||
if n >= 80:
|
||||
color = 'brightgreen'
|
||||
else:
|
||||
color = 'yellow'
|
||||
self.redirect(('https://img.shields.io/badge/'
|
||||
'coverage-%s-%s.svg'
|
||||
'?style=flat') %
|
||||
(urllib.quote(coverage), color))
|
||||
except IOError:
|
||||
raise tornado.web.HTTPError(404)
|
||||
|
||||
application = tornado.web.Application([
|
||||
(r"/([a-zA-Z0-9\-_]+)", MainHandler),
|
||||
])
|
||||
|
||||
if __name__ == "__main__":
|
||||
application.listen(8888, address='127.0.0.1')
|
||||
tornado.ioloop.IOLoop.instance().start()
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"fastopen_password",
|
||||
"timeout":60,
|
||||
"method":"aes-256-cfb",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":true
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"::1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"aes_password",
|
||||
"timeout":60,
|
||||
"method":"aes-256-cfb",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"::",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"aes_password",
|
||||
"timeout":60,
|
||||
"method":"aes-256-cfb",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
#!/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
|
||||
}
|
||||
|
||||
python --version
|
||||
coverage erase
|
||||
mkdir tmp
|
||||
run_test pep8 --ignore=E402 .
|
||||
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/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/aes.json -c tests/client-multi-server-ip.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 -q" -a "-m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -vv"
|
||||
run_test python tests/test.py --with-coverage -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --workers 1" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -qq -b 127.0.0.1"
|
||||
run_test python tests/test.py --with-coverage --should-fail --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --forbidden-ip=127.0.0.1,::1,8.8.8.8" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1"
|
||||
|
||||
# test if DNS works
|
||||
run_test python tests/test.py --with-coverage -c tests/aes.json --url="https://clients1.google.com/generate_204"
|
||||
|
||||
# test localhost is in the forbidden list by default
|
||||
run_test python tests/test.py --with-coverage --should-fail --tcp-only --url="http://127.0.0.1/" -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 -t 30 -b 127.0.0.1"
|
||||
|
||||
# test localhost is available when forbidden list is empty
|
||||
run_test python tests/test.py --with-coverage --tcp-only --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --forbidden-ip=" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1"
|
||||
|
||||
if [ -f /proc/sys/net/ipv4/tcp_fastopen ] ; then
|
||||
if [ 3 -eq `cat /proc/sys/net/ipv4/tcp_fastopen` ] ; then
|
||||
# we have to run it twice:
|
||||
# the first time there's no syn cookie
|
||||
# the second time there is syn cookie
|
||||
run_test python tests/test.py --with-coverage -c tests/fastopen.json
|
||||
run_test python tests/test.py --with-coverage -c tests/fastopen.json
|
||||
fi
|
||||
fi
|
||||
|
||||
run_test tests/test_large_file.sh
|
||||
run_test tests/test_udp_src.sh
|
||||
run_test tests/test_command.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
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ ! -d libsodium-1.0.1 ]; then
|
||||
wget https://github.com/jedisct1/libsodium/releases/download/1.0.1/libsodium-1.0.1.tar.gz || exit 1
|
||||
tar xf libsodium-1.0.1.tar.gz || exit 1
|
||||
fi
|
||||
pushd libsodium-1.0.1
|
||||
./configure && make -j2 && make install || exit 1
|
||||
sudo ldconfig
|
||||
popd
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2015 clowwindy
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import nose
|
||||
from nose.plugins.base import Plugin
|
||||
|
||||
|
||||
class ExtensionPlugin(Plugin):
|
||||
|
||||
name = "ExtensionPlugin"
|
||||
|
||||
def options(self, parser, env):
|
||||
Plugin.options(self, parser, env)
|
||||
|
||||
def configure(self, options, config):
|
||||
Plugin.configure(self, options, config)
|
||||
self.enabled = True
|
||||
|
||||
def wantFile(self, file):
|
||||
return file.endswith('.py')
|
||||
|
||||
def wantDirectory(self, directory):
|
||||
return True
|
||||
|
||||
def wantModule(self, file):
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
nose.main(addplugins=[ExtensionPlugin()])
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"aes_password",
|
||||
"timeout":60,
|
||||
"method":"rc4-md5",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"salsa20_password",
|
||||
"timeout":60,
|
||||
"method":"salsa20-ctr",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"salsa20_password",
|
||||
"timeout":60,
|
||||
"method":"salsa20",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"server": "127.0.0.1",
|
||||
"server_port": "8385",
|
||||
"local_port": 1081,
|
||||
"password": "foobar5",
|
||||
"timeout": 60,
|
||||
"method": "aes-256-cfb"
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"server": "127.0.0.1",
|
||||
"server_port": 8384,
|
||||
"local_port": 1081,
|
||||
"password": "foobar4",
|
||||
"port_password": {
|
||||
"8381": "foobar1",
|
||||
"8382": "foobar2",
|
||||
"8383": "foobar3",
|
||||
"8384": "foobar4",
|
||||
"8385": "foobar5",
|
||||
"8386": "foobar6",
|
||||
"8387": "foobar7",
|
||||
"8388": "foobar8",
|
||||
"8389": "foobar9"
|
||||
},
|
||||
"timeout": 60,
|
||||
"method": "table"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"server": "127.0.0.1",
|
||||
"local_port": 1081,
|
||||
"port_password": {
|
||||
"8381": "foobar1",
|
||||
"8382": "foobar2",
|
||||
"8383": "foobar3",
|
||||
"8384": "foobar4",
|
||||
"8385": "foobar5",
|
||||
"8386": "foobar6",
|
||||
"8387": "foobar7",
|
||||
"8388": "foobar8",
|
||||
"8389": "foobar9"
|
||||
},
|
||||
"timeout": 60,
|
||||
"method": "aes-256-cfb"
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"server": "127.0.0.1",
|
||||
"server_port": [8384, 8345, 8346, 8347],
|
||||
"local_port": 1081,
|
||||
"password": "foobar4",
|
||||
"timeout": 60,
|
||||
"method": "aes-256-cfb"
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ ! -d dante-1.4.0 ]; then
|
||||
wget http://www.inet.no/dante/files/dante-1.4.0.tar.gz || exit 1
|
||||
tar xf dante-1.4.0.tar.gz || exit 1
|
||||
fi
|
||||
pushd dante-1.4.0
|
||||
./configure && make -j4 && make install || exit 1
|
||||
popd
|
||||
cp tests/socksify/socks.conf /etc/ || exit 1
|
||||
@@ -0,0 +1,5 @@
|
||||
route {
|
||||
from: 0.0.0.0/0 to: 0.0.0.0/0 via: 127.0.0.1 port = 1081
|
||||
proxyprotocol: socks_v5
|
||||
method: none
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"table_password",
|
||||
"timeout":60,
|
||||
"method":"table",
|
||||
"local_address":"127.0.0.1",
|
||||
"fast_open":false
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright 2015 clowwindy
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from __future__ import absolute_import, division, print_function, \
|
||||
with_statement
|
||||
|
||||
import sys
|
||||
import os
|
||||
import signal
|
||||
import select
|
||||
import time
|
||||
import argparse
|
||||
from subprocess import Popen, PIPE
|
||||
|
||||
python = ['python']
|
||||
|
||||
default_url = 'http://localhost/'
|
||||
|
||||
parser = argparse.ArgumentParser(description='test Shadowsocks')
|
||||
parser.add_argument('-c', '--client-conf', type=str, default=None)
|
||||
parser.add_argument('-s', '--server-conf', type=str, default=None)
|
||||
parser.add_argument('-a', '--client-args', type=str, default=None)
|
||||
parser.add_argument('-b', '--server-args', type=str, default=None)
|
||||
parser.add_argument('--with-coverage', action='store_true', default=None)
|
||||
parser.add_argument('--should-fail', action='store_true', default=None)
|
||||
parser.add_argument('--tcp-only', action='store_true', default=None)
|
||||
parser.add_argument('--url', type=str, default=default_url)
|
||||
parser.add_argument('--dns', type=str, default='8.8.8.8')
|
||||
|
||||
config = parser.parse_args()
|
||||
|
||||
if config.with_coverage:
|
||||
python = ['coverage', 'run', '-p']
|
||||
|
||||
client_args = python + ['shadowsocks/local.py', '-v']
|
||||
server_args = python + ['shadowsocks/server.py', '-v']
|
||||
|
||||
if config.client_conf:
|
||||
client_args.extend(['-c', config.client_conf])
|
||||
if config.server_conf:
|
||||
server_args.extend(['-c', config.server_conf])
|
||||
else:
|
||||
server_args.extend(['-c', config.client_conf])
|
||||
if config.client_args:
|
||||
client_args.extend(config.client_args.split())
|
||||
if config.server_args:
|
||||
server_args.extend(config.server_args.split())
|
||||
else:
|
||||
server_args.extend(config.client_args.split())
|
||||
if config.url == default_url:
|
||||
server_args.extend(['--forbidden-ip', ''])
|
||||
|
||||
p1 = Popen(server_args, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
|
||||
p2 = Popen(client_args, stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
|
||||
p3 = None
|
||||
p4 = None
|
||||
p3_fin = False
|
||||
p4_fin = False
|
||||
|
||||
# 1 shadowsocks started
|
||||
# 2 curl started
|
||||
# 3 curl finished
|
||||
# 4 dig started
|
||||
# 5 dig finished
|
||||
stage = 1
|
||||
|
||||
try:
|
||||
local_ready = False
|
||||
server_ready = False
|
||||
fdset = [p1.stdout, p2.stdout, p1.stderr, p2.stderr]
|
||||
while True:
|
||||
r, w, e = select.select(fdset, [], fdset)
|
||||
if e:
|
||||
break
|
||||
|
||||
for fd in r:
|
||||
line = fd.readline()
|
||||
if not line:
|
||||
if stage == 2 and fd == p3.stdout:
|
||||
stage = 3
|
||||
if stage == 4 and fd == p4.stdout:
|
||||
stage = 5
|
||||
if bytes != str:
|
||||
line = str(line, 'utf8')
|
||||
sys.stderr.write(line)
|
||||
if line.find('starting local') >= 0:
|
||||
local_ready = True
|
||||
if line.find('starting server') >= 0:
|
||||
server_ready = True
|
||||
|
||||
if stage == 1:
|
||||
time.sleep(2)
|
||||
|
||||
p3 = Popen(['curl', config.url, '-v', '-L',
|
||||
'--socks5-hostname', '127.0.0.1:1081',
|
||||
'-m', '15', '--connect-timeout', '10'],
|
||||
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
|
||||
if p3 is not None:
|
||||
fdset.append(p3.stdout)
|
||||
fdset.append(p3.stderr)
|
||||
stage = 2
|
||||
else:
|
||||
sys.exit(1)
|
||||
|
||||
if stage == 3 and p3 is not None:
|
||||
fdset.remove(p3.stdout)
|
||||
fdset.remove(p3.stderr)
|
||||
r = p3.wait()
|
||||
if config.should_fail:
|
||||
if r == 0:
|
||||
sys.exit(1)
|
||||
else:
|
||||
if r != 0:
|
||||
sys.exit(1)
|
||||
if config.tcp_only:
|
||||
break
|
||||
p4 = Popen(['socksify', 'dig', '@%s' % config.dns,
|
||||
'www.google.com'],
|
||||
stdin=PIPE, stdout=PIPE, stderr=PIPE, close_fds=True)
|
||||
if p4 is not None:
|
||||
fdset.append(p4.stdout)
|
||||
fdset.append(p4.stderr)
|
||||
stage = 4
|
||||
else:
|
||||
sys.exit(1)
|
||||
|
||||
if stage == 5:
|
||||
r = p4.wait()
|
||||
if config.should_fail:
|
||||
if r == 0:
|
||||
sys.exit(1)
|
||||
print('test passed (expecting failure)')
|
||||
else:
|
||||
if r != 0:
|
||||
sys.exit(1)
|
||||
print('test passed')
|
||||
break
|
||||
finally:
|
||||
for p in [p1, p2]:
|
||||
try:
|
||||
os.kill(p.pid, signal.SIGINT)
|
||||
os.waitpid(p.pid, 0)
|
||||
except OSError:
|
||||
pass
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/bin/bash
|
||||
|
||||
. tests/assert.sh
|
||||
|
||||
PYTHON="coverage run -p"
|
||||
LOCAL="$PYTHON shadowsocks/local.py"
|
||||
SERVER="$PYTHON shadowsocks/server.py"
|
||||
|
||||
assert "$LOCAL --version 2>&1 | grep Shadowsocks | awk -F\" \" '{print \$1}'" "Shadowsocks"
|
||||
assert "$SERVER --version 2>&1 | grep Shadowsocks | awk -F\" \" '{print \$1}'" "Shadowsocks"
|
||||
|
||||
|
||||
assert "$LOCAL 2>&1 -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d start | grep WARNING | awk -F\"WARNING\" '{print \$2}'" " warning: server set to listen on 127.0.0.1:8388, are you sure?"
|
||||
$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop
|
||||
|
||||
assert "$LOCAL 2>&1 -m rc4-md5 -k testrc4 -s 0.0.0.0 -p 8388 -t10 -d start | grep WARNING | awk -F\"WARNING\" '{print \$2}'" " warning: your timeout 10 seems too short"
|
||||
$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop
|
||||
|
||||
assert "$LOCAL 2>&1 -m rc4-md5 -k testrc4 -s 0.0.0.0 -p 8388 -t1000 -d start | grep WARNING | awk -F\"WARNING\" '{print \$2}'" " warning: your timeout 1000 seems too long"
|
||||
$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop
|
||||
|
||||
assert "$LOCAL 2>&1 -m rc4 -k testrc4 -s 0.0.0.0 -p 8388 -d start | grep WARNING | awk -F\"WARNING\" '{print \$2}'" " warning: RC4 is not safe; please use a safer cipher, like AES-256-CFB"
|
||||
$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop
|
||||
|
||||
assert "$LOCAL 2>&1 -m rc4-md5 -k mypassword -s 0.0.0.0 -p 8388 -d start | grep ERROR | awk -F\"ERROR\" '{print \$2}'" " DON'T USE DEFAULT PASSWORD! Please change it in your config.json!"
|
||||
$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop
|
||||
|
||||
|
||||
assert "$SERVER 2>&1 --forbidden-ip 127.0.0.1/4a -m rc4-md5 -k 12345 -p 8388 -s 0.0.0.0 -d start | grep ERROR | awk -F\"ERROR\" '{print \$2}'" ": Not a valid CIDR notation: 127.0.0.1/4a"
|
||||
$LOCAL 2>/dev/null 1>/dev/null -m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -d stop
|
||||
|
||||
assert_end command
|
||||
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
|
||||
function run_test {
|
||||
expected=$1
|
||||
shift
|
||||
echo "running test: $command $@"
|
||||
$command $@
|
||||
status=$?
|
||||
if [ $status -ne $expected ]; then
|
||||
echo "exit $status != $expected"
|
||||
exit 1
|
||||
fi
|
||||
echo "exit status $status == $expected"
|
||||
echo OK
|
||||
return
|
||||
}
|
||||
|
||||
for module in local server
|
||||
do
|
||||
|
||||
command="coverage run -p shadowsocks/$module.py"
|
||||
|
||||
mkdir -p tmp
|
||||
|
||||
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 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 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 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
|
||||
|
||||
done
|
||||
@@ -0,0 +1,24 @@
|
||||
#!/bin/bash
|
||||
|
||||
PYTHON="coverage run -p"
|
||||
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 --forbidden-ip "" &
|
||||
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
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import socket
|
||||
import socks
|
||||
|
||||
|
||||
SERVER_IP = '127.0.0.1'
|
||||
SERVER_PORT = 1081
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Test 1: same source port IPv4
|
||||
sock_out = socks.socksocket(socket.AF_INET, socket.SOCK_DGRAM,
|
||||
socket.SOL_UDP)
|
||||
sock_out.set_proxy(socks.SOCKS5, SERVER_IP, SERVER_PORT)
|
||||
sock_out.bind(('127.0.0.1', 9000))
|
||||
|
||||
sock_in1 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
|
||||
socket.SOL_UDP)
|
||||
sock_in2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM,
|
||||
socket.SOL_UDP)
|
||||
|
||||
sock_in1.bind(('127.0.0.1', 9001))
|
||||
sock_in2.bind(('127.0.0.1', 9002))
|
||||
|
||||
sock_out.sendto(b'data', ('127.0.0.1', 9001))
|
||||
result1 = sock_in1.recvfrom(8)
|
||||
|
||||
sock_out.sendto(b'data', ('127.0.0.1', 9002))
|
||||
result2 = sock_in2.recvfrom(8)
|
||||
|
||||
sock_out.close()
|
||||
sock_in1.close()
|
||||
sock_in2.close()
|
||||
|
||||
# make sure they're from the same source port
|
||||
assert result1 == result2
|
||||
|
||||
# Test 2: same source port IPv6
|
||||
# try again from the same port but IPv6
|
||||
sock_out = socks.socksocket(socket.AF_INET, socket.SOCK_DGRAM,
|
||||
socket.SOL_UDP)
|
||||
sock_out.set_proxy(socks.SOCKS5, SERVER_IP, SERVER_PORT)
|
||||
sock_out.bind(('127.0.0.1', 9000))
|
||||
|
||||
sock_in1 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM,
|
||||
socket.SOL_UDP)
|
||||
sock_in2 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM,
|
||||
socket.SOL_UDP)
|
||||
|
||||
sock_in1.bind(('::1', 9001))
|
||||
sock_in2.bind(('::1', 9002))
|
||||
|
||||
sock_out.sendto(b'data', ('::1', 9001))
|
||||
result1 = sock_in1.recvfrom(8)
|
||||
|
||||
sock_out.sendto(b'data', ('::1', 9002))
|
||||
result2 = sock_in2.recvfrom(8)
|
||||
|
||||
sock_out.close()
|
||||
sock_in1.close()
|
||||
sock_in2.close()
|
||||
|
||||
# make sure they're from the same source port
|
||||
assert result1 == result2
|
||||
|
||||
# Test 3: different source ports IPv6
|
||||
sock_out = socks.socksocket(socket.AF_INET, socket.SOCK_DGRAM,
|
||||
socket.SOL_UDP)
|
||||
sock_out.set_proxy(socks.SOCKS5, SERVER_IP, SERVER_PORT)
|
||||
sock_out.bind(('127.0.0.1', 9003))
|
||||
|
||||
sock_in1 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM,
|
||||
socket.SOL_UDP)
|
||||
sock_in1.bind(('::1', 9001))
|
||||
sock_out.sendto(b'data', ('::1', 9001))
|
||||
result3 = sock_in1.recvfrom(8)
|
||||
|
||||
# make sure they're from different source ports
|
||||
assert result1 != result3
|
||||
|
||||
sock_out.close()
|
||||
sock_in1.close()
|
||||
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
PYTHON="coverage run -p"
|
||||
|
||||
mkdir -p tmp
|
||||
|
||||
$PYTHON shadowsocks/local.py -c tests/aes.json -v &
|
||||
LOCAL=$!
|
||||
|
||||
$PYTHON shadowsocks/server.py -c tests/aes.json --forbidden-ip "" -v &
|
||||
SERVER=$!
|
||||
|
||||
sleep 3
|
||||
|
||||
python tests/test_udp_src.py
|
||||
r=$?
|
||||
|
||||
kill -s SIGINT $LOCAL
|
||||
kill -s SIGINT $SERVER
|
||||
|
||||
sleep 2
|
||||
|
||||
exit $r
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"server":"127.0.0.1",
|
||||
"server_port":8388,
|
||||
"local_port":1081,
|
||||
"password":"workers_password",
|
||||
"timeout":60,
|
||||
"method":"aes-256-cfb",
|
||||
"local_address":"127.0.0.1",
|
||||
"workers": 4
|
||||
}
|
||||
Reference in new issue
Block a user