simplistix/testfixtures

8.3.0 fails with "AssertionError: LogCapture instance closed while still installed"

Closed this issue · 2 comments

In the tests for our pywbem project we have a "recorder" module and its unit tests use testfixtures.LogCapture to test the logs produced by the module. We are using logging.shutdown() in the test setup method to make sure there are no loggers left before we set them up again.

That worked fine all the time, but with testfixtures 8.3.0, the logging.shutdown() call fails with:

self = <tests.unittest.pywbem.test_recorder.TestLoggingEndToEnd object at 0x111ba85c0>

    def setup_method(self):
        """
        Setup that is run before each test method.
        """
        # Shut down any existing logger and reset WBEMConnection and
        # reset WBEMConnection class attributes
        # pylint: disable=protected-access
        WBEMConnection._reset_logging_config()
>       logging.shutdown()

tests/unittest/pywbem/test_recorder.py:1627: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/local/Cellar/python@3.12/3.12.3/Frameworks/Python.framework/Versions/3.12/lib/python3.12/logging/__init__.py:2265: in shutdown
    h.close()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <LogCapture (Level 1)>

    def close(self):
        super().close()
        if self in self.instances:
>           raise AssertionError(
                'LogCapture instance closed while still installed, '
                'loggers captured:\n'
                '%s' % ('\n'.join((str(i.names) for i in self.instances)))
            )
E           AssertionError: LogCapture instance closed while still installed, loggers captured:
E           (None,)

../../../virtualenvs/pywbem312/lib/python3.12/site-packages/testfixtures/logcapture.py:304: AssertionError
_________________________________________________________ ERROR at setup of TestLoggingEndToEnd.test_9 _________________________________________________________

The exception is raised here: https://github.com/simplistix/testfixtures/blob/master/testfixtures/logcapture.py#L304 and this code was introduced in PR #198 and released with testfixtures 8.3.0.

Do you consider our use of logging.shutdown() in the test setup method legitimate?
If not, what do you recommend instead to ensure there are no loggers left?
Why is there a None item in self.instances and is there a way to get rid of it?

For now, I am circumventing the issue by excluding testfixtures 8.3.0 in our dev dependencies.

Do you consider our use of logging.shutdown() in the test setup method legitimate?

Yes, but you should ensure there are no installed LogCapture instances when you do so.
I introduced this assertion, because I got bitten by a nasty intermittent test failure resulting from a LogCapture still being installed when logging.shutdown was called by a test.

If not, what do you recommend instead to ensure there are no loggers left?

LogCapture.uninstall_all()
WBEMConnection._reset_logging_config()
logging.shutdown()

Why is there a None item in self.instances and is there a way to get rid of it?

It's not, it's showing you what loggers were being captured by the LogCapture that was still installed; (None,) is the default of the root logger.

Thanks for the response.

Just for the record: The suggested code sequence did not work, but it turned out that in this place (the test setup method), we did not need logging.shutdown() in the first place, so the solution for us was to remove it (PR pywbem/pywbem#3217).