2023-08-23 14:01:18 +00:00
import requests
2023-09-11 02:14:21 +00:00
import docker
2023-08-23 14:01:18 +00:00
import concurrent . futures
import time
2023-09-11 02:14:21 +00:00
import os
from math import floor
from init import init
2023-10-03 18:31:33 +00:00
from common import FRAMEWORKS , ENDPOINTS , API_REQUESTS , AVG_RUNS
2023-08-23 14:01:18 +00:00
2023-09-11 02:14:21 +00:00
init ( )
2023-08-23 14:01:18 +00:00
2023-09-11 02:14:21 +00:00
THREADS = 10
2023-10-03 18:31:33 +00:00
FRAMEWORK_NAME = " "
CONTAINER_NAME = " "
2023-09-11 02:14:21 +00:00
URL_BASE = ' http://localhost:9090 '
2023-11-04 20:05:55 +00:00
def send_request ( url , method = ' GET ' , data = None ) :
2023-09-11 02:14:21 +00:00
success = False
responses = {
2 : 0 , # OK
4 : 0 , # Bad Request
5 : 0 , # Server Error
}
while not success :
try :
response = None
if method == ' GET ' :
response = requests . get ( url )
elif method == ' POST ' :
2023-11-04 20:05:55 +00:00
payload = data [ 0 ]
content_type = data [ 1 ]
response = requests . post ( url , data = payload , headers = { ' Content-Type ' : content_type } )
2023-09-11 02:14:21 +00:00
except :
continue
success = response . status_code == 200
responses [ floor ( response . status_code / 100 ) ] + = 1
return responses
def getFileNames ( endpoint ) :
endpoint = endpoint . replace ( ' / ' , ' ' )
files = [
f " data/req_ { FRAMEWORK_NAME } _ { endpoint } .csv " ,
f " data/resource_ { FRAMEWORK_NAME } _ { endpoint } .csv " ,
]
return files
def record ( filename , requests , reqpersec ) :
with open ( filename , " a " ) as file :
file . write ( f " { requests } , { reqpersec } \n " )
def record_resource ( filename , requests , cpu , ram ) :
with open ( filename , " a " ) as file :
file . write ( f " { requests } , { cpu } , { ram } \n " )
def run_tests ( endpoint , method , num_requests , metadata ) :
files = getFileNames ( endpoint )
for filename in files :
if os . path . exists ( filename ) :
os . remove ( filename )
2023-08-23 14:01:18 +00:00
for num_request in num_requests :
2023-09-11 02:14:21 +00:00
if num_request < = 0 : continue
2023-10-03 18:31:33 +00:00
for run in range ( AVG_RUNS ) :
ok_responses = 0
bad_responses = 0
server_errors = 0
2023-08-23 14:01:18 +00:00
2023-10-29 22:01:24 +00:00
cpu , ram = 0 , 0
2023-10-03 18:31:33 +00:00
with concurrent . futures . ThreadPoolExecutor ( max_workers = THREADS ) as executor :
url = f ' { URL_BASE } { endpoint } '
2023-08-23 14:01:18 +00:00
2023-10-03 18:31:33 +00:00
start_time = time . time ( )
2023-09-11 02:14:21 +00:00
2023-10-03 18:31:33 +00:00
futures = [ ]
2023-09-11 02:14:21 +00:00
2023-10-03 18:31:33 +00:00
half = floor ( num_request / 2 )
for i in range ( num_request ) :
futures . append ( executor . submit ( send_request , url , method , metadata ) )
2023-08-23 14:01:18 +00:00
2023-10-03 18:31:33 +00:00
if i == half :
cpu , ram = get_resource_usage ( )
2023-08-23 14:01:18 +00:00
2023-10-03 18:31:33 +00:00
concurrent . futures . wait ( futures )
2023-08-23 14:01:18 +00:00
2023-10-03 18:31:33 +00:00
elapsed_time = time . time ( ) - start_time
2023-09-11 02:14:21 +00:00
2023-10-03 18:31:33 +00:00
for future in futures :
responses = future . result ( )
ok_responses + = responses [ 2 ]
bad_responses + = responses [ 4 ]
server_errors + = responses [ 5 ]
print ( f " [# { run } ] { num_request } : { elapsed_time : .2f } seconds. { elapsed_time / num_request : .4f } seconds per request. { num_request / elapsed_time : .2f } requests per second. [OK: { ok_responses } , Bad Request: { bad_responses } , Server Error: { server_errors } ]] " )
client = docker . from_env ( )
client . containers . get ( CONTAINER_NAME ) . restart ( )
2023-09-11 02:14:21 +00:00
2023-10-29 22:01:24 +00:00
record ( files [ 0 ] , num_request , f " { num_request / elapsed_time : .2f } " )
record_resource ( files [ 1 ] , num_request , cpu , ram )
2023-09-11 02:14:21 +00:00
2024-03-24 22:31:53 +00:00
time . sleep ( 30 )
2023-09-11 02:14:21 +00:00
def get_resource_usage ( ) :
if CONTAINER_NAME == " " : return 0 , 0
try :
client = docker . from_env ( )
stats = client . containers . get ( CONTAINER_NAME ) . stats ( stream = False )
except :
return 0 , 0 # unable to get stats
return get_cpu_usage ( stats ) , get_ram_usage ( stats )
def get_cpu_usage ( stats ) :
UsageDelta = stats [ ' cpu_stats ' ] [ ' cpu_usage ' ] [ ' total_usage ' ] - stats [ ' precpu_stats ' ] [ ' cpu_usage ' ] [ ' total_usage ' ]
SystemDelta = stats [ ' cpu_stats ' ] [ ' system_cpu_usage ' ] - stats [ ' precpu_stats ' ] [ ' system_cpu_usage ' ]
len_cpu = stats [ ' cpu_stats ' ] [ ' online_cpus ' ]
percentage = ( UsageDelta / SystemDelta ) * len_cpu
return f " { percentage : .2f } "
def get_ram_usage ( stats ) :
usage = stats [ ' memory_stats ' ] [ ' usage ' ]
limit = stats [ ' memory_stats ' ] [ ' limit ' ]
percentage = ( usage / limit )
# percent = round(percentage, 2)
return f " { percentage : .2f } "
2023-08-23 14:01:18 +00:00
2023-09-11 02:14:21 +00:00
if __name__ == " __main__ " :
if not os . path . exists ( " data " ) :
os . mkdir ( " data " )
2023-08-23 14:01:18 +00:00
2023-10-30 23:34:20 +00:00
init ( )
2023-10-03 18:31:33 +00:00
for i in range ( len ( FRAMEWORKS ) ) :
FRAMEWORK_NAME = FRAMEWORKS [ i ] [ 0 ]
CONTAINER_NAME = FRAMEWORKS [ i ] [ 1 ]
URL_BASE = ENDPOINTS [ FRAMEWORK_NAME ]
for endpoint , method , num_requests , metadata in API_REQUESTS :
print ( f " # { FRAMEWORK_NAME } - { endpoint } " )
run_tests ( endpoint , method , num_requests , metadata )