-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
XIO: fatal IO error 0 (Success) on X server ":1001" #11
Comments
Hmm, that's odd, especially the "Success" part 😉 Does it happen at the very end of the testsuite by any chance? What GUI toolkit are you using there? |
Yep
TkInter ( |
Hmm, it might be the same thing as #1 then. Unfortunately I never was able to find out what's causing it exactly - and since it works fine for Qt5, I unfortunately don't have the time to dig further currently - too busy with my main project, qutebrowser 😆 Sorry! I'll let you know if I (or someone else) figure out more somehow though. |
I can confirm that
I read the recent announcement on the Python planet. Congrats and best of luck with the project 👍
I am afraid I won't be of any help. It was mostly a heads-up in case someone else had trouble using it with a different UI toolkit. Worst case, we still have good old manual calls to |
I have the following test that allows me to get the same "success" message at the end of pytest: from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.button = QtGui.QPushButton('Test', self)
self.button.clicked.connect(self.handleButton)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.button)
def handleButton(self):
print('Hello World')
def test_qtgui(qtbot, capsys):
w = Window()
qtbot.mouseClick(w.button, QtCore.Qt.LeftButton)
out, err = capsys.readouterr()
assert 'Hello World' in out
|
FWIW I see something like this as well with Qt5 nowadays (I think it was with the new PyQt exit scheme). Interestingly, it only happens when I run a subset of my tests, not when I run all of them - so there might be something in there that fixes it. |
I just ran into the same issue with PyQt5. I'm getting it when I'm repeatedly opening and closing a dialog which performs threaded tasks, but the tasks and threads are being cleaned up before the dialog closes and the main window freezes. |
FWIW my issue was with a thread being closed and improperly closing sqlite3 resources |
For qutebrowser tests, it seems to depend on how much time is passing after the widget tests have finished. For example, Maybe we need to change something so we close the server after pytest-qt has had a chance to clean up widgets? Also, it looks like it only happens with Qt 5.13 and newer - no issues with Qt 5.7 to 5.12... |
I'm having a similar problem using TkAgg backend. The unit tests all run fine, it's in the cleanup. Using latest version of matplotlib etc. |
@petercorke Any chance you can show things (the exact output, ideally the code triggering it) instead of describing them? That might help in tracking this down. |
The project is https://github.com/petercorke/spatialmath-python and the raw log is: 2020-08-19T06:52:56.4452400Z env: the last test, spatialmath/base/test_transforms.py, does a bunch of matplotlib 3D plots and 3D animations using FuncAnimation. All graphical windows are closed after the tests using tearDownClass() handler. The tests all pass, but it looks like the error occurs as pytest is exiting up. From what I can see of the code, a SIGTERM is sent to xvfb but maybe this error is caused by the pipe closing before it dies?? This is running on some version of Ubuntu provided by GH, apparently "latest". I'm happy to add debugs if you can advise what to add. Thanks. |
@petercorke Thanks! It might take me a while until I get the time to get back to this. |
@jhavl and I did some digging on this. The error happens in unconfigure, which is calling code in pyvirtualdisplay package. The error happens as soon as we attempt to terminate the Xvfb subprocess when THERE ARE STILL OPEN WINDOWS. This is really more an Xvfb issue than a pytest-xvfb issue, but there's lots of people in forums asking about this bug. The lesson, close all your windows after each unit test. |
I still haven't had a chance to dig into this more I'm afraid - thanks for the useful information though, @petercorke! If that's all there is to it, I might be able to add some code to I now found a way to reproduce this when running the entire testsuite of qutebrowser (rather than just a part): diff --git a/tests/unit/utils/test_utils.py b/tests/unit/utils/test_utils.py
index d674dd694..bbeeff5cc 100644
--- a/tests/unit/utils/test_utils.py
+++ b/tests/unit/utils/test_utils.py
@@ -706,9 +706,9 @@ def test_set_unsupported_selection(self, clipboard_mock):
(False, 'clipboard', 'fake text', 'fake text'),
(False, 'clipboard', 'füb', r'f\u00fcb'),
])
- def test_set_logging(self, clipboard_mock, caplog, selection, what,
+ def test_set_logging(self, monkeypatch, clipboard_mock, caplog, selection, what,
text, expected):
- utils.log_clipboard = True
+ monkeypatch.setattr(utils, 'log_clipboard', True)
utils.set_clipboard(text, selection=selection)
assert not clipboard_mock.setText.called
expected = 'Setting fake {}: "{}"'.format(what, expected)
Why? No idea. |
https://build.opensuse.org/request/show/881754 by user bnavigator + RBrownSUSE - Remove removal of early QtWebEngine import before tests. It triggered a fallback to testing with qtwebkit which is being removed from Tumbleweed - Switch to xvfb-run instead of pytest-xvfb to avoid gh#The-Compiler/pytest-xvfb#11 - Replace pytest-ordering marks with pytest-order gh#spyder-ide/spyder#14935 - Update to version 4.2.5 * Fix restoring window properties at startup. * Fix a segfault when restarting kernels. * Fix a segfault when processing linting results. - Update to version 4.2.4 * Fix an important error when restarting kernels. * Add compatibility with the future Spyder
There are times our tests suffer from The-Compiler/pytest-xvfb#11 That is, the tests run but because smoething still has a window open then the xvfb server falls over, causing the tests to appear to fail, when they haven't. Following the discussion in this issue this commit adds a session-scoped fixture that ensures that any matplotlib windows are closed before the tests end.
There are times our tests suffer from The-Compiler/pytest-xvfb#11 That is, the tests run but because smoething still has a window open then the xvfb server falls over, causing the tests to appear to fail, when they haven't. Following the discussion in this issue this commit adds a session-scoped fixture that ensures that any matplotlib windows are closed before the tests end.
Encountered same issue. It happened when I added a long test using (EDIT) Here are the build results, Order of the test functions in the file did not matter. (EDIT) |
This seems to reliably reproduce it (minimized from pytest-dev/pytest-qt#490): import pytest
import sys
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from PyQt5.QtWidgets import QWidget, QApplication
app = QApplication(sys.argv)
def test_widget():
widget = QWidget()
widget.show() Most notably, removing the QtWebEngine import fixes the problem?! Using xvfb-run also still works correctly. I'm still puzzled. This is with Python 3.11.3 and:
|
Plain Python reproducer: import sys
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from PyQt5.QtWidgets import QWidget, QApplication
from pyvirtualdisplay import Display
with Display() as disp:
app = QApplication(sys.argv)
widget = QWidget()
widget.show() and a quick hack without PyVirtualDisplay: import os
import sys
import time
import subprocess
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from PyQt5.QtWidgets import QWidget, QApplication
proc = subprocess.Popen(["Xvfb", ":42"])
os.environ["DISPLAY"] = ":42"
time.sleep(1)
app = QApplication(sys.argv)
widget = QWidget()
widget.show()
print("done")
proc.terminate() I suppose the problem is that the QApplication (or PyQt) does some kind of cleanup (like disconnecting from the X server?) when the process exits. However, if we start Xvfb from inside Python, and we want to terminate it cleanly, it follows that Xvfb will always be killed before the process where the It's still unclear to me why this only happens sometimes (in the qutebrowser testsuite I only see it when running individual tests, not when running the entire testsuite) - or why it only happens when importing QtWebEngine (might be registering some kind of exit hooks?). Sadly, even using import os
import sys
import time
import subprocess
import atexit
from PyQt5.QtWebEngineWidgets import QWebEnginePage
from PyQt5.QtWidgets import QWidget, QApplication
proc = subprocess.Popen(["Xvfb", ":42"])
atexit.register(proc.terminate)
os.environ["DISPLAY"] = ":42"
time.sleep(1)
app = QApplication(sys.argv)
widget = QWidget()
widget.show()
print("done") |
You are probably right about the exit hooks. I found that simply importing the dependencies after having registered the xvfb exit hook works.
Note that simply changing the order of these lines makes all the difference: It makes sense if pyqt's hooks are also using atexit, since per the documentation they will run in reverse order as they were registered. |
I don't know a lot about pytest, but I guess this can be solved by registering this exit hook before the rest of the imports, perhaps by creating a dummy module which must be imported before any other dependencies. However, I am not sure how to reconcile this with the pytest framework. |
Using I have a few small things I want to look at, and then it's time for a v3.0.0 release with this (hopefully) finally fixed for everyone. Thanks @jacobszpz for the initial reproducer and the ideas around atexit! |
v3.0.0 has been released! I added a test for the reproducer involving QtWebEngine, but if anyone else here who was still seeing this could confirm it's now gone, that'd be great. |
I tried to run the test suite of
ltfatpy
usingpytest-xvfb
but it fails with the following error:The test suite succeeds if I call pytest with
xvfb-run -a
and the verbose log indicates that no test has failed in either cases.Any idea what could cause this?
The text was updated successfully, but these errors were encountered: