I guess this worked itself out?
Hi @krishnakeshan I got the same issue. Do you mind to share the solution? Thanks
Hi @krishnakeshan I got the same issue. Do you mind to share the solution? Thanks
Could you share some specifics like your test plan and maybe what the dict contains?
Hi @feizalasmoro, @cyberw, I had the same problem last week. Since this issue does not have any details in it, I was going to open a new one, but maybe its better to reopen this one instead.
Here are the details of what happened to me and how I solved the problem in my test:
After using transformer to generate a script and running a successful test with the default settings, I wanted to see the difference in performance when using FastHttpLocust. Unfortunately, a post request in my test was not working (for two different reasons, I'll detail them below), with this traceback:
[2020-04-17 18:54:04,093] localhost/ERROR/stderr: File "/home/iadmin/stresstests/locust/test2.py", line 19, in on_start
self.client.post(path='/my-app/j_spring_security_check', name='/my-app/j_spring_security_check', timeout=30, allow_redirects=False, headers={'User-Agent': 'Locust-Request', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', 'Accept-Language': 'en-US,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': '73', 'Origin': '', 'DNT': '1', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1'}, data={"j_username":username, "j_password":password, "desired_dashboard":"", "login_mode_embed":"false"} )
[2020-04-17 18:54:04,093] localhost/ERROR/stderr:
[2020-04-17 18:54:04,093] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/locust/contrib/fasthttp.py", line 228, in post
return self.request("POST", path, data=data, **kwargs)
[2020-04-17 18:54:04,093] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/locust/contrib/fasthttp.py", line 170, in request
response = self._send_request_safe_mode(method, url, payload=data, headers=headers, **kwargs)
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/locust/contrib/fasthttp.py", line 116, in _send_request_safe_mode
return self.client.urlopen(url, method=method, **kwargs)
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/geventhttpclient/useragent.py", line 352, in urlopen
last_error = self._handle_error(e, url=req.url)
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/geventhttpclient/useragent.py", line 319, in _handle_error
raise reraise(type(e), e, sys.exc_info()[2])
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/six.py", line 693, in reraise
raise value
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/geventhttpclient/useragent.py", line 347, in urlopen
resp = self._urlopen(req)
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/locust/contrib/fasthttp.py", line 305, in _urlopen
body=request.payload, headers=request.headers)
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/geventhttpclient/client.py", line 236, in request
sock.sendfile(body)
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/gevent/_socket3.py", line 671, in sendfile
return self._sendfile_use_send(file, offset, count)
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,094] localhost/ERROR/stderr: File "/home/iadmin/anaconda3/lib/python3.7/site-packages/gevent/_socket3.py", line 609, in _sendfile_use_send
file_read = file.read
[2020-04-17 18:54:04,094] localhost/ERROR/stderr:
[2020-04-17 18:54:04,095] localhost/ERROR/stderr: AttributeError: 'dict' object has no attribute 'read'
[2020-04-17 18:54:04,095] localhost/ERROR/stderr:
[2020-04-17 18:54:04,095] localhost/ERROR/stderr: 2020-04-17T21:54:04Z
[2020-04-17 18:54:04,095] localhost/ERROR/stderr:
[2020-04-17 18:54:04,095] localhost/ERROR/stderr: <Greenlet at 0x7f1555b744d0: start_locust(<test2.WebsiteUser object at 0x7f1555b0d390>)> failed with AttributeError
What was really strange to me is that this issue only happened when I defined the header 'Content-Type': 'application/x-www-form-urlencoded'. Looking through the client code, I think this is the cause:
if payload:
# Adjust headers depending on payload content
content_type = req_headers.get('content-type', None)
if not content_type and isinstance(payload, dict):
req_headers['content-type'] = "application/x-www-form-urlencoded; charset=utf-8"
payload = urlencode(payload)
As we can see, if you do not define the content-type but pass a dict as payload (parameter data), the client urlencodes it. However, if you do set it beforehand, we get the AttributeError exception.
After encoding the body, however, I ran into the second cause of this issue (this affects GET requests as well): leaving the parameters timeout and allow_redirects from my original test in the requests. Looking through the code again, if you leave unrecognized named parameters in the request they are added as the request body:
def urlopen(self, url, method='GET', response_codes=valid_response_codes,
headers=None, payload=None, to_string=False, debug_stream=None, **kwargs):
""" Open an URL, do retries and redirects and verify the status code
"""
# POST or GET parameters can be passed in **kwargs
if kwargs:
if not payload:
payload = kwargs
elif isinstance(payload, dict):
payload.update(kwargs)
After removing both parameters, my test worked as expected.
I'm not sure what is the best solution here, but I'd like to suggest two possible options:
data parameterYes. That was exactly what happen in my case. Sorry I haven't got the time to add all details.
IMO we should wrap geventhttpclient so that it gets the same behaviour as requests. If someone creates a PR to fix this, I am +1.
At the same time we might change it so that it automatically converts a dict type data parameter to json (which requests does). I was thinking about doing that when I added the json parameter (9a090163fcb748d577f9aa780c320fdcceb91246), but decided against it because I was lazy and didnt want to break anything :)
I seem to experience the same problem. In order to solve some other problem I followed these instructions, but I got an error
Traceback (most recent call last):
File "src/gevent/greenlet.py", line 854, in gevent._gevent_cgreenlet.Greenlet.run
File "/Users/adietz/Work/10_NSE/1.19_SSCX_Portal/dev/salpeter/locustfile.py", line 51, in <lambda>
group.spawn(lambda: self.client.get(url, headers=headers, verify=False))
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/locust/contrib/fasthttp.py", line 245, in get
return self.request("GET", path, **kwargs)
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/locust/contrib/fasthttp.py", line 189, in request
response = self._send_request_safe_mode(method, url, payload=data, headers=headers, **kwargs)
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/locust/contrib/fasthttp.py", line 109, in _send_request_safe_mode
return self.client.urlopen(url, method=method, **kwargs)
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/geventhttpclient/useragent.py", line 359, in urlopen
last_error = self._handle_error(e, url=req.url)
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/geventhttpclient/useragent.py", line 326, in _handle_error
raise reraise(type(e), e, sys.exc_info()[2])
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/six.py", line 703, in reraise
raise value
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/geventhttpclient/useragent.py", line 354, in urlopen
resp = self._urlopen(req)
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/locust/contrib/fasthttp.py", line 402, in _urlopen
resp = client.request(
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/geventhttpclient/client.py", line 236, in request
sock.sendfile(body)
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/gevent/_socket3.py", line 684, in sendfile
return self._sendfile_use_send(file, offset, count)
File "/Users/adietz/Envs/mac_1.19_salpeter/lib/python3.8/site-packages/gevent/_socket3.py", line 622, in _sendfile_use_send
file_read = file.read
AttributeError: 'dict' object has no attribute 'read'
2020-12-04T06:55:32Z <Greenlet at 0x107ce76a0: <lambda>> failed with AttributeError
Most helpful comment
Hi @feizalasmoro, @cyberw, I had the same problem last week. Since this issue does not have any details in it, I was going to open a new one, but maybe its better to reopen this one instead.
Here are the details of what happened to me and how I solved the problem in my test:
After using transformer to generate a script and running a successful test with the default settings, I wanted to see the difference in performance when using FastHttpLocust. Unfortunately, a post request in my test was not working (for two different reasons, I'll detail them below), with this traceback:
What was really strange to me is that this issue only happened when I defined the header
'Content-Type': 'application/x-www-form-urlencoded'. Looking through the client code, I think this is the cause:As we can see, if you do not define the content-type but pass a dict as payload (parameter data), the client urlencodes it. However, if you do set it beforehand, we get the AttributeError exception.
After encoding the body, however, I ran into the second cause of this issue (this affects GET requests as well): leaving the parameters
timeoutandallow_redirectsfrom my original test in the requests. Looking through the code again, if you leave unrecognized named parameters in the request they are added as the request body:After removing both parameters, my test worked as expected.
I'm not sure what is the best solution here, but I'd like to suggest two possible options:
dataparameterEnvironment