Package: curt
CuRTTable of contentsCuRTIntroductionRequirementsGet CuRTConfigurationUsing source codeMaintenanceIntroductionCustom RPS Testeris a tool to make specific requests per second to a webservice.RequirementsPython versionPython 3ModulesPandas 1.5.2Plotly 5.11.0Requests 2.28.1Get CuRTpipinstallcurtConfigurationGit repository CuRT.py file is just a main file example.ExampleThere are two file inejemplosdirectory.properties.pyfile has example variables for CuRT.py file (i.e.hostforhttps://jsonplaceholder.typicode.com/posts).post.jsonfile is a sample json file forhost.In this example, the main file isCuRT.py, and it can importproperties.pyfile:try:fromresourcesimportpropertiesaspexcept(ModuleNotFoundError,ImportError):print('Error: Propiedades no encontradas.')CuRT can be imported too:fromcurtimportdictionary_creatorfromcurtimportthreads_managerfromcurtimportreportsfromcurtimportsimple_restThe HTTP methods to be used must be defined, and the request can be made using the importedpost_requestfunctions forPOSTrequests, andget_requestforGETrequests.Since the responses for each request are generated independently, there must be a way to store them. In the example adf_listis created where each request made is added. Thedictionary_creatormodule contains a single function, which creates a dictionary taking the start time, end time, the json method used and the response obtained, so that, joining everything together, the function declaration part for the methods to be consumed would look something like this in theCuRT.py:df_list=[]defpost_ex():start=dt.datetime.now()# Método:json_method="/posts"# Ubicación de la petición:request_file='resources/post.json'withopen(request_file)asjson_file:payload=json.load(json_file)# POST requestresponse=simple_rest.post_request(p.HOST+json_method,payload,p.HEADERS)end=dt.datetime.now()df_list.append(dictionary_creator.new_dict(start,end,json_method,response))defget_ex():start=dt.datetime.now()# Método:json_method="/posts/1"# POST requestresponse=simple_rest.get_request(p.HOST+json_method,p.HEADERS)end=dt.datetime.now()df_list.append(dictionary_creator.new_dict(start,end,json_method,response))CuRT consumes the methods of the indicated web service and then generates a report with the results obtained. As all the tools to do this are included within CuRT itself, then they can be used to generate reports based on a previous.csvfile. So in the example there are two functions that generate a report:do_testandgenerate_html.Thereportsmodule contains only one function, calledloadtest, which is the one that contains the main functionality of the tool: making the reports. So regardless of what the data source is, it is this method that must be consumed to generate the report.The module that is in charge of loadtesting as such isthreads_manager. It contains a single function that needs three values: the duration of the test in seconds, the functions that perform consume the web service and the number of requests per second.Putting these together, the functions look like this:defhacer_pruebas(length,test_name,dark_mode,base_dir,functions,rps):print('## Custom RPS Tester ##')print('# Tester #')start_time=dt.datetime.now()threads_manager.start_threads(int(length),functions,int(rps))end_time=dt.datetime.now()df=pd.DataFrame(df_list)report_dir=test_name+'_'+str(dt.datetime.now().timestamp())dir_name=base_dir+'/'+report_dirifnotos.path.exists(dir_name):os.makedirs(dir_name)df.to_csv(dir_name+'/data.csv',index=False,encoding='utf-8-sig')df.sort_values(by='End',inplace=True)reports.loadtest(dark_mode=dark_mode,dir_name=dir_name,functions=functions,df=df,start_time=start_time,end_time=end_time,testing=True)defgenerar_html(dark_mode,dir_name,csv_location):print('## Custom RPS Tester ##')print('# Generador de reportes #')print('##########################################################################')ifdir_name=='NULL':dir_name=os.getcwd()print('Cargando archivo: '+csv_location)df=pd.read_csv(csv_location,encoding='utf-8')print('Hecho.')print('##########################################################################')function_names=df['MethodName'].drop_duplicates().tolist()functions=[]forfunctioninfunction_names:functions.append(globals()[function])datetime_format='%Y-%m-%d%H:%M:%S.%f'start_time=dt.datetime.strptime(df['Start'].min(),datetime_format)end_time=dt.datetime.strptime(df['End'].max(),datetime_format)df.sort_values(by='End',inplace=True)reports.loadtest(dark_mode=dark_mode,dir_name=dir_name,functions=functions,df=df,start_time=start_time,end_time=end_time,testing=False)Thetestingflag is used to indicate the name of the report. For a new report, the final file will beindex.html. For a report based on previous data, the final file will beindex-[timestamp].html.Finally, the main function will define which function will be called, so there are two possibilities:The loadtest is performed and then the report is generated:defmain():length=20rps=20test_name='Ejemplo'base_dir='Reports'functions=[post_ex,get_ex]dark_mode=Truehacer_pruebas(length=length,test_name=test_name,dark_mode=dark_mode,base_dir=base_dir,functions=functions,rps=rps)The report is made based on existing data:defmain():dir_name=p.DIRECTORY+'/CuRT/Reports/Ejemplo_1670629990.446974'csv_location=dir_name+'/data.csv'dark_mode=Truegenerar_html(dark_mode=dark_mode,dir_name=dir_name,csv_location=csv_location)Finally theCuRT.pyfile is executed and the report is generated:Using source codeInstallationPrerequisitesInstall Python 3.Add Python installation path topathenvironment variable.Get startedCreate a virtual environment (pipenv,virtualenv, etc.).Activate the virtual environment.Install required modules (requirements.txt):pipinstall-rrequirements.txtMaintenanceCurrent developers who maintain the code:Jahaziel Alvarez (jahaziel.alvarez@pm.me)