11import time
2+ from statistics import mean
23from typing import Optional , Union , Tuple
34
45from matplotlib import pyplot as plt
@@ -11,25 +12,49 @@ class BaseMonitor(AbstractMonitor):
1112 def __init__ (self , stress : AbstractStressTest ):
1213 self ._stress = stress
1314
14- def start (self , timeout : Union [int , float ] = 0.2 ):
15+ def start (self , timeout : Union [int , float ] = 0.2 ) -> None :
16+ """
17+ Запускает тест.
18+ :param timeout: Union[int, float] (время задержки, используется при создании потоков и отправки запросов)
19+ :return: None
20+ """
1521 self ._stress .auto_create_connection ()
1622 for _ in self ._stress .auto_get_stats (timeout ):
17- print (f'Запросов всего : { len (self ._stress .stats )} ' )
23+ print (f'Всего запросов : { len (self ._stress .stats )} ' )
1824
1925 def set_params (self , kill : Optional [bool ] = None , timeout : Optional [Union [float , int ]] = None ,
20- max_thread_count : Optional [int ] = None , max_execution_time : Optional [int ] = None ):
26+ max_thread_count : Optional [int ] = None , max_execution_time : Optional [int ] = None ) -> None :
27+ """
28+ Устанавливает параметры стресс-теста.
29+ :param kill: bool (True - убить потоки, False - продолжить тестирование)
30+ :param timeout: Union[int, float] (время задержки, используется при создании потоков и отправки запросов)
31+ :param max_thread_count: int (максимальное кол-во потоков,
32+ реальное кол-во может незначительно отличаться от заданного)
33+ :param max_execution_time: int (максимальное время выполнения теста)
34+ :return: None
35+ """
2136 self ._stress .kill = kill or self ._stress .kill
2237 self ._stress .timeout = timeout or self ._stress .timeout
2338 self ._stress .max_thread_count = max_thread_count or self ._stress .max_thread_count
2439 self ._stress .max_execution_time = max_execution_time or self ._stress .max_execution_time
2540
26- def stop (self ):
41+ def stop (self ) -> None :
42+ """
43+ Останавливает работу теста и запускает построение статистики.
44+ :return: None
45+ """
2746 self ._stress .kill_all_connections ()
2847 self .build_graph ()
2948
3049
3150class ChartMonitor (BaseMonitor ):
32- def build_graph (self ):
51+ def build_graph (self ) -> None :
52+ """
53+ Построить статистику в виде графика. Используется matplotlib.
54+ Первый график - зависимость времени выполнения запроса от кол-ва запросов.
55+ Второй график - зависимость кол-ва ошибок от кол-ва запросов.
56+ :return: None
57+ """
3358 stats = sorted (self ._stress .stats .items (), key = lambda i : i [0 ])
3459 x_time_request = list (map (lambda i : round (time .time () - i [0 ], 4 ), stats ))
3560 y_time_request = list (map (lambda i : round (i [1 ], 4 ), stats ))
@@ -42,6 +67,14 @@ def build_graph(self):
4267 plt .show ()
4368
4469 def _get_x_y_error_coord (self ) -> Tuple [list , list ]:
70+ """
71+ Получение кортежа с координатами ошибок x, y.
72+ tuple[0] - list (координата x)
73+ tuple[1] - list (координата y)
74+ В качестве координат x, идёт время, когда проищошла ошибка.
75+ В качестве координат y, идёт кол-во ошибок, которое проищошло за время указанное в x (по умолчанию за 1 секунду)
76+ :return: Tuple[list, list]
77+ """
4578 res = [[]]
4679 x_error = y_error = []
4780 if len (self ._stress .errors ) > 0 :
@@ -57,12 +90,22 @@ def _get_x_y_error_coord(self) -> Tuple[list, list]:
5790 res .append ([i ])
5891 back = i [0 ]
5992 # Получаем время когда проихошла ошибка
60- x_error = list (map (lambda i : round (time .time () - i , 4 ), [i [0 ][0 ] for i in res ]))
93+ x_error = list (map (lambda el : round (time .time () - el , 4 ), [i [0 ][0 ] for i in res ]))
6194 # Получаем кол-во ошибок
6295 y_error = [len (i ) for i in res ]
6396 return x_error , y_error
6497
65- def _draw_plot (self , x : list , y : list , coord : Optional [list ] = None , title : Optional [str ] = None , color : str = 'b' ):
98+ def _draw_plot (self , x : list , y : list , coord : Optional [list ] = None , title : Optional [str ] = None ,
99+ color : str = 'b' ) -> None :
100+ """
101+ Строит график по указанным координатам x, y.
102+ :param x: list (координаты x (работает при условии len(x) == len(y)))
103+ :param y: list (координаты y (работает при условии len(x) == len(y)))
104+ :param coord: Optional[list] (координаты разбивания графика (matplotlib.subplot))
105+ :param title: Optional[str] (название графика (matplotlib.title))
106+ :param color: str (цвет графика)
107+ :return: None
108+ """
66109 if coord :
67110 plt .subplot (* coord )
68111 plt .plot (x , y , c = color )
@@ -72,7 +115,12 @@ def _draw_plot(self, x: list, y: list, coord: Optional[list] = None, title: Opti
72115
73116
74117class CMDMonitor (BaseMonitor ):
75- def start (self , timeout : Union [int , float ] = 0.2 ):
118+ def start (self , timeout : Union [int , float ] = 0.2 ) -> None :
119+ """
120+ Запускает тест, отобрадение статистики происходит в терминале.
121+ :param timeout: Union[int, float] (время задержки, используется при создании потоков и отправки запросов)
122+ :return: None
123+ """
76124 self ._stress .auto_create_connection ()
77125 for i in self ._stress .auto_get_stats (0.2 ):
78126 if isinstance (i , int ):
@@ -82,12 +130,19 @@ def start(self, timeout: Union[int, float] = 0.2):
82130 print (f'Запросов всего: { len (self ._stress .stats )} ' )
83131 print (f'Ошибок: { len (self ._stress .errors )} ' , end = '\n \n \n ' )
84132
85- def build_graph (self ):
133+ def build_graph (self ) -> None :
134+ """
135+ Строит график в терминале.
136+ Параметры вывода:
137+ 1) Всего потоков
138+ 2) Всего запросов
139+ 3) Среднее время на запрос
140+ 4) Всего ошибок
141+ :return: None
142+ """
86143 stats = self ._stress .stats .items ()
87- total_runtime = 0
88- for i in stats :
89- total_runtime += i [1 ]
144+ average_time_per_request = mean ([i [1 ] for i in stats ])
90145 print (f'\n \n \n Всего потоков: { len (self ._stress .thread )} ' )
91146 print (f'Всего запросов: { len (stats )} ' )
92- print (f'Среднее время на запрос: { len ( stats ) / total_runtime } ' )
147+ print (f'Среднее время на запрос: { average_time_per_request } ' )
93148 print (f'Всего ошибок: { len (self ._stress .errors )} ' , end = '\n \n \n ' )
0 commit comments