~wgrant/ubuntu/natty/landscape-client/natty-updates-broken

« back to all changes in this revision

Viewing changes to landscape/lib/tests/test_fd.py

  • Committer: Bazaar Package Importer
  • Author(s): Christopher Armstrong
  • Date: 2009-04-09 17:09:50 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20090409170950-mc5mqadawk0ls2vc
Tags: 1.0.29-0ubuntu0.9.04.0
* New upstream bugfix release (LP: #358744)
  - Add a timeout to HTTP operations to avoid hanging (LP: #349737)
  - Clean up environment variables on startup to avoid propagating
    variables that will corrupt package installation (LP: #348681)
  - Clean up FDs on startup for the same reason (LP: #352458)
  - Catch and handle certain errors from smart (such as invalid package
    data) to avoid "stuck" Landscape activities (LP: #268745)
  - Don't print warnings meant for developers to the console (LP: #336669)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""Tests for L{landscape.lib.fd}"""
 
2
 
 
3
import resource
 
4
from landscape.tests.mocker import ANY
 
5
 
 
6
from landscape.lib.fd import clean_fds
 
7
from landscape.tests.helpers import LandscapeTest
 
8
 
 
9
 
 
10
class CleanFDsTests(LandscapeTest):
 
11
    """Tests for L{clean_fds}."""
 
12
    
 
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])
 
17
 
 
18
    def test_clean_fds_rlimit(self):
 
19
        """
 
20
        L{clean_fds} cleans all non-stdio file descriptors up to the process
 
21
        limit for file descriptors.
 
22
        """
 
23
        self.mocker.order()
 
24
        self.mock_rlimit(10)
 
25
        close_mock = self.mocker.replace("os.close", passthrough=False)
 
26
        for i in range(3, 10):
 
27
            close_mock(i)
 
28
        self.mocker.replay()
 
29
        clean_fds()
 
30
 
 
31
    def test_clean_fds_sanity(self):
 
32
        """
 
33
        If the process limit for file descriptors is very high (> 4096), then
 
34
        we only close 4096 file descriptors.
 
35
        """
 
36
        self.mocker.order()
 
37
        self.mock_rlimit(4100)
 
38
        close_mock = self.mocker.replace("os.close", passthrough=False)
 
39
        closed_fds = []
 
40
        close_mock(ANY)
 
41
        self.mocker.call(closed_fds.append)
 
42
        self.mocker.count(4093)
 
43
        self.mocker.replay()
 
44
        clean_fds()
 
45
        self.assertEquals(closed_fds, range(3, 4096))
 
46
 
 
47
    def test_ignore_OSErrors(self):
 
48
        """
 
49
        If os.close raises an OSError, it is ignored and we continue to close
 
50
        the rest of the FDs.
 
51
        """
 
52
        self.mocker.order()
 
53
        self.mock_rlimit(10)
 
54
 
 
55
        closed_fds = []
 
56
        def remember_and_throw(fd):
 
57
            closed_fds.append(fd)
 
58
            raise OSError("Bad FD!")
 
59
 
 
60
        close_mock = self.mocker.replace("os.close", passthrough=False)
 
61
        close_mock(ANY)
 
62
        self.mocker.count(7)
 
63
        self.mocker.call(remember_and_throw)
 
64
 
 
65
        self.mocker.replay()
 
66
        clean_fds()
 
67
        self.assertEquals(closed_fds, range(3, 10))
 
68
 
 
69
    def test_dont_ignore_other_errors(self):
 
70
        """
 
71
        If other errors are raised from os.close, L{clean_fds} propagates them.
 
72
        """
 
73
        self.mocker.order()
 
74
        self.mock_rlimit(10)
 
75
        close_mock = self.mocker.replace("os.close", passthrough=False)
 
76
        close_mock(ANY)
 
77
        self.mocker.throw(MemoryError())
 
78
 
 
79
        self.mocker.replay()
 
80
        self.assertRaises(MemoryError, clean_fds)