--select-instances hbal manpage update
[ganeti-local] / test / tempfile_fork_unittest.py
1 #!/usr/bin/python
2 #
3
4 # Copyright (C) 2010 Google Inc.
5 #
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful, but
12 # WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 # General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 # 02110-1301, USA.
20
21
22 """Script for testing utils.ResetTempfileModule"""
23
24 import os
25 import sys
26 import errno
27 import shutil
28 import tempfile
29 import unittest
30 import logging
31
32 from ganeti import utils
33
34 import testutils
35
36
37 # This constant is usually at a much higher value. Setting it lower for test
38 # purposes.
39 tempfile.TMP_MAX = 3
40
41
42 class TestResetTempfileModule(unittest.TestCase):
43   def setUp(self):
44     self.tmpdir = tempfile.mkdtemp()
45
46   def tearDown(self):
47     shutil.rmtree(self.tmpdir)
48
49   def testNoReset(self):
50     self._Test(False)
51
52   def testReset(self):
53     self._Test(True)
54
55   def _Test(self, reset):
56     self.failIf(tempfile.TMP_MAX > 10)
57
58     # Initialize tempfile module
59     (fd, _) = tempfile.mkstemp(dir=self.tmpdir, prefix="init.", suffix="")
60     os.close(fd)
61
62     (notify_read, notify_write) = os.pipe()
63
64     pid = os.fork()
65     if pid == 0:
66       # Child
67       try:
68         try:
69           if reset:
70             utils.ResetTempfileModule()
71
72           os.close(notify_write)
73
74           # Wait for parent to close pipe
75           os.read(notify_read, 1)
76
77           try:
78             # This is a short-lived process, not caring about closing file
79             # descriptors
80             (_, path) = tempfile.mkstemp(dir=self.tmpdir,
81                                          prefix="test.", suffix="")
82           except EnvironmentError, err:
83             if err.errno == errno.EEXIST:
84               # Couldnt' create temporary file (e.g. because we run out of
85               # retries)
86               os._exit(2)
87             raise
88
89           logging.debug("Child created %s", path)
90
91           os._exit(0)
92         except Exception:
93           logging.exception("Unhandled error")
94       finally:
95         os._exit(1)
96
97     # Parent
98     os.close(notify_read)
99
100     # Create parent's temporary files
101     for _ in range(tempfile.TMP_MAX):
102       (fd, path) = tempfile.mkstemp(dir=self.tmpdir,
103                                     prefix="test.", suffix="")
104       os.close(fd)
105       logging.debug("Parent created %s", path)
106
107     # Notify child by closing pipe
108     os.close(notify_write)
109
110     (_, status) = os.waitpid(pid, 0)
111
112     self.failIf(os.WIFSIGNALED(status))
113
114     if reset:
115       # If the tempfile module was reset, it should not fail to create
116       # temporary files
117       expected = 0
118     else:
119       expected = 2
120
121     self.assertEqual(os.WEXITSTATUS(status), expected)
122
123
124 if __name__ == "__main__":
125   testutils.GanetiTestProgram()