Fix memory leak in apache unit tests (#10421)

This was causing oldest tests to fail on my mac, which has an open file
limit of 256. Locks were being released at exit, but there were more
than 256 tests being run at once. Holding onto the file descriptor for
temporary files was making us keep the files open.

I also removed unnecessary setUps and tearDowns in subclasses so that
this could be fixed in only one spot.

If you wanted to do any testing locally, I was throwing this in places:
```
import errno, os, resource
open_file_handles = []
for fd in range(resource.getrlimit(resource.RLIMIT_NOFILE)[0]):
    try: os.fstat(fd)
    except OSError as e:
        if e.errno == errno.EBADF: continue
    open_file_handles.append(fd)
print(f'location description: {len(open_file_handles)}')
```
This commit is contained in:
ohemorange
2025-08-14 17:13:33 -07:00
committed by GitHub
parent 49900b27d3
commit 454048f2f6
4 changed files with 2 additions and 28 deletions
@@ -1,5 +1,4 @@
"""Tests for certbot_apache._internal.parser.""" """Tests for certbot_apache._internal.parser."""
import shutil
import sys import sys
import pytest import pytest
@@ -20,11 +19,6 @@ class ComplexParserTest(util.ParserTest):
# until after # until after
self.parser.parse_modules() # pylint: disable=protected-access self.parser.parse_modules() # pylint: disable=protected-access
def tearDown(self):
shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
def setup_variables(self): def setup_variables(self):
"""Set up variables for parser.""" """Set up variables for parser."""
self.parser.variables.update( self.parser.variables.update(
@@ -1,5 +1,4 @@
"""Test for certbot_apache._internal.configurator implementations of reverter""" """Test for certbot_apache._internal.configurator implementations of reverter"""
import shutil
import sys import sys
from unittest import mock from unittest import mock
@@ -20,11 +19,6 @@ class ConfiguratorReverterTest(util.ApacheTest):
self.vh_truth = util.get_vh_truth(self.temp_dir, "debian_apache_2_4/multiple_vhosts") self.vh_truth = util.get_vh_truth(self.temp_dir, "debian_apache_2_4/multiple_vhosts")
def tearDown(self):
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
shutil.rmtree(self.temp_dir)
def test_bad_save_checkpoint(self): def test_bad_save_checkpoint(self):
self.config.reverter.add_to_checkpoint = mock.Mock(side_effect=errors.ReverterError) self.config.reverter.add_to_checkpoint = mock.Mock(side_effect=errors.ReverterError)
self.config.parser.add_dir(self.vh_truth[0].path, "Test", "bad_save_ckpt") self.config.parser.add_dir(self.vh_truth[0].path, "Test", "bad_save_ckpt")
@@ -1,5 +1,4 @@
"""Tests for certbot_apache._internal.parser.""" """Tests for certbot_apache._internal.parser."""
import shutil
import sys import sys
from unittest import mock from unittest import mock
@@ -13,14 +12,6 @@ from certbot_apache._internal.tests import util
class BasicParserTest(util.ParserTest): class BasicParserTest(util.ParserTest):
"""Apache Parser Test.""" """Apache Parser Test."""
def setUp(self): # pylint: disable=arguments-differ
super().setUp()
def tearDown(self):
shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
def test_bad_parse(self): def test_bad_parse(self):
self.parser.parse_file(os.path.join(self.parser.root, self.parser.parse_file(os.path.join(self.parser.root,
"conf-available", "bad_conf_file.conf")) "conf-available", "bad_conf_file.conf"))
@@ -341,13 +332,6 @@ class BasicParserTest(util.ParserTest):
class ParserInitTest(util.ApacheTest): class ParserInitTest(util.ApacheTest):
def setUp(self): # pylint: disable=arguments-differ
super().setUp()
def tearDown(self):
shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir)
@mock.patch("certbot_apache._internal.parser.init_augeas") @mock.patch("certbot_apache._internal.parser.init_augeas")
def test_prepare_no_augeas(self, mock_init_augeas): def test_prepare_no_augeas(self, mock_init_augeas):
@@ -7,6 +7,7 @@ from unittest import mock
import augeas import augeas
import josepy as jose import josepy as jose
from certbot import util
from certbot.compat import os from certbot.compat import os
from certbot.plugins import common from certbot.plugins import common
from certbot.tests import util as test_util from certbot.tests import util as test_util
@@ -53,6 +54,7 @@ class ApacheTest(unittest.TestCase):
os.symlink(target, vhost) os.symlink(target, vhost)
def tearDown(self) -> None: def tearDown(self) -> None:
util._release_locks()
shutil.rmtree(self.temp_dir) shutil.rmtree(self.temp_dir)
shutil.rmtree(self.config_dir) shutil.rmtree(self.config_dir)
shutil.rmtree(self.work_dir) shutil.rmtree(self.work_dir)