Coverage for tests/test_getTempFilePath.py: 19%

87 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-08 09:53 +0000

1# This file is part of utils. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (https://www.lsst.org). 

6# See the COPYRIGHT file at the top-level directory of this distribution 

7# for details of code ownership. 

8# 

9# Use of this source code is governed by a 3-clause BSD-style 

10# license that can be found in the LICENSE file. 

11 

12import os.path 

13import sys 

14import time 

15import unittest 

16 

17import lsst.utils.tests 

18 

19"""This file contains tests for lsst.utils.tests.getTempFilePath. 

20 

21The ``TestNameClashN`` classes are used to check that getTempFilePath 

22does not use the same name across different test classes in the same 

23file even if they have the same test methods. They are distinct classes 

24with the same test method in an attempt to trigger a race condition 

25whereby context managers use the same name and race to delete the file. 

26The sleeps are there to ensure the race condition occurs in older versions 

27of this package. This should not happen as of DM-13046. 

28""" 

29 

30 

31class GetTempFilePathTestCase(unittest.TestCase): 

32 """Tests for temporary file path creation.""" 

33 

34 def testBasics(self): 

35 with lsst.utils.tests.getTempFilePath(".txt") as tmpFile: 

36 # Path will have unique component so do not test full equality 

37 self.assertIn("test_getTempFilePath_testBasics", tmpFile) 

38 self.assertTrue(tmpFile.endswith(".txt")) 

39 f = open(tmpFile, "w") 

40 f.write("foo\n") 

41 f.close() 

42 self.assertFalse(os.path.exists(tmpFile)) 

43 

44 def testMultipleCallDepth(self): 

45 """Test getTempFile with multiple call depth""" 

46 funcName = "testMultipleCallDepth" 

47 self.runGetTempFile(funcName) 

48 self.runLevel2(funcName) 

49 self.runLevel3(funcName) 

50 

51 def runGetTempFile(self, funcName): 

52 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile: 

53 # Path will have unique component so do not test full equality 

54 self.assertIn(f"test_getTempFilePath_{funcName}", tmpFile) 

55 self.assertTrue(tmpFile.endswith(".fits")) 

56 f = open(tmpFile, "w") 

57 f.write("foo\n") 

58 f.close() 

59 self.assertFalse(os.path.exists(tmpFile)) 

60 

61 def runLevel2(self, funcName): 

62 """Call runGetTempFile""" 

63 self.runGetTempFile(funcName) 

64 

65 def runLevel3(self, funcName): 

66 """Call runLevel2, which calls runGetTempFile""" 

67 self.runLevel2(funcName) 

68 

69 

70class TestNested(unittest.TestCase): 

71 """Tests of the use of getTempFilePath in nested context managers.""" 

72 

73 def testNested(self): 

74 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile1: 

75 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile2: 

76 self.assertNotEqual(tmpFile1, tmpFile2) 

77 with open(tmpFile1, "w") as f1: 

78 f1.write("foo\n") 

79 with open(tmpFile2, "w") as f2: 

80 f2.write("foo\n") 

81 self.assertTrue(os.path.exists(tmpFile1)) 

82 self.assertFalse(os.path.exists(tmpFile2)) 

83 self.assertFalse(os.path.exists(tmpFile1)) 

84 

85 

86class TestExpected(unittest.TestCase): 

87 """Tests that we get files when we expect to get them and we get upset 

88 when we don't get them. 

89 """ 

90 

91 def testOutputExpected(self): 

92 with lsst.utils.tests.getTempFilePath(".txt") as tmpFile: 

93 with open(tmpFile, "w") as f: 

94 f.write("foo\n") 

95 self.assertFalse(os.path.exists(tmpFile)) 

96 

97 with self.assertRaises(RuntimeError): 

98 with lsst.utils.tests.getTempFilePath(".txt", expectOutput=True) as tmpFile: 

99 pass 

100 

101 with self.assertRaises(RuntimeError): 

102 with lsst.utils.tests.getTempFilePath(".txt") as tmpFile: 

103 pass 

104 

105 def testOutputUnexpected(self): 

106 with self.assertRaises(RuntimeError): 

107 with lsst.utils.tests.getTempFilePath(".txt", expectOutput=False) as tmpFile: 

108 with open(tmpFile, "w") as f: 

109 f.write("foo\n") 

110 

111 with lsst.utils.tests.getTempFilePath(".txt", expectOutput=False) as tmpFile: 

112 pass 

113 self.assertFalse(os.path.exists(tmpFile)) 

114 

115 

116class TestNameClash1(unittest.TestCase): 

117 """Test involving a potential clash of test method name.""" 

118 

119 def testClash(self): 

120 """Create the temp file and pause before trying to delete it.""" 

121 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile: 

122 with open(tmpFile, "w") as f: 

123 f.write("foo\n") 

124 time.sleep(0.2) 

125 self.assertTrue(os.path.exists(tmpFile)) 

126 

127 

128class TestNameClash2(unittest.TestCase): 

129 """Test involving a potential clash of test method name.""" 

130 

131 def testClash(self): 

132 """Pause a little before trying to create the temp file. The pause 

133 time is less than the time that TestNameClash1 is pausing. 

134 """ 

135 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile: 

136 time.sleep(0.1) 

137 with open(tmpFile, "w") as f: 

138 f.write("foo\n") 

139 self.assertTrue(os.path.exists(tmpFile)) 

140 

141 

142class TestNameClash3(unittest.TestCase): 

143 """Test involving a potential clash of test method name.""" 

144 

145 def testClash(self): 

146 """Create temp file and remove it without pauses.""" 

147 with lsst.utils.tests.getTempFilePath(".fits") as tmpFile: 

148 with open(tmpFile, "w") as f: 

149 f.write("foo\n") 

150 self.assertTrue(os.path.exists(tmpFile)) 

151 

152 

153class TestMemory(lsst.utils.tests.MemoryTestCase): 

154 """Test for file descriptor leaks.""" 

155 

156 

157def setup_module(module): 

158 """Initialize the pytest environment.""" 

159 lsst.utils.tests.init() 

160 

161 

162if __name__ == "__main__": 

163 setup_module(sys.modules[__name__]) 

164 unittest.main()