GispoCoding / pytest-qgis

A pytest plugin for testing QGIS python plugins
GNU General Public License v2.0
29 stars 8 forks source link

PermissionError when running unit tests (QGIS 3.30, pytest-qgis 1.3.4) #41

Closed pavetsu14 closed 1 year ago

pavetsu14 commented 1 year ago

Describe the bug

The bug described here has been occurring on multiple qgis plugin repositories after updating QGIS version from 3.22.14 to 3.30.3. When trying to run unit tests in new venv (with QGIS 3.30, no other modifications done on plugin code or dependencies compared to the old venv when unit tests worked fine), following occurs:

(.venv) C:\Users\xx\vscode\quality-result-gui>pytest test/unit ============================================================================== test session starts =============================================================================== platform win32 -- Python 3.9.5, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 PyQt5 5.15.4 -- Qt runtime 5.15.3 -- Qt compiled 5.15.2 rootdir: C:\Users\xx\vscode\quality-result-gui, configfile: pyproject.toml plugins: cov-2.12.0, dotenv-0.5.2, mock-3.7.0, order-1.0.0, qgis-1.3.0, qt-3.3.0, timeout-1.4.2 collected 116 items

test\unit\quality_result_gui\test_quality_data_fetcher.py .... [ 3%] test\unit\quality_result_gui\test_quality_error_visualizer.py .................. [ 18%] test\unit\quality_result_gui\test_quality_errors_filters.py ........... [ 28%] test\unit\quality_result_gui\test_quality_errors_manager.py ......... [ 36%] test\unit\quality_result_gui\test_quality_errors_tree_model.py .......................... [ 58%] test\unit\quality_result_gui\test_quality_layer.py ......................................... [ 93%] test\unit\quality_result_gui\ui\test_quality_errors_dock.py ...... [ 99%] test\unit\quality_result_gui_plugin\test_plugin.py sWindows fatal exception: access violation

Current thread 0x000063fc (most recent call first): File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pytestqt\plugin.py", line 197 in _process_events File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pytestqt\plugin.py", line 184 in pytest_runtest_teardown File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_callers.py", line 55 in _multicall File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_manager.py", line 80 in _hookexec File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_hooks.py", line 265 in call File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\runner.py", line 255 in File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\runner.py", line 311 in from_call File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\runner.py", line 254 in call_runtest_hook File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\runner.py", line 215 in call_and_report File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\runner.py", line 127 in runtestprotocol File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\runner.py", line 109 in pytest_runtest_protocol File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_callers.py", line 39 in _multicall File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_manager.py", line 80 in _hookexec File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_hooks.py", line 265 in call File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\main.py", line 348 in pytest_runtestloop File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_callers.py", line 39 in _multicall File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_manager.py", line 80 in _hookexec File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_hooks.py", line 265 in call File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\main.py", line 323 in _main File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\main.py", line 269 in wrap_session File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\main.py", line 316 in pytest_cmdline_main File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_callers.py", line 39 in _multicall File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_manager.py", line 80 in _hookexec File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages\pluggy_hooks.py", line 265 in call File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\config__init.py", line 162 in main File "c:\users\xx\vscode\quality-result-gui.venv\lib\site-packages_pytest\config__init__.py", line 185 in console_main File "C:\Users\xx\vscode\quality-result-gui.venv\Scripts\pytest.exe\main__.py", line 7 in File "C:\Omat\qgis\3.30.3\apps\Python39\lib\runpy.py", line 87 in _run_code File "C:\Omat\qgis\3.30.3\apps\Python39\lib\runpy.py", line 197 in _run_module_as_main

(.venv) C:\Users\xx\vscode\quality-result-gui>

The error description above happened with pytest-qgis version 1.3.0. Note that last test file only contains one skipped test so the problem is not in the tests itself. Next I installed the latest version of pytest-qgis, 1.3.4, and the following occurred:

(.venv) C:\Users\xx\vscode\quality-result-gui>pytest test/unit =============================================================================== test session starts =============================================================================== platform win32 -- Python 3.9.5, pytest-6.2.5, py-1.11.0, pluggy-1.0.0 PyQt5 5.15.4 -- Qt runtime 5.15.3 -- Qt compiled 5.15.2 rootdir: C:\Users\xx\vscode\quality-result-gui, configfile: pyproject.toml plugins: cov-2.12.0, dotenv-0.5.2, mock-3.7.0, order-1.0.0, qgis-1.3.4, qt-3.3.0, timeout-1.4.2 collected 116 items

