Opened 3 years ago

Last modified 3 years ago

#21227 new Bug

Selenium tests terminate with [Errno 10054]

Reported by: Kevin Christopher Henry Owned by: nobody
Component: Testing framework Version: master
Severity: Normal Keywords: selenium
Cc: Florian Apolloner Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When I run the test suite on Windows with the --selenium option, I consistently see errors like this:

Exception happened during processing of request from ('127.0.0.1', 51603)
Traceback (most recent call last):
  File "C:\Program Other\Python27\Lib\SocketServer.py", line 295, in _handle_request_noblock
    self.process_request(request, client_address)
  File "C:\Program Other\Python27\Lib\SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "C:\Program Other\Python27\Lib\SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "C:\Django\django\django\core\servers\basehttp.py", line 126, in __init__
    super(WSGIRequestHandler, self).__init__(*args, **kwargs)
  File "C:\Program Other\Python27\Lib\SocketServer.py", line 649, in __init__
    self.handle()
  File "C:\Program Other\Python27\Lib\wsgiref\simple_server.py", line 116, in handle
    self.raw_requestline = self.rfile.readline()
  File "C:\Program Other\Python27\Lib\socket.py", line 447, in readline
    data = self._sock.recv(self._rbufsize)
error: [Errno 10054] An existing connection was forcibly closed by the remote host

Based on some anecdotal data, I tried putting a refresh() before the quit() in contrib.admin.tests.AdminSeleniumWebDriverTestCase._tearDownClassInternal() and that reliably solved the problem.

I have no idea why this works, but if it does it's probably worth doing since it should be harmless.

Attachments (1)

selenium_10054_aa1abb5f1e47e23a5aa9b56824c1e9bcf34e260d.patch (716 bytes) - added by Thomas Khyn 3 years ago.

Download all attachments as: .zip

Change History (13)

comment:1 Changed 3 years ago by Tim Graham

Component: contrib.adminTesting framework
Triage Stage: UnreviewedAccepted

There are some other places where we call selenium.quit() -- should those places be updated as well?

docs/topics/testing/overview.txt: cls.selenium.quit()
tests/view_tests/tests/test_i18n.py: cls.selenium.quit()

comment:2 Changed 3 years ago by Kevin Christopher Henry

I think it's worth doing this wherever we're calling selenium.quit(), since it seems harmless and does solve the spurious failures. Here's a patch for it: https://github.com/django/django/pull/1806.

However, I hesitate to give this workaround canonical status by putting it in the documentation, since it's basically a bug in another project, could be fixed at any time, and adds a little extra noise and cognitive dissonance to the documentation. It only seems to pop up in some environments, and the workaround can be easily found with a quick internet search. On the other hand, for people developing reusable applications, it might be nice to warn them about this since it might affect them even if they aren't seeing the bug in their own test environments. Maybe the wiki is the right place for this?

comment:3 Changed 3 years ago by Tim Graham

Resolution: fixed
Status: newclosed

In 08c9ab5a0f564a3ac7803e6a97fae855f2e0524e:

Fixed #21227 -- Added workaround for selenium test failures

Added a refresh() before quit() in the selenium tests, since this
solves the problem of spurious test failures in some environments.

comment:4 Changed 3 years ago by Florian Apolloner

@marfire That workaround slows down firefox pretty much and should Be unneeded; can you test if this sequence works better for you:

        if hasattr(cls, 'selenium'):
            cls.selenium.close()
        super(AdminSeleniumWebDriverTestCase, cls)._tearDownClassInternal()
        if hasattr(cls, 'selenium'):
            cls.selenium.quit()

Last edited 3 years ago by Florian Apolloner (previous) (diff)

comment:5 Changed 3 years ago by Florian Apolloner

@marfire: Is this a hard failure or just output on the console? Cause essentially everything which is a subclass of Exception is captured and more or less ignored.

comment:6 Changed 3 years ago by Florian Apolloner

Cc: Florian Apolloner added

comment:7 Changed 3 years ago by Kevin Christopher Henry

I'm out of town right now, but I'll try this next week and report back...

comment:8 Changed 3 years ago by Florian Apolloner <florian@…>

In 7d0a5190328f277b97b1f55171e1fecb22a1e461:

Revert "Fixed #21227 -- Added workaround for selenium test failures"

This reverts commit 08c9ab5a0f564a3ac7803e6a97fae855f2e0524e.

comment:9 Changed 3 years ago by Florian Apolloner

Resolution: fixed
Status: closednew

I just reverted it since it doubles (or more) the time for firefox tests. The real fix should go something like this: When we tear down set a flag that we are in a shutdown process and then ignore the error.

comment:10 Changed 3 years ago by Thomas Khyn

Hi,

An attempt to mitigate this issue is in attached patch above.

The only way to make it work is to Attempt to set server_thread.httpd.ignore_errors = True before calling WebDriver.quit() in the Selenium test case class's tearDownClass, like that:

class MySeleniumTestCase(LiveServerTestCase)

    [...]

    @classmethod
    def tearDownClass(cls):
        if hasattr(cls, 'server_thread'):
            # test if server_thread attribute is available (as there may have been an exception in setUpClass)
            # setting ignore_errors flag on WSGI server thread to avoid unwanted 10054
            cls.server_thread.httpd.ignore_errors = True
        cls.wd.quit() # cls.wd is the WebDriver instance
        super(LiveServerTestCase, cls).tearDownClass()

Could not find a simpler way to do it as the flag must be set before calling wd.quit(). Fully integrating it in Django would require a django-specific SeleniumTestCase class on top of LiveServerTestCase.

Last edited 3 years ago by Thomas Khyn (previous) (diff)

comment:11 Changed 3 years ago by Tim Graham

#22252 was a duplicate.

comment:12 Changed 3 years ago by anonymous

For anyone looking to repro this, here's a single test case that shows the error:

python runtests.py --selenium admin_widgets.tests.DateTimePickerSeleniumFirefoxTests

be aware that if this PR on logging gets accepted (https://github.com/jmbowman/django/commit/c34c5860d4e842e62574657ec61a125bc91b6c0f) then the error will no longer be visible on stdout. If I get time I'll try and build some kind of specific failing test for just this issue...

Note: See TracTickets for help on using tickets.
Back to Top