581d6e687f
Since now the unit tests is huge, using third party website is not polite. So use localhost instead.
158 lines
4.9 KiB
Python
Executable file
158 lines
4.9 KiB
Python
Executable file
#!/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', '-a']
|
|
|
|
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
|