221 lines
7.6 KiB
Python
221 lines
7.6 KiB
Python
import time
|
|
import subprocess, os, sys
|
|
import json, requests
|
|
from web import http
|
|
|
|
|
|
class Worker:
|
|
def __init__(self, domain: str, create_admin: bool):
|
|
'''
|
|
@opt:base = base url string
|
|
@opt:create_admin = creates admin account directly off cargo -c <NAME>
|
|
@opt:admin = optionally pass in dictionary with some admin credentials
|
|
potentially from another instance to run multiple tests at once
|
|
'''
|
|
|
|
self.domain = domain
|
|
self.requests = {}
|
|
self.responses = {}
|
|
self.body_logs = {}
|
|
|
|
self.jwt = None # never gets assigned until /login is hit
|
|
self.basic_creds = self.__create_admin()
|
|
self.id = self.basic_creds['id']
|
|
self.secret = self.basic_creds['secret']
|
|
|
|
def __create_admin(self):
|
|
# /home/$user/.cargo/bin/cargo <- normally
|
|
# NOTE: the above path is prolly some awful shit on ci pipeline
|
|
CARGO_BIN = os.getenv('CARGO_BIN')
|
|
|
|
proc = subprocess.run(f'cargo run --release -- -c dev-test'.split(), text=True, capture_output=True)
|
|
try:
|
|
return json.loads(proc.stdout)
|
|
except:
|
|
import sys
|
|
print('TESTBOT UNABLE TO LOAD JSON DATA FROM -c flag', file=sys.stderr)
|
|
exit(1)
|
|
|
|
def auth(self, auth_opt: str):
|
|
if auth_opt == 'basic':
|
|
return self.basic_creds
|
|
else:
|
|
return {'id': self.id, 'jwt': auth_opt}
|
|
|
|
|
|
def _append_auth(self, opts: dict, auth: str):
|
|
'''
|
|
Default auth fallback type is jwt because that's they only other type of auth
|
|
FC cares about really
|
|
|
|
@param opts: Dictionary of parameters to pass to the endpoint
|
|
@auth: Denotes if we use basic auth or jwt if its not 'basic'
|
|
|
|
'''
|
|
if type(auth) == str:
|
|
opts['id'] = self.id
|
|
if auth == 'basic':
|
|
opts['secret'] = self.secret
|
|
else:
|
|
opts['jwt'] = auth
|
|
return opts
|
|
else:
|
|
# if its not a string we don't add anything in
|
|
return opts
|
|
|
|
def logs(self):
|
|
ids = sorted(self.requests.keys()) # shared keys in requests/responses
|
|
for key in ids:
|
|
self.responses[key].log()
|
|
|
|
# Logg the provided data to ensure that _it_ wasn't the cause for error
|
|
resp = self.responses[key]
|
|
if resp.code != resp.expected:
|
|
opts = self.requests[key].params
|
|
print(f'\tParams: {opts}')
|
|
if self.body_logs[key] is True:
|
|
print(f'\tBody: {self.responses[key].body}')
|
|
|
|
|
|
def request(self, method: str, path: str, auth: str, opts: dict, expectation: int, show_body=False):
|
|
assert(path[0] == '/')
|
|
|
|
# First make sure we add in the correct auth params that are requested
|
|
opts = self._append_auth(opts, auth)
|
|
|
|
# Build the request and store it in our structure
|
|
url = self.domain + path
|
|
req = http.Request(method, url, opts)
|
|
r_id = time.time()
|
|
|
|
resp = req.make(expectation)
|
|
|
|
# update log trackers
|
|
self.requests[r_id] = req
|
|
self.responses[r_id] = resp
|
|
self.body_logs[r_id] = show_body
|
|
|
|
return r_id
|
|
|
|
|
|
def run(worker: Worker):
|
|
VOICE_CHAN = 1
|
|
TEXT_CHAN = 2
|
|
# Basically every test requires a jwt to be passed in so we grab that here
|
|
# Should this fail so should nearly every other test from this point
|
|
req_login = worker.request('post', '/login', 'basic',{}, 200)
|
|
jwt = worker.responses[req_login].json()['jwt']
|
|
|
|
new_channel_name = time.time()
|
|
|
|
channel_tests = [
|
|
# sanity check
|
|
{'init': ['get', '/channels/list', {}], 'auth': None, 'hope': 401},
|
|
|
|
{'init': ['post', '/channels/list', {}], 'auth': jwt, 'hope': 404},
|
|
|
|
{'init': ['post', '/channels/create', {'name': str(new_channel_name), 'kind': TEXT_CHAN, 'description': 'asdf'}], 'auth': jwt, 'hope': 200},
|
|
# Just a regular test no saving for this one
|
|
{'init': ['post', '/channels/create', {'name': str(new_channel_name+1), 'kind': TEXT_CHAN,}], 'auth': jwt, 'hope': 200},
|
|
|
|
{'init': ['post', '/channels/create', {}], 'auth': jwt, 'hope': 400},
|
|
{'init': ['post', '/channels/create', {'name': 123, 'kind': 'adsf'}], 'auth': jwt, 'hope': 400},
|
|
|
|
# save this and compare its results to the previous
|
|
{'init': ['get', '/channels/list', {}], 'auth': jwt, 'hope': 200},
|
|
{'init': ['get', '/channels/list', {'random-param': 123}], 'auth': jwt, 'hope': 200},
|
|
]
|
|
|
|
for test in channel_tests:
|
|
method, path, opts = test['init']
|
|
auth = test['auth']
|
|
hope = test['hope']
|
|
|
|
worker.request(method, path, auth, opts, hope)
|
|
|
|
msg_chan_name = time.time()
|
|
_id = worker.request('post', '/channels/create', jwt, {
|
|
'name': str(msg_chan_name),
|
|
'kind': TEXT_CHAN,
|
|
}, 200)
|
|
chan_d = worker.responses[_id].json()
|
|
|
|
message_tests = [
|
|
# bs message spam
|
|
{'init': ['post', '/message/send', {'channel': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
|
|
{'init': ['post', '/message/send', {'channel': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
|
|
{'init': ['post', '/message/send', {'channel': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
|
|
{'init': ['post', '/message/send', {'channel': chan_d['id'], 'content': 'bs content'}], 'auth': jwt, 'hope': 200},
|
|
|
|
# can we get them back tho?
|
|
{
|
|
'init': [
|
|
'get', '/message/get_range', {'channel': chan_d['id'], 'start-time': int(msg_chan_name-10), 'end-time': int(msg_chan_name + 10)}
|
|
],
|
|
'auth': jwt, 'hope': 200
|
|
},
|
|
{
|
|
'init': [
|
|
'get', '/message/get_range', {'channel': chan_d['id'], 'end-time': int(msg_chan_name)}
|
|
],
|
|
'auth': jwt, 'hope': 400
|
|
},
|
|
{
|
|
'init': [
|
|
'get', '/message/get_range', {'channel': chan_d['id'], 'start-time': int(msg_chan_name), 'end-time': int(msg_chan_name)}
|
|
],
|
|
'auth': jwt, 'hope': 400
|
|
},
|
|
{
|
|
'init': [
|
|
'get', '/message/get_range', {'channel': chan_d['id'], 'end-time': int(msg_chan_name), 'start-time': int(msg_chan_name)}
|
|
],
|
|
'auth': jwt, 'hope': 400
|
|
},
|
|
# two tests that follow the rules
|
|
{
|
|
'init': [
|
|
'get', '/message/from_id', {'start': 1, 'channel': 3}
|
|
],
|
|
'auth': jwt, 'hope': 200, 'body': True
|
|
},
|
|
{
|
|
'init': [
|
|
'get', '/message/from_id', {'start':1, 'channel':3, 'limit':2}
|
|
],
|
|
'auth': jwt, 'hope': 200, 'body': True
|
|
},
|
|
# tests that don't follow the api's rules
|
|
{
|
|
# channel doesn't exist so a 404 seems to be inorder
|
|
'init': [
|
|
'get', '/message/from_id', {'start': 1, 'channel':9}
|
|
],
|
|
'auth': jwt, 'hope': 404
|
|
},
|
|
{
|
|
'init': [
|
|
# good channel but id is tooo high
|
|
'get', '/message/from_id', {'start': 5, 'channel':3}
|
|
],
|
|
'auth': jwt, 'hope': 404
|
|
},
|
|
]
|
|
|
|
for test in message_tests:
|
|
method, path, opts = test['init']
|
|
auth = test['auth']
|
|
hope = test['hope']
|
|
if 'body' in test:
|
|
worker.request(method, path, auth, opts, hope, show_body=test['body'])
|
|
else:
|
|
worker.request(method, path, auth, opts, hope)
|
|
|
|
|
|
|
|
worker.logs()
|
|
|
|
if __name__ == '__main__':
|
|
worker = Worker('http://localhost:8888', create_admin=True)
|
|
run(worker)
|