蝗虫:request_success.火什么都做不了



我为Poly API函数做了一个包装器。包装器应该触发一些蝗虫事件。 API 函数"授权"被成功调用(如果提供了错误的参数来"授权",则会在控制台中引发异常(。看起来蝗虫事件函数不是。统计数据不会反映在 Locust 界面中,就像什么都没发生一样。

import time
from business_logic_refactored import BusinessLogic
from locust import User, task, between, events
class PolyClinet(BusinessLogic):
_locust_environment = None
def __getattr__(self, name):
#func = BusinessLogic.__getattr__(self, name)
func = BusinessLogic.authorize
def wrapper(*args, **kwargs):
start_time = time.time()
try:
result = func(*args, **kwargs)
events.request_success.fire(request_type="TEST", name=name, response_time=total_time, response_length=0)
self._locust_environment.events.request_success.fire(request_type="TEST", name=name, response_time=total_time, response_length=0)
except Fault as e:
total_time = int((time.time() - start_time) * 1000)
self._locust_environment.events.request_failure.fire(request_type="TEST", name=name, response_time=total_time, exception=e)
else:
total_time = int((time.time() - start_time) * 1000)
events.request_success.fire(request_type="grpc", name=name, response_time=total_time, response_length=0)
###self._locust_environment.events.request_success.fire(request_type="TEST", name=name, response_time=total_time, response_length=0)
# In this example, I've hardcoded response_length=0. If we would want the response length to be
# reported correctly in the statistics, we would probably need to hook in at a lower level
return wrapper
class PolyUser(User):
abstract = True
def __init__(self, *args, **kwargs):
super(PolyUser, self).__init__(*args, **kwargs)
self.client = PolyClient()
self.client._locust_environment = self.environment
class ApiUser(PolyUser):
@task(10)
def get_time(self):
self.client.authorize("user", "password","URL")

UPD 06/11/20:

基本上,问题是.getattr仅在不存在的函数上调用。以下是尝试查看差异/问题的脚本:

class BusinessLogic():
def __getattr__(self, name):
return name
def authorize(self):
print("authorize")
class PolyClinet(BusinessLogic):
_locust_environment = None
def __getattr__(self, name):
print("getattr")
func = BusinessLogic.__getattr__(self, name)
def wrapper(*args, **kwargs):
print("wrapper")
func()
return wrapper
class PolyUser():
abstract = True
def __init__(self, *args, **kwargs):
super(PolyUser, self).__init__(*args, **kwargs)
self.client = PolyClinet()
#self.client._locust_environment = self.environment
class ApiUser(PolyUser):
def get_time(self):
print("get_time")
self.client.authorize()
def get_time2(self):
print("get_time2")
self.client.authorize2()
c= ApiUser()
c.get_time()
print("*******")
c.get_time2()

要记录事件,您应该在 User 类中执行 self.environment.events.request_success.fire(...(

例如,请参阅 https://github.com/SvenskaSpel/locust-plugins/blob/2958d265857a8730af3b6cd9fd05f8839ec8f383/locust_plugins/users.py#L70。

我不确定当你直接打电话给events.request_success时会发生什么。也许它应该抛出一个异常。它可能也可以更好地记录...

编辑:根本问题是BusinessLogic有自己的常规(非getattr(方法,在这种情况下,子类化将使客户端无法包装BusinessLogic方法(因为客户端的getattr不会被调用(文档中的示例应该得到改进。 https://github.com/locustio/locust/issues/1423

就我而言,问题是蝗虫版本。在版本 1.4.4 中,events.request_success.fire工作(并命名为EventHook(,但在版本 1.5.1 中,它应该只是request对象,并且events.request_success.fire已经弃用了 EventHook 名称。 https://docs.locust.io/en/stable/api.html#locust.event.Events.request

最新更新