Coverage for tests/test_instrument.py: 34%

87 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2022-08-18 11:52 -0700

1# This file is part of pipe_base. 

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# This program is free software: you can redistribute it and/or modify 

10# it under the terms of the GNU General Public License as published by 

11# the Free Software Foundation, either version 3 of the License, or 

12# (at your option) any later version. 

13# 

14# This program is distributed in the hope that it will be useful, 

15# but WITHOUT ANY WARRANTY; without even the implied warranty of 

16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

17# GNU General Public License for more details. 

18# 

19# You should have received a copy of the GNU General Public License 

20# along with this program. If not, see <http://www.gnu.org/licenses/>. 

21 

22"""Tests of the Instrument class. 

23""" 

24 

25import datetime 

26import unittest 

27 

28from lsst.daf.butler import Registry, RegistryConfig 

29from lsst.daf.butler.formatters.json import JsonFormatter 

30from lsst.pipe.base import Instrument 

31from lsst.utils.introspection import get_full_type_name 

32 

33 

34class DummyInstrument(Instrument): 

35 @classmethod 

36 def getName(cls): 

37 return "DummyInstrument" 

38 

39 def register(self, registry, update=False): 

40 detector_max = 2 

41 record = { 

42 "instrument": self.getName(), 

43 "class_name": get_full_type_name(DummyInstrument), 

44 "detector_max": detector_max, 

45 } 

46 with registry.transaction(): 

47 registry.syncDimensionData("instrument", record, update=update) 

48 

49 def getRawFormatter(self, dataId): 

50 return JsonFormatter 

51 

52 

53class BadInstrument(DummyInstrument): 

54 """Instrument with wrong class name.""" 

55 

56 @classmethod 

57 def getName(cls): 

58 return "BadInstrument" 

59 

60 def register(self, registry, update=False): 

61 # Register a bad class name 

62 record = { 

63 "instrument": self.getName(), 

64 "class_name": "builtins.str", 

65 "detector_max": 1, 

66 } 

67 registry.syncDimensionData("instrument", record, update=update) 

68 

69 

70class UnimportableInstrument(DummyInstrument): 

71 """Instrument with class name that does not exist.""" 

72 

73 @classmethod 

74 def getName(cls): 

75 return "NoImportInstr" 

76 

77 def register(self, registry, update=False): 

78 # Register a bad class name 

79 record = { 

80 "instrument": self.getName(), 

81 "class_name": "not.importable", 

82 "detector_max": 1, 

83 } 

84 registry.syncDimensionData("instrument", record, update=update) 

85 

86 

87class InstrumentTestCase(unittest.TestCase): 

88 """Test for Instrument.""" 

89 

90 def setUp(self): 

91 self.instrument = DummyInstrument() 

92 self.name = "DummyInstrument" 

93 

94 def test_basics(self): 

95 self.assertEqual(self.instrument.getName(), self.name) 

96 self.assertEqual(self.instrument.getRawFormatter({}), JsonFormatter) 

97 

98 def test_register(self): 

99 """Test that register() sets appropriate Dimensions.""" 

100 registryConfig = RegistryConfig() 

101 registryConfig["db"] = "sqlite://" 

102 registry = Registry.createFromConfig(registryConfig) 

103 # Check that the registry starts out empty. 

104 self.instrument.importAll(registry) 

105 self.assertFalse(list(registry.queryDimensionRecords("instrument"))) 

106 

107 # Register and check again. 

108 self.instrument.register(registry) 

109 instruments = list(registry.queryDimensionRecords("instrument")) 

110 self.assertEqual(len(instruments), 1) 

111 self.assertEqual(instruments[0].name, self.name) 

112 self.assertEqual(instruments[0].detector_max, 2) 

113 self.assertIn("DummyInstrument", instruments[0].class_name) 

114 

115 self.instrument.importAll(registry) 

116 from_registry = DummyInstrument.fromName("DummyInstrument", registry) 

117 self.assertIsInstance(from_registry, Instrument) 

118 with self.assertRaises(LookupError): 

119 Instrument.fromName("NotThrere", registry) 

120 

121 # Register a bad instrument. 

122 BadInstrument().register(registry) 

123 with self.assertRaises(TypeError): 

124 Instrument.fromName("BadInstrument", registry) 

125 

126 UnimportableInstrument().register(registry) 

127 with self.assertRaises(ImportError): 

128 Instrument.fromName("NoImportInstr", registry) 

129 

130 # This should work even with the bad class name. 

131 self.instrument.importAll(registry) 

132 

133 def test_defaults(self): 

134 self.assertEqual(self.instrument.makeDefaultRawIngestRunName(), "DummyInstrument/raw/all") 

135 self.assertEqual( 

136 self.instrument.makeUnboundedCalibrationRunName("a", "b"), "DummyInstrument/calib/a/b/unbounded" 

137 ) 

138 self.assertEqual( 

139 self.instrument.makeCuratedCalibrationRunName("2018-05-04", "a"), 

140 "DummyInstrument/calib/a/curated/20180504T000000Z", 

141 ) 

142 self.assertEqual(self.instrument.makeCalibrationCollectionName("c"), "DummyInstrument/calib/c") 

143 self.assertEqual(self.instrument.makeRefCatCollectionName(), "refcats") 

144 self.assertEqual(self.instrument.makeRefCatCollectionName("a"), "refcats/a") 

145 self.assertEqual(self.instrument.makeUmbrellaCollectionName(), "DummyInstrument/defaults") 

146 

147 instrument = DummyInstrument(collection_prefix="Different") 

148 self.assertEqual(instrument.makeCollectionName("a"), "Different/a") 

149 self.assertEqual(self.instrument.makeCollectionName("a"), "DummyInstrument/a") 

150 

151 def test_collection_timestamps(self): 

152 self.assertEqual( 

153 Instrument.formatCollectionTimestamp("2018-05-03"), 

154 "20180503T000000Z", 

155 ) 

156 self.assertEqual( 

157 Instrument.formatCollectionTimestamp("2018-05-03T14:32:16"), 

158 "20180503T143216Z", 

159 ) 

160 self.assertEqual( 

161 Instrument.formatCollectionTimestamp("20180503T143216Z"), 

162 "20180503T143216Z", 

163 ) 

164 self.assertEqual( 

165 Instrument.formatCollectionTimestamp(datetime.datetime(2018, 5, 3, 14, 32, 16)), 

166 "20180503T143216Z", 

167 ) 

168 formattedNow = Instrument.makeCollectionTimestamp() 

169 self.assertIsInstance(formattedNow, str) 

170 datetimeThen1 = datetime.datetime.strptime(formattedNow, "%Y%m%dT%H%M%S%z") 

171 self.assertEqual(datetimeThen1.tzinfo, datetime.timezone.utc) 

172 

173 with self.assertRaises(TypeError): 

174 Instrument.formatCollectionTimestamp(0) 

175 

176 

177if __name__ == "__main__": 177 ↛ 178line 177 didn't jump to line 178, because the condition on line 177 was never true

178 unittest.main()