1
"""Tests for L{landscape.lib.fd}"""
4
from landscape.tests.mocker import ANY
6
from landscape.lib.fd import clean_fds
7
from landscape.tests.helpers import LandscapeTest
10
class CleanFDsTests(LandscapeTest):
11
"""Tests for L{clean_fds}."""
13
def mock_rlimit(self, limit):
14
getrlimit_mock = self.mocker.replace("resource.getrlimit")
15
getrlimit_mock(resource.RLIMIT_NOFILE)
16
self.mocker.result([None, limit])
18
def test_clean_fds_rlimit(self):
20
L{clean_fds} cleans all non-stdio file descriptors up to the process
21
limit for file descriptors.
25
close_mock = self.mocker.replace("os.close", passthrough=False)
26
for i in range(3, 10):
31
def test_clean_fds_sanity(self):
33
If the process limit for file descriptors is very high (> 4096), then
34
we only close 4096 file descriptors.
37
self.mock_rlimit(4100)
38
close_mock = self.mocker.replace("os.close", passthrough=False)
41
self.mocker.call(closed_fds.append)
42
self.mocker.count(4093)
45
self.assertEquals(closed_fds, range(3, 4096))
47
def test_ignore_OSErrors(self):
49
If os.close raises an OSError, it is ignored and we continue to close
56
def remember_and_throw(fd):
58
raise OSError("Bad FD!")
60
close_mock = self.mocker.replace("os.close", passthrough=False)
63
self.mocker.call(remember_and_throw)
67
self.assertEquals(closed_fds, range(3, 10))
69
def test_dont_ignore_other_errors(self):
71
If other errors are raised from os.close, L{clean_fds} propagates them.
75
close_mock = self.mocker.replace("os.close", passthrough=False)
77
self.mocker.throw(MemoryError())
80
self.assertRaises(MemoryError, clean_fds)