test\unit\quality_result_gui\test_quality_data_fetcher.py .... [ 3%] test\unit\quality_result_gui\test_quality_error_visualizer.py .................. [ 18%] test\unit\quality_result_gui\test_quality_errors_filters.py ........... [ 28%] test\unit\quality_result_gui\test_quality_errors_manager.py ......... [ 36%] test\unit\quality_result_gui\test_quality_errors_tree_model.py .......................... [ 58%] test\unit\quality_result_gui\test_quality_layer.py ......................................... [ 93%] test\unit\quality_result_gui\ui\test_quality_errors_dock.py ...... [ 99%] test\unit\quality_result_gui_plugin\test_plugin.py sE [100%]

===================================================================================== ERRORS ====================================================================================== _ ERROR at teardown of test_dev_tool_action_shows_dialog __

request = <SubRequest 'qgis_app' for <Function test_run_background_check_status_signals[ongoing]>>

@pytest.fixture(autouse=True, scope="session")
def qgis_app(request: "SubRequest") -> QgsApplication:
    yield _APP if not request.config._plugin_settings.qgis_init_disabled else None

    if not request.config._plugin_settings.qgis_init_disabled:
        assert _APP
        if not sip.isdeleted(_CANVAS) and _CANVAS is not None:
            _CANVAS.deleteLater()
        _APP.exitQgis()
        if _QGIS_CONFIG_PATH and _QGIS_CONFIG_PATH.exists():
          shutil.rmtree(_QGIS_CONFIG_PATH)

.venv\lib\site-packages\pytest_qgis\pytest_qgis.py:158:


C:\Omat\qgis\3.30.3\apps\Python39\lib\shutil.py:740: in rmtree return _rmtree_unsafe(path, onerror) C:\Omat\qgis\3.30.3\apps\Python39\lib\shutil.py:613: in _rmtree_unsafe _rmtree_unsafe(fullname, onerror) C:\Omat\qgis\3.30.3\apps\Python39\lib\shutil.py:613: in _rmtree_unsafe _rmtree_unsafe(fullname, onerror) C:\Omat\qgis\3.30.3\apps\Python39\lib\shutil.py:618: in _rmtree_unsafe onerror(os.unlink, fullname, sys.exc_info())


path = 'C:\Users\xx~1\AppData\Local\Temp\pytest-qgissihc5j7z\profiles\default', onerror = <function rmtree..onerror at 0x000001854C0AAB80>

def _rmtree_unsafe(path, onerror):
    try:
        with os.scandir(path) as scandir_it:
            entries = list(scandir_it)
    except OSError:
        onerror(os.scandir, path, sys.exc_info())
        entries = []
    for entry in entries:
        fullname = entry.path
        if _rmtree_isdir(entry):
            try:
                if entry.is_symlink():
                    # This can only happen if someone replaces
                    # a directory with a symlink after the call to
                    # os.scandir or entry.is_dir above.
                    raise OSError("Cannot call rmtree on a symbolic link")
            except OSError:
                onerror(os.path.islink, fullname, sys.exc_info())
                continue
            _rmtree_unsafe(fullname, onerror)
        else:
            try:
              os.unlink(fullname)

E PermissionError: [WinError 32] Prosessi ei voi käyttää tiedostoa, koska se on toisen prosessin käytössä: 'C:\Users\xx~1\AppData\Local\Temp\pytest-qgissihc5j7z\profiles\default\user-history.db'

C:\Omat\qgis\3.30.3\apps\Python39\lib\shutil.py:616: PermissionError ---------------------------------------------------------------------------- Captured stderr teardown ----------------------------------------------------------------------------- QTemporaryDir: Unable to remove "C:\Users\xx\AppData\Local\Temp\python-WPoVHW" most likely due to the presence of read-only files. QTemporaryDir: Unable to remove "C:\Users\xx\AppData\Local\Temp\python-zZarlz" most likely due to the presence of read-only files. ============================================================================= short test summary info ============================================================================= ERROR test/unit/quality_result_gui_plugin/test_plugin.py::test_dev_tool_action_shows_dialog - PermissionError: [WinError 32] Prosessi ei voi käyttää tiedostoa, koska se on toise...==================================================================== 115 passed, 1 skipped, 1 error in 11.86s =====================================================================

(.venv) C:\Users\xx\vscode\quality-result-gui>

Environment (please complete the following information):

Joonalai commented 1 year ago

Thank you for the issue! Great that the original Access violation exception was changed into much more easily managable PermissionError. Since those temporary _QGIS_CONFIG_PATH files are already stored in User's temp directory, I think the easiest solution here is to suppress the PermissionError. You can test the solution by trying to install the PR #42 version of the project.