Coverage for tests/test_getTempFilePath.py: 19%

85 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-07-25 09:27 +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 with open(tmpFile, "w") as f: 

40 f.write("foo\n") 

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

42 

43 def testMultipleCallDepth(self): 

44 """Test getTempFile with multiple call depth""" 

45 funcName = "testMultipleCallDepth" 

46 self.runGetTempFile(funcName) 

47 self.runLevel2(funcName) 

48 self.runLevel3(funcName) 

49 

50 def runGetTempFile(self, funcName): 

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

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

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

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

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

56 f.write("foo\n") 

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

58 

59 def runLevel2(self, funcName): 

60 """Call runGetTempFile""" 

61 self.runGetTempFile(funcName) 

62 

63 def runLevel3(self, funcName): 

64 """Call runLevel2, which calls runGetTempFile""" 

65 self.runLevel2(funcName) 

66 

67 

68class TestNested(unittest.TestCase): 

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

70 

71 def testNested(self): 

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

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

74 self.assertNotEqual(tmpFile1, tmpFile2) 

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

76 f1.write("foo\n") 

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

78 f2.write("foo\n") 

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

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

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

82 

83 

84class TestExpected(unittest.TestCase): 

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

86 when we don't get them. 

87 """ 

88 

89 def testOutputExpected(self): 

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

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

92 f.write("foo\n") 

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

94 

95 with self.assertRaises(RuntimeError): 

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

97 pass 

98 

99 with self.assertRaises(RuntimeError): 

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

101 pass 

102 

103 def testOutputUnexpected(self): 

104 with self.assertRaises(RuntimeError): 

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

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

107 f.write("foo\n") 

108 

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

110 pass 

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

112 

113 

114class TestNameClash1(unittest.TestCase): 

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

116 

117 def testClash(self): 

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

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

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

121 f.write("foo\n") 

122 time.sleep(0.2) 

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

124 

125 

126class TestNameClash2(unittest.TestCase): 

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

128 

129 def testClash(self): 

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

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

132 """ 

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

134 time.sleep(0.1) 

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

136 f.write("foo\n") 

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

138 

139 

140class TestNameClash3(unittest.TestCase): 

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

142 

143 def testClash(self): 

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

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

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

147 f.write("foo\n") 

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

149 

150 

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

152 """Test for file descriptor leaks.""" 

153 

154 

155def setup_module(module): 

156 """Initialize the pytest environment.""" 

157 lsst.utils.tests.init() 

158 

159 

160if __name__ == "__main__": 

161 setup_module(sys.modules[__name__]) 

162 unittest.main()