Browse Source

update: enhanced testing experience

master
dnomd343 2 years ago
parent
commit
91ba0efbb4
  1. 8
      Tester/Brook.py
  2. 8
      Tester/Hysteria.py
  3. 6
      Tester/Plugin.py
  4. 12
      Tester/Settings.py
  5. 8
      Tester/Shadowsocks.py
  6. 9
      Tester/ShadowsocksR.py
  7. 10
      Tester/Trojan.py
  8. 8
      Tester/TrojanGo.py
  9. 5
      Tester/V2ray.py
  10. 8
      Tester/VLESS.py
  11. 8
      Tester/VMess.py
  12. 6
      Tester/Xray.py
  13. 113
      Tester/__init__.py
  14. 157
      test.py

8
Tester/Brook.py

@ -4,12 +4,10 @@
import copy import copy
import itertools import itertools
from Builder import Brook from Builder import Brook
from Tester import Settings
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Process import Process from Basis.Process import Process
from Basis.Functions import genFlag from Tester.Settings import Settings
from Basis.Functions import hostFormat from Basis.Functions import hostFormat, genFlag, getAvailablePort
from Basis.Functions import getAvailablePort
def originStream(isUot: bool) -> dict: def originStream(isUot: bool) -> dict:
@ -68,7 +66,7 @@ def loadTest(stream: dict) -> dict:
clientCommand, _, _ = Brook.load(proxyInfo, socksInfo, '') clientCommand, _, _ = Brook.load(proxyInfo, socksInfo, '')
serverCommand = ['brook', '--debug', '--listen', ':'] + stream['command'](proxyInfo) serverCommand = ['brook', '--debug', '--listen', ':'] + stream['command'](proxyInfo)
testInfo = { # release test info testInfo = { # release test info
'title': 'Brook test: ' + stream['caption'], 'caption': 'Brook test: ' + stream['caption'],
'client': Process(Settings['workDir'], cmd = clientCommand, isStart = False), 'client': Process(Settings['workDir'], cmd = clientCommand, isStart = False),
'server': Process(Settings['workDir'], cmd = serverCommand, isStart = False), 'server': Process(Settings['workDir'], cmd = serverCommand, isStart = False),
'socks': socksInfo, # exposed socks5 address 'socks': socksInfo, # exposed socks5 address

8
Tester/Hysteria.py

@ -4,14 +4,12 @@
import os import os
import json import json
import itertools import itertools
from Tester import Settings
from Builder import Hysteria from Builder import Hysteria
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Process import Process from Basis.Process import Process
from Basis.Functions import genFlag from Tester.Settings import Settings
from Basis.Functions import hostFormat
from Basis.Methods import hysteriaProtocols from Basis.Methods import hysteriaProtocols
from Basis.Functions import getAvailablePort from Basis.Functions import hostFormat, genFlag, getAvailablePort
def loadServer(configFile: str, hysteriaConfig: dict) -> Process: def loadServer(configFile: str, hysteriaConfig: dict) -> Process:
@ -71,7 +69,7 @@ def loadTest(protocol: str, isObfs: bool, isAuth: bool) -> dict:
'config': [proxyInfo['passwd']] 'config': [proxyInfo['passwd']]
} }
testInfo = { testInfo = {
'title': caption, 'caption': caption,
'client': loadClient(configName + '_client.json', proxyInfo, socksInfo), 'client': loadClient(configName + '_client.json', proxyInfo, socksInfo),
'server': loadServer(configName + '_server.json', serverConfig), 'server': loadServer(configName + '_server.json', serverConfig),
'socks': socksInfo, # exposed socks5 address 'socks': socksInfo, # exposed socks5 address

6
Tester/Plugin.py

@ -4,13 +4,11 @@
import os import os
import re import re
import json import json
from Tester import Settings
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Process import Process from Basis.Process import Process
from Basis.Methods import plugins from Basis.Methods import plugins
from Basis.Functions import genFlag from Tester.Settings import Settings
from Basis.Functions import hostFormat from Basis.Functions import genFlag, hostFormat, getAvailablePort
from Basis.Functions import getAvailablePort
pluginParams = { pluginParams = {

12
Tester/Settings.py

@ -0,0 +1,12 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
Settings = {
'workDir': '/tmp/ProxyC',
'serverBind': '127.0.0.1',
'clientBind': '127.0.0.1',
'site': 'www.bing.com',
'host': '343.re',
'cert': '/etc/ssl/certs/343.re/fullchain.pem',
'key': '/etc/ssl/certs/343.re/privkey.pem',
}

8
Tester/Shadowsocks.py

@ -6,14 +6,12 @@ import json
import base64 import base64
import itertools import itertools
from Tester import Plugin from Tester import Plugin
from Tester import Settings
from Builder import Shadowsocks from Builder import Shadowsocks
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Process import Process from Basis.Process import Process
from Basis.Functions import md5Sum from Tester.Settings import Settings
from Basis.Functions import genFlag
from Basis.Functions import getAvailablePort
from Basis.Methods import ssMethods, ssAllMethods from Basis.Methods import ssMethods, ssAllMethods
from Basis.Functions import md5Sum, genFlag, getAvailablePort
def loadConfig(proxyInfo: dict) -> dict: # load basic config option def loadConfig(proxyInfo: dict) -> dict: # load basic config option
@ -126,7 +124,7 @@ def loadTest(serverType: str, clientType: str, method: str, plugin: dict or None
configName += '_%s_%s' % (plugin['type'], md5Sum(plugin['type'] + plugin['caption'])[:8]) configName += '_%s_%s' % (plugin['type'], md5Sum(plugin['type'] + plugin['caption'])[:8])
pluginText = '' if plugin is None else (' [%s -> %s]' % (plugin['type'], plugin['caption'])) pluginText = '' if plugin is None else (' [%s -> %s]' % (plugin['type'], plugin['caption']))
testInfo = { # release test info testInfo = { # release test info
'title': 'Shadowsocks test: {%s <- %s -> %s}%s' % (serverType, method, clientType, pluginText), 'caption': 'Shadowsocks test: {%s <- %s -> %s}%s' % (serverType, method, clientType, pluginText),
'client': loadClient(clientType, configName + '_client.json', {**proxyInfo, **pluginClient}, socksInfo), 'client': loadClient(clientType, configName + '_client.json', {**proxyInfo, **pluginClient}, socksInfo),
'server': loadServer(serverType, configName + '_server.json', {**proxyInfo, **pluginServer}), 'server': loadServer(serverType, configName + '_server.json', {**proxyInfo, **pluginServer}),
'socks': socksInfo, # exposed socks5 address 'socks': socksInfo, # exposed socks5 address

9
Tester/ShadowsocksR.py

@ -3,12 +3,11 @@
import os import os
import json import json
from Tester import Settings
from Basis.Logger import logging
from Builder import ShadowsocksR from Builder import ShadowsocksR
from Basis.Logger import logging
from Basis.Process import Process from Basis.Process import Process
from Basis.Functions import genFlag from Tester.Settings import Settings
from Basis.Functions import getAvailablePort from Basis.Functions import genFlag, getAvailablePort
from Basis.Methods import ssrMethods, ssrProtocols, ssrObfuscations from Basis.Methods import ssrMethods, ssrProtocols, ssrObfuscations
@ -56,7 +55,7 @@ def loadTest(method: str, protocol: str, obfs: str) -> dict:
} }
configName = 'ssr_%s_%s_%s' % (method, protocol, obfs) # prefix of config file name configName = 'ssr_%s_%s_%s' % (method, protocol, obfs) # prefix of config file name
testInfo = { # release test info testInfo = { # release test info
'title': 'ShadowsocksR test: method = %s | protocol = %s | obfs = %s' % (method, protocol, obfs), 'caption': 'ShadowsocksR test: method = %s | protocol = %s | obfs = %s' % (method, protocol, obfs),
'client': loadClient(configName + '_client.json', proxyInfo, socksInfo), 'client': loadClient(configName + '_client.json', proxyInfo, socksInfo),
'server': loadServer(configName + '_server.json', proxyInfo), 'server': loadServer(configName + '_server.json', proxyInfo),
'socks': socksInfo, # exposed socks5 address 'socks': socksInfo, # exposed socks5 address

10
Tester/Trojan.py

@ -5,13 +5,11 @@ import os
import json import json
from Tester import Xray from Tester import Xray
from Builder import Trojan from Builder import Trojan
from Tester import Settings
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Process import Process from Basis.Process import Process
from Basis.Functions import md5Sum
from Basis.Methods import xtlsFlows from Basis.Methods import xtlsFlows
from Basis.Functions import genFlag from Tester.Settings import Settings
from Basis.Functions import getAvailablePort from Basis.Functions import md5Sum, genFlag, getAvailablePort
def loadServer(configFile: str, proxyInfo: dict, streamConfig: dict, xtlsFlow: str or None) -> Process: def loadServer(configFile: str, proxyInfo: dict, streamConfig: dict, xtlsFlow: str or None) -> Process:
@ -72,7 +70,7 @@ def loadBasicTest(tcpTlsStream: dict) -> dict:
'content': json.dumps(trojanConfig) 'content': json.dumps(trojanConfig)
}, isStart = False) }, isStart = False)
testInfo = { # release test info testInfo = { # release test info
'title': 'Trojan test: basic connection', 'caption': 'Trojan test: basic connection',
'client': loadClient('trojan_basic_client.json', proxyInfo, socksInfo), 'client': loadClient('trojan_basic_client.json', proxyInfo, socksInfo),
'server': trojanServer, 'server': trojanServer,
'socks': socksInfo, # exposed socks5 address 'socks': socksInfo, # exposed socks5 address
@ -102,7 +100,7 @@ def loadTest(stream: dict) -> dict:
xtlsFlow = xtlsFlow.replace('splice', 'direct') # XTLS on server should use xtls-rprx-direct flow xtlsFlow = xtlsFlow.replace('splice', 'direct') # XTLS on server should use xtls-rprx-direct flow
configName = 'trojan_%s' % (md5Sum(stream['caption'])[:8]) configName = 'trojan_%s' % (md5Sum(stream['caption'])[:8])
testInfo = { # release test info testInfo = { # release test info
'title': 'Trojan test: %s' % stream['caption'], 'caption': 'Trojan test: %s' % stream['caption'],
'client': loadClient(configName + '_client.json', proxyInfo, socksInfo), 'client': loadClient(configName + '_client.json', proxyInfo, socksInfo),
'server': loadServer(configName + '_server.json', proxyInfo, stream['server'], xtlsFlow), 'server': loadServer(configName + '_server.json', proxyInfo, stream['server'], xtlsFlow),
'socks': socksInfo, # exposed socks5 address 'socks': socksInfo, # exposed socks5 address

8
Tester/TrojanGo.py

@ -4,14 +4,12 @@
import os import os
import json import json
from Tester import Plugin from Tester import Plugin
from Tester import Settings
from Builder import TrojanGo from Builder import TrojanGo
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Process import Process from Basis.Process import Process
from Basis.Functions import md5Sum from Tester.Settings import Settings
from Basis.Functions import genFlag
from Basis.Methods import trojanGoMethods from Basis.Methods import trojanGoMethods
from Basis.Functions import getAvailablePort from Basis.Functions import md5Sum, genFlag, getAvailablePort
def loadServer(configFile: str, proxyInfo: dict) -> Process: def loadServer(configFile: str, proxyInfo: dict) -> Process:
@ -76,7 +74,7 @@ def loadTest(wsObject: dict or None, ssObject: dict or None, plugin: dict or Non
('' if wsObject is None else ' (with websocket)') + \ ('' if wsObject is None else ' (with websocket)') + \
('' if plugin is None else ' [%s -> %s]' % (plugin['type'], plugin['caption'])) ('' if plugin is None else ' [%s -> %s]' % (plugin['type'], plugin['caption']))
testInfo = { # release test info testInfo = { # release test info
'title': testTitle, 'caption': testTitle,
'client': loadClient(configName + '_client.json', {**proxyInfo, **pluginClient}, socksInfo), 'client': loadClient(configName + '_client.json', {**proxyInfo, **pluginClient}, socksInfo),
'server': loadServer(configName + '_server.json', {**proxyInfo, **pluginServer}), 'server': loadServer(configName + '_server.json', {**proxyInfo, **pluginServer}),
'socks': socksInfo, # exposed socks5 address 'socks': socksInfo, # exposed socks5 address

5
Tester/V2ray.py

@ -3,10 +3,9 @@
import copy import copy
import itertools import itertools
from Tester import Settings
from Basis.Functions import genFlag from Basis.Functions import genFlag
from Basis.Methods import quicMethods from Tester.Settings import Settings
from Basis.Methods import udpObfuscations from Basis.Methods import quicMethods, udpObfuscations
httpConfig = { httpConfig = {
'version': '1.1', 'version': '1.1',

8
Tester/VLESS.py

@ -5,13 +5,11 @@ import os
import json import json
from Tester import Xray from Tester import Xray
from Builder import VLESS from Builder import VLESS
from Tester import Settings
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Process import Process from Basis.Process import Process
from Basis.Functions import md5Sum
from Basis.Methods import xtlsFlows from Basis.Methods import xtlsFlows
from Basis.Functions import genUUID from Tester.Settings import Settings
from Basis.Functions import getAvailablePort from Basis.Functions import md5Sum, genUUID, getAvailablePort
def loadServer(configFile: str, proxyInfo: dict, streamConfig: dict, xtlsFlow: str or None) -> Process: def loadServer(configFile: str, proxyInfo: dict, streamConfig: dict, xtlsFlow: str or None) -> Process:
@ -63,7 +61,7 @@ def loadTest(stream: dict) -> dict:
xtlsFlow = xtlsFlow.replace('splice', 'direct') # XTLS on server should use xtls-rprx-direct flow xtlsFlow = xtlsFlow.replace('splice', 'direct') # XTLS on server should use xtls-rprx-direct flow
configName = 'vless_%s' % (md5Sum(stream['caption'])[:8]) configName = 'vless_%s' % (md5Sum(stream['caption'])[:8])
testInfo = { # release test info testInfo = { # release test info
'title': 'VLESS test: %s' % stream['caption'], 'caption': 'VLESS test: %s' % stream['caption'],
'client': loadClient(configName + '_client.json', proxyInfo, socksInfo), 'client': loadClient(configName + '_client.json', proxyInfo, socksInfo),
'server': loadServer(configName + '_server.json', proxyInfo, stream['server'], xtlsFlow), 'server': loadServer(configName + '_server.json', proxyInfo, stream['server'], xtlsFlow),
'socks': socksInfo, # exposed socks5 address 'socks': socksInfo, # exposed socks5 address

8
Tester/VMess.py

@ -6,14 +6,12 @@ import json
import itertools import itertools
from Tester import V2ray from Tester import V2ray
from Builder import VMess from Builder import VMess
from Tester import Settings
from Builder import pathEnv from Builder import pathEnv
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Process import Process from Basis.Process import Process
from Basis.Functions import md5Sum from Tester.Settings import Settings
from Basis.Functions import genUUID
from Basis.Methods import vmessMethods from Basis.Methods import vmessMethods
from Basis.Functions import getAvailablePort from Basis.Functions import md5Sum, genUUID, getAvailablePort
def loadServer(configFile: str, proxyInfo: dict, streamConfig: dict) -> Process: # load server process def loadServer(configFile: str, proxyInfo: dict, streamConfig: dict) -> Process: # load server process
@ -63,7 +61,7 @@ def loadTest(method: str, aid: int, stream: dict) -> dict:
} }
configName = 'vmess_%s_%i_%s' % (method, aid, md5Sum(stream['caption'])[:8]) configName = 'vmess_%s_%i_%s' % (method, aid, md5Sum(stream['caption'])[:8])
testInfo = { # release test info testInfo = { # release test info
'title': 'VMess test: %s [security = %s | alterId = %i]' % (stream['caption'], method, aid), 'caption': 'VMess test: %s [security = %s | alterId = %i]' % (stream['caption'], method, aid),
'client': loadClient(configName + '_client.json', proxyInfo, socksInfo), 'client': loadClient(configName + '_client.json', proxyInfo, socksInfo),
'server': loadServer(configName + '_server.json', proxyInfo, stream['server']), 'server': loadServer(configName + '_server.json', proxyInfo, stream['server']),
'socks': socksInfo, # exposed socks5 address 'socks': socksInfo, # exposed socks5 address

6
Tester/Xray.py

@ -4,11 +4,9 @@
import copy import copy
import itertools import itertools
from Tester import V2ray from Tester import V2ray
from Tester import Settings
from Basis.Methods import xtlsFlows
from Basis.Functions import genFlag from Basis.Functions import genFlag
from Basis.Methods import quicMethods from Tester.Settings import Settings
from Basis.Methods import udpObfuscations from Basis.Methods import xtlsFlows, quicMethods, udpObfuscations
loadConfig = V2ray.loadConfig loadConfig = V2ray.loadConfig
tcpStream = V2ray.tcpStream tcpStream = V2ray.tcpStream

113
Tester/__init__.py

@ -1,12 +1,109 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
Settings = { import time
'workDir': '/tmp/ProxyC', import requests
'serverBind': '127.0.0.1', from threading import Thread
'clientBind': '127.0.0.1', from Basis.Logger import logging
'site': 'www.bing.com', from Basis.Functions import md5Sum, hostFormat, checkPortStatus
'host': '343.re',
'cert': '/etc/ssl/certs/343.re/fullchain.pem', from Tester import Brook
'key': '/etc/ssl/certs/343.re/privkey.pem', from Tester import VMess
from Tester import VLESS
from Tester import Trojan
from Tester import TrojanGo
from Tester import Hysteria
from Tester import Shadowsocks
from Tester import ShadowsocksR
testEntry = {
'ss': Shadowsocks.load(),
'ss-all': Shadowsocks.load(isExtra = True),
'ssr': ShadowsocksR.load(),
'vmess': VMess.load(),
'vless': VLESS.load(),
'trojan': Trojan.load(),
'trojan-go': TrojanGo.load(),
'brook': Brook.load(),
'hysteria': Hysteria.load(),
} }
def waitPort(port: int, times: int = 100, delay: int = 100) -> bool: # wait until port occupied
for i in range(times):
if not checkPortStatus(port): # port occupied
return True
time.sleep(delay / 1000) # default wait 100ms
return False # timeout
def httpCheck(socksInfo: dict, url: str, timeout: int = 10):
socksProxy = 'socks5://%s:%i' % (hostFormat(socksInfo['addr'], v6Bracket = True), socksInfo['port'])
try:
proxy = {
'http': socksProxy,
'https': socksProxy,
}
request = requests.get(url, timeout = timeout, proxies = proxy)
request.raise_for_status()
logging.info('%s -> ok' % socksProxy)
except Exception as exp:
logging.error('%s -> error' % socksProxy)
logging.error('requests exception\n' + str(exp))
raise RuntimeError('socks5 test failed')
def runTest(testInfo: dict, testUrl: str, testFilter: set or None, delay: int = 1) -> None:
testInfo['hash'] = md5Sum(testInfo['caption'])[:12]
if testFilter is not None and testInfo['hash'] not in testFilter: return
logging.warning('[%s] %s' % (testInfo['hash'], testInfo['caption']))
testInfo['server'].start() # start test server
if waitPort(testInfo['interface']['port']): # wait for server
logging.debug('server start complete')
testInfo['client'].start() # start test client
if waitPort(testInfo['socks']['port']): # wait for client
logging.debug('client start complete')
try:
logging.debug('start test process')
time.sleep(delay)
httpCheck(testInfo['socks'], testUrl)
except:
# client debug info
logging.warning('client info')
logging.error('command -> %s' % testInfo['client'].cmd)
logging.error('envVar -> %s' % testInfo['client'].env)
logging.error('file -> %s' % testInfo['client'].file)
logging.warning('client capture output')
logging.error('\n%s' % testInfo['client'].output)
# server debug info
logging.warning('server info')
logging.error('command -> %s' % testInfo['server'].cmd)
logging.error('envVar -> %s' % testInfo['server'].env)
logging.error('file -> %s' % testInfo['server'].file)
logging.warning('server capture output')
logging.error('\n%s' % testInfo['server'].output)
finally:
testInfo['client'].quit()
testInfo['server'].quit()
def test(testIter: iter, threadNum: int, testUrl: str, testFilter: set or None = None):
threads = []
while True: # infinite loop
try:
for thread in threads:
if thread.is_alive(): continue
threads.remove(thread) # remove dead thread
if len(threads) < threadNum:
for i in range(threadNum - len(threads)): # start threads within limit
thread = Thread( # create new thread
target = runTest,
args = (next(testIter), testUrl, testFilter)
)
thread.start()
threads.append(thread) # record thread info
time.sleep(0.1)
except StopIteration: # traverse completed
break
for thread in threads: # wait until all threads exit
thread.join()

157
test.py

@ -1,118 +1,59 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import time import sys
import requests import Tester
from threading import Thread from Tester import testEntry
from Tester import Brook
from Tester import VMess
from Tester import VLESS
from Tester import Trojan
from Tester import TrojanGo
from Tester import Hysteria
from Tester import Shadowsocks
from Tester import ShadowsocksR
from Basis.Logger import logging from Basis.Logger import logging
from Basis.Functions import hostFormat
from Basis.Functions import checkPortStatus
threadNum = 16
testItem = None
testFilter = None
testUrl = 'http://baidu.com'
helpMsg = '''
./test.py [ITEM] [OPTIONS]
def waitForStart(port: int, times: int = 100, delay: int = 100) -> bool: [ITEM]: ss / ss-all / ssr / vmess / vless / trojan / trojan-go / brook / hysteria
for i in range(times):
if not checkPortStatus(port): # port occupied
return True
time.sleep(delay / 1000) # default wait 100ms
return False # timeout
[OPTIONS]:
--thread NUM thread number
--url URL http check url
--filter ID1[,ID2...] test the specified id
--all test extra shadowsocks items
--help show this message
'''
def test(testObj: dict) -> None:
logging.warning(testObj['title'])
testObj['server'].start()
time.sleep(0.2)
testObj['client'].start()
if waitForStart(testObj['interface']['port']):
logging.debug('server start complete')
if waitForStart(testObj['socks']['port']):
logging.debug('client start complete')
logging.debug('start test process')
time.sleep(1) def getArg(field: str) -> str or None:
errFlag = False
socks5 = '%s:%i' % (
hostFormat(testObj['socks']['addr'], v6Bracket = True),
testObj['socks']['port']
)
try: try:
request = requests.get( index = sys.argv.index(field)
'http://iserv.scutbot.cn', return sys.argv[index + 1]
proxies = { except:
'http': 'socks5://' + socks5, return None
'https': 'socks5://' + socks5,
}, if '--help' in sys.argv:
timeout = 10 print(helpMsg)
) sys.exit(0)
request.raise_for_status() if len(sys.argv) > 1 and not sys.argv[1].startswith('--'):
logging.info('socks5 %s -> ok' % socks5) testItem = sys.argv[1]
except Exception as exp: if getArg('--url') is not None:
logging.error('socks5 %s -> error' % socks5) testUrl = getArg('--url')
logging.error('requests exception\n' + str(exp)) if getArg('--thread') is not None:
errFlag = True threadNum = int(getArg('--thread'))
if getArg('--filter') is not None:
testObj['client'].quit() testFilter = set(getArg('--filter').split(','))
testObj['server'].quit()
if errFlag: logging.critical('test item: ' + ('all' if testItem is None else testItem))
logging.warning('client info') logging.critical('filter: %s' % testFilter)
logging.error('command -> %s' % testObj['client'].cmd) logging.critical('url: ' + testUrl)
logging.error('envVar -> %s' % testObj['client'].env) logging.critical('thread number: %i' % threadNum)
logging.error('file -> %s' % testObj['client'].file) logging.critical('TEST START')
logging.warning('client capture output') if testItem is not None:
logging.error('\n' + str(testObj['client'].output)) Tester.test(testEntry[testItem], threadNum, testUrl, testFilter)
logging.warning('server info') else:
logging.error('command -> %s' % testObj['server'].cmd) for item in testEntry:
logging.error('envVar -> %s' % testObj['server'].env) if item == ('ss' if '--all' in sys.argv else 'ss-all'): # skip ss / ss-all
logging.error('file -> %s' % testObj['server'].file) continue
logging.warning('server capture output') logging.critical('TEST ITEM -> ' + item)
logging.error('\n' + str(testObj['server'].output)) Tester.test(testEntry[item], threadNum, testUrl, testFilter)
logging.critical('TEST COMPLETE')
def runTest(testIter: iter, threadNum: int):
threads = []
while True: # infinite loop
try:
for thread in threads:
if thread.is_alive(): continue
threads.remove(thread) # remove dead thread
if len(threads) < threadNum:
for i in range(threadNum - len(threads)): # start threads within limit
thread = Thread(target=test, args=(next(testIter),)) # create new thread
thread.start()
threads.append(thread) # record thread info
time.sleep(0.1)
except StopIteration: # traverse completed
break
for thread in threads: # wait until all threads exit
thread.join()
ss = Shadowsocks.load(isExtra = True)
# ss = Shadowsocks.load(isExtra = False)
ssr = ShadowsocksR.load()
vmess = VMess.load()
vless = VLESS.load()
trojan = Trojan.load()
trojanGo = TrojanGo.load()
brook = Brook.load()
hysteria = Hysteria.load()
logging.critical('test start')
runTest(ss, 64)
runTest(ssr, 64)
runTest(vmess, 64)
runTest(vless, 64)
runTest(trojan, 64)
runTest(trojanGo, 64)
runTest(brook, 64)
runTest(hysteria, 64)
logging.critical('test complete')

Loading…
Cancel
Save