如何处理Python WebDriver中偶发的BadStatusLine,CannotSendRequest错误 [英] How to deal with sporadic BadStatusLine, CannotSendRequest errors in python WebDriver

查看:157
本文介绍了如何处理Python WebDriver中偶发的BadStatusLine,CannotSendRequest错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

自从我们开始在jenkins中运行硒UI测试以来,我们注意到在测试期间出现错误的频率很小但很烦人.我们在看似随机的硒操作(单击,退出,访问等)上收到BadStatusLine和CannotSendRequest错误.

Since we started running selenium UI tests in jenkins, we noticed a small but annoying frequency of errors during tests. We get BadStatusLine and CannotSendRequest errors on seemingly random selenium actions (click, quit, visit, etc.).

它们通常看起来像:

  File "/usr/lib/python2.7/unittest/case.py", line 327, in run
    testMethod()
  File "/home/jenkins/workspace/Create and Upload Functional Testing/shapeways/test_suite/Portal/CreateAndUpload/TestUploadWhenNotLoggedIn_ExpectLoginModal.py", line 22, in runTest
    self.dw.visit(ShapewaysUrlBuilder.build_model_upload_url())
  File "/home/jenkins/workspace/Create and Upload Functional Testing/webdriver/webdriverwrapper/WebDriverWrapper.py", line 212, in visit
    return self.execute_and_handle_webdriver_exceptions(lambda: _visit(url))
  File "/home/jenkins/workspace/Create and Upload Functional Testing/webdriver/webdriverwrapper/WebDriverWrapper.py", line 887, in execute_and_handle_webdriver_exceptions
    return function_to_execute()
  File "/home/jenkins/workspace/Create and Upload Functional Testing/webdriver/webdriverwrapper/WebDriverWrapper.py", line 212, in <lambda>
    return self.execute_and_handle_webdriver_exceptions(lambda: _visit(url))
  File "/home/jenkins/workspace/Create and Upload Functional Testing/webdriver/webdriverwrapper/WebDriverWrapper.py", line 205, in _visit
    return self.driver.get(url)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 185, in get
    self.execute(Command.GET, {'url': url})
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/webdriver.py", line 171, in execute
    response = self.command_executor.execute(driver_command, params)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/remote_connection.py", line 349, in execute
    return self._request(command_info[0], url, body=data)
  File "/usr/local/lib/python2.7/dist-packages/selenium/webdriver/remote/remote_connection.py", line 380, in _request
    resp = self._conn.getresponse()
  File "/usr/lib/python2.7/httplib.py", line 1030, in getresponse
    response.begin()
  File "/usr/lib/python2.7/httplib.py", line 407, in begin
    version, status, reason = self._read_status()
  File "/usr/lib/python2.7/httplib.py", line 371, in _read_status
    raise BadStatusLine(line)

此特殊情况来自以下堆栈:

This particular case came from the following stack:

  • selenium == 2.44.0
  • python == 2.7.3
  • firefox == 34.0
  • 詹金斯
  • xvfb(使用jenkins插件进行无头显示)

尽管我们一直看到这些错误始终在firefox/selenium的许多不同版本排列中突然出现.

though we've seen these errors popping up all the time across many different version permutations of firefox/selenium.

我运行了一个tcpdump来捕获在BadStatusLine错误出现之前发送的实际请求,并得到了以下信息.

I ran a tcpdump to capture the actual request sent right before the BadStatusLine error came up and got the following.

    POST /hub/session/ab64574a-4a17-447a-b2e8-5b0f5ed5e923/url HTTP/1.1 
    Host: 127.0.0.1:41246
    Accept-Encoding: identity Content-Length: 102
    Connection: keep-alive
    Content-type: application/json;charset="UTF-8"
    POST: /hub/session/ab64574a-4a17-447a-b2e8-5b0f5ed5e923/url
    Accept: application/json
    User-Agent: Python http auth

    {"url": "http://example.com/login", "sessionId": "ab64574a-4a17-447a-b2e8-5b0f5ed5e923"}

响应以0字节返回.因此BadStatusLine是由空响应引起的,这是有道理的.

Response comes back with 0 bytes. So the BadStatusLine was caused by an empty response, which makes sense.

问题是,为什么硒服务器会返回一个空响应.如果服务器死了,我们会不会出现ConnectionError或类似的错误消息?

The question is, why would selenium's server return an empty response. If the server died, wouldn't we get a ConnectionError or something along those lines?

推荐答案

有一段时间,我没有问题,也不知道是什么原因.我终于可以通过运行来进行复制:

For a while, I had no repro and no idea what the cause was. I was finally able to repro by running:

import requests
import json

while True:

  requests.post('http://127.0.0.1/hub/session/', data=json.dumps({"url": "http://example.com/login", "sessionId": "ab64574a-4a17-447a-b2e8-5b0f5ed5e923"}))

在运行时,我退出浏览器并收到BadStatusLine错误!当我再次尝试发出该请求时,这就是从任何死服务器中看到的预期"ConnectionError"的时间.

While this was running, I quit the browser and got a BadStatusLine error! When I tried making that request again, that's when I got the expected "ConnectionError" that you would see from any dead server.

因此,我怀疑发生的情况是,在向浏览器发送kill信号时,在关闭期间会出现一个短窗口,其中任何响应仍将返回,但带有0字节.这就是为什么您针对同一问题(浏览器死亡)获得不同类型的异常的原因.原来我们有一个cron,它在后台杀死了我们的浏览器.

SO, what I suspect happens is that when the browser is sent the kill signal, there is a short window during its shutdown where any response will still be returned but with 0 bytes. That's why you get different types of exceptions for essentially the same problem (browser dies). Turns out we had a cron which was killing our browsers in the background.

这篇关于如何处理Python WebDriver中偶发的BadStatusLine,CannotSendRequest错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