Code

Opened 6 months ago

Last modified 6 days ago

#21227 new Bug

Selenium tests terminate with [Errno 10054]

Reported by: marfire Owned by: nobody
Component: Testing framework Version: master
Severity: Normal Keywords: selenium
Cc: apollo13 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 tkhyn 2 months ago.

Download all attachments as: .zip

Change History (12)

comment:1 Changed 6 months ago by timo

  • Component changed from contrib.admin to Testing framework
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

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 6 months ago by marfire

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 6 months ago by timo

  • Resolution set to fixed
  • Status changed from new to closed

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 4 months ago by apollo13

@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 4 months ago by apollo13 (previous) (diff)

comment:5 Changed 4 months ago by apollo13

@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 4 months ago by apollo13

  • Cc apollo13 added

comment:7 Changed 3 months ago by marfire

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

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

In 7d0a5190328f277b97b1f55171e1fecb22a1e461:

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

This reverts commit 08c9ab5a0f564a3ac7803e6a97fae855f2e0524e.

comment:9 Changed 3 months ago by apollo13

  • Resolution fixed deleted
  • Status changed from closed to new

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 2 months ago by tkhyn

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 2 months ago by tkhyn (previous) (diff)

comment:11 Changed 6 days ago by timo

#22252 was a duplicate.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as new
The owner will be changed from nobody to anonymous. Next status will be 'assigned'
as The resolution will be set. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.