Coverage for tests/test_jointcalRunner.py: 25%

83 statements  

« prev     ^ index     » next       coverage.py v7.2.1, created at 2023-03-12 03:55 -0700

1# This file is part of jointcal. 

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 <https://www.gnu.org/licenses/>. 

21 

22import os.path 

23import tempfile 

24import unittest 

25import unittest.mock 

26 

27import lsst.log 

28import lsst.utils 

29 

30import lsst.daf.persistence 

31import lsst.jointcal 

32from lsst.meas.algorithms import DatasetConfig 

33import lsst.pipe.base 

34 

35current_dir = os.path.abspath(os.path.dirname(__file__)) 

36 

37 

38# for MemoryTestCase 

39def setup_module(module): 

40 lsst.utils.tests.init() 

41 

42 

43class TestJointcalRunner(lsst.utils.tests.TestCase): 

44 """Test that JointcalRunner calls JointcalTask with appropriate arguments. 

45 

46 This test mocks a butler to force JointcalRunner to be called with 

47 specific sets of parameters (e.g. 1 or 2 tracts), and mocks JointcalTask to 

48 check that it is called the correct number of times (i.e. once per tract). 

49 """ 

50 @classmethod 

51 def setUpClass(cls): 

52 cls.data_dir = os.path.join(current_dir, 'data') 

53 

54 def setUp(self): 

55 def mock_get(arg): 

56 """Return things that sub-tasks need from butler.get().""" 

57 if arg == 'verify_job_filename': 

58 return 'some/path/filename.job' 

59 elif arg == 'ref_cat_config': 

60 result = unittest.mock.Mock(DatasetConfig) 

61 result.indexer = DatasetConfig().indexer 

62 return result 

63 else: 

64 return None 

65 

66 def mock_dataRef(datasetType, level=None, dataId=None): 

67 """Return a fake dataRef that always exists.""" 

68 ref = lsst.daf.persistence.ButlerDataRef(None, dataId) 

69 ref.datasetExists = lambda: True 

70 return ref 

71 

72 def mock_subset(datasetType, dataId=None): 

73 """Return a fake butler subset containing one dataRef.""" 

74 return [mock_dataRef(datasetType, dataId=dataId)] 

75 

76 butlerPatcher = unittest.mock.patch("lsst.daf.persistence.Butler", autospec=True) 

77 self.butler = butlerPatcher.start() 

78 self.addCleanup(butlerPatcher.stop) 

79 self.butler.return_value.get = mock_get 

80 self.butler.return_value.subset = mock_subset 

81 self.butler.return_value.dataRef = mock_dataRef 

82 self.butler.return_value.getKeys.return_value = {'visit': int, 'ccd': int} 

83 # static methods: mock on the class, not the return_value 

84 self.butler.getMapperClass.return_value.getPackageName.return_value = 'jointcal' 

85 self.butler.getMapperClass.return_value.getCameraName.return_value = 'cfht' 

86 

87 def prep_jointcal(self, tracts=None): 

88 """Prepare a jointcal mock to be called by JointcalRunner. 

89 

90 We use the `tests/data/cfht_minimal` repo to provide a "real" refcat, 

91 and use dataIds associated with it, even though we mock the butler. 

92 

93 Parameters 

94 ---------- 

95 tracts : `list` [`int`] 

96 List of tracts to build DataRefs for. 

97 """ 

98 configfile = os.path.join(current_dir, 'config/config.py') 

99 

100 input_dir = os.path.join(self.data_dir, 'cfht_minimal') 

101 output_dir = tempfile.mkdtemp() # we don't care about any outputs 

102 

103 visits = '849375^850587' 

104 args = [input_dir, '--output', output_dir, '--doraise', '--configfile=%s'%configfile, 

105 '--id', 'visit=%s'%visits, 'ccd=12'] 

106 if tracts is not None: 

107 args.append('tract=%s'%'^'.join(str(tract) for tract in tracts)) 

108 

109 config = lsst.jointcal.JointcalConfig() 

110 parser = lsst.jointcal.JointcalTask._makeArgumentParser() 

111 parsedArgs = parser.parse_args(config, args=args) 

112 

113 jointcalPatcher = unittest.mock.patch("lsst.jointcal.JointcalTask", autospec=True) 

114 JointcalTask = jointcalPatcher.start() 

115 self.addCleanup(jointcalPatcher.stop) 

116 self.return_value = 100 

117 result = lsst.pipe.base.Struct(exitStatus=self.return_value, job=unittest.mock.Mock()) 

118 JointcalTask.return_value.runDataRef.return_value = result 

119 JointcalTask.return_value.log = unittest.mock.Mock() # jointcal.log is created in __init__ 

120 

121 return parsedArgs, JointcalTask 

122 

123 def testJointcalRunnerOneTract(self): 

124 parsedArgs, JointcalTask = self.prep_jointcal(tracts=[5]) 

125 runner = lsst.jointcal.JointcalRunner(JointcalTask, parsedArgs) 

126 result = runner.run(parsedArgs) 

127 self.assertEqual(result[0].exitStatus, self.return_value) 

128 JointcalTask.return_value.runDataRef.assert_called_once() 

129 

130 def testJointcalRunnerTwoTracts(self): 

131 parsedArgs, JointcalTask = self.prep_jointcal(tracts=[5, 6]) 

132 runner = lsst.jointcal.JointcalRunner(JointcalTask, parsedArgs) 

133 result = runner.run(parsedArgs) 

134 self.assertEqual(result[0].exitStatus, self.return_value) 

135 self.assertEqual(JointcalTask.return_value.runDataRef.call_count, 2) 

136 

137 def testJointcalRunnerThreeTracts(self): 

138 parsedArgs, JointcalTask = self.prep_jointcal(tracts=[5, 6, 7]) 

139 runner = lsst.jointcal.JointcalRunner(JointcalTask, parsedArgs) 

140 result = runner.run(parsedArgs) 

141 self.assertEqual(result[0].exitStatus, self.return_value) 

142 self.assertEqual(JointcalTask.return_value.runDataRef.call_count, 3) 

143 

144 

145class MemoryTester(lsst.utils.tests.MemoryTestCase): 

146 pass 

147 

148 

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

150 lsst.utils.tests.init() 

151 unittest.main()