Coverage for tests/test_simple.py: 15%

90 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-03-20 03:38 -0700

1# This file is part of felis. 

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 

23import unittest 

24from collections.abc import Iterable, MutableMapping, Sequence 

25from typing import Any 

26 

27import yaml 

28 

29from felis import DEFAULT_FRAME, types 

30from felis.simple import ForeignKeyConstraint, SimpleVisitor, UniqueConstraint 

31 

32TESTDIR = os.path.abspath(os.path.dirname(__file__)) 

33TEST_YAML = os.path.join(TESTDIR, "data", "test.yml") 

34 

35 

36def _names(items: Iterable) -> Sequence[str]: 

37 """Return names of items.""" 

38 return [item.name for item in items] 

39 

40 

41class VisitorTestCase(unittest.TestCase): 

42 """Tests for both SimpleVisitor classes.""" 

43 

44 schema_obj: MutableMapping[str, Any] = {} 

45 

46 def setUp(self) -> None: 

47 """Load data from test file.""" 

48 with open(TEST_YAML) as test_yaml: 

49 self.schema_obj = yaml.load(test_yaml, Loader=yaml.SafeLoader) 

50 self.schema_obj.update(DEFAULT_FRAME) 

51 

52 def test_schema(self) -> None: 

53 """Check schema generated by SimpleVisitor class.""" 

54 visitor = SimpleVisitor() 

55 schema = visitor.visit_schema(self.schema_obj) 

56 

57 self.assertIsNotNone(schema) 

58 self.assertEqual(schema.name, "sdqa") 

59 

60 self.assertIsNotNone(schema.version) 

61 assert schema.version is not None, "cannot be None" 

62 self.assertEqual(schema.version.current, "1.2.3") 

63 assert schema.version.compatible is not None, "cannot be None" 

64 self.assertEqual(set(schema.version.compatible), {"1.2.0", "1.2.1", "1.2.2"}) 

65 assert schema.version.read_compatible is not None, "cannot be None" 

66 self.assertEqual(set(schema.version.read_compatible), {"1.1.0", "1.1.1"}) 

67 

68 self.assertIsNotNone(schema.tables) 

69 table_names = [ 

70 "sdqa_ImageStatus", 

71 "sdqa_Metric", 

72 "sdqa_Rating_ForAmpVisit", 

73 "sdqa_Rating_CcdVisit", 

74 "sdqa_Threshold", 

75 ] 

76 

77 # Check schema.tables attribute. 

78 self.assertCountEqual(set(_names(schema.tables)), set(table_names)) 

79 

80 tables = {table.name: table for table in schema.tables} 

81 

82 # Details of sdqa_ImageStatus table. 

83 table = tables["sdqa_ImageStatus"] 

84 self.assertEqual(_names(table.columns), ["sdqa_imageStatusId", "statusName", "definition"]) 

85 self.assertEqual( 

86 [column.datatype for column in table.columns], [types.Short, types.String, types.String] 

87 ) 

88 self.assertEqual([column.length for column in table.columns], [None, 30, 255]) 

89 self.assertEqual( 

90 [column.annotations for column in table.columns], 

91 [ 

92 {"mysql:datatype": "SMALLINT", "tap:principal": 1}, 

93 {"mysql:datatype": "VARCHAR(30)"}, 

94 {"mysql:datatype": "VARCHAR(255)"}, 

95 ], 

96 ) 

97 self.assertEqual(_names(table.primary_key), ["sdqa_imageStatusId"]) 

98 self.assertFalse(table.indexes) 

99 self.assertEqual(table.annotations, {"mysql:engine": "MyISAM", "tap:table_index": 1}) 

100 

101 # Details of sdqa_Metric table. 

102 table = tables["sdqa_Metric"] 

103 self.assertEqual( 

104 _names(table.columns), ["sdqa_metricId", "metricName", "physicalUnits", "dataType", "definition"] 

105 ) 

106 self.assertEqual( 

107 [column.datatype for column in table.columns], 

108 [types.Short, types.String, types.String, types.Char, types.String], 

109 ) 

110 self.assertEqual([column.length for column in table.columns], [None, 30, 30, 1, 255]) 

111 self.assertEqual(_names(table.primary_key), ["sdqa_metricId"]) 

112 self.assertFalse(table.indexes) 

113 self.assertEqual(table.annotations, {"mysql:engine": "MyISAM", "tap:table_index": 2}) 

114 

115 # It defines a unique constraint. 

116 self.assertEqual(len(table.constraints), 1) 

117 constraint = table.constraints[0] 

118 self.assertIsInstance(constraint, UniqueConstraint) 

119 assert isinstance(constraint, UniqueConstraint) # for mypy 

120 self.assertEqual(constraint.name, "UQ_sdqaMetric_metricName") 

121 self.assertEqual(_names(constraint.columns), ["metricName"]) 

122 self.assertEqual(constraint.annotations, {}) 

123 

124 # Details of sdqa_Rating_ForAmpVisit table. 

125 table = tables["sdqa_Rating_ForAmpVisit"] 

126 self.assertEqual( 

127 _names(table.columns), 

128 [ 

129 "sdqa_ratingId", 

130 "sdqa_metricId", 

131 "sdqa_thresholdId", 

132 "ampVisitId", 

133 "metricValue", 

134 "metricSigma", 

135 ], 

136 ) 

137 self.assertEqual(_names(table.primary_key), ["sdqa_ratingId"]) 

138 self.assertEqual( 

139 [column.datatype for column in table.columns], 

140 [types.Long, types.Short, types.Short, types.Long, types.Double, types.Double], 

141 ) 

142 self.assertEqual(table.annotations, {"mysql:engine": "MyISAM", "tap:table_index": 3}) 

143 

144 # constraints 

145 self.assertEqual(len(table.constraints), 2) 

146 constraint = table.constraints[0] 

147 self.assertIsInstance(constraint, UniqueConstraint) 

148 assert isinstance(constraint, UniqueConstraint) # for mypy 

149 self.assertEqual(constraint.name, "UQ_sdqaRatingForAmpVisit_metricId_ampVisitId") 

150 self.assertEqual(_names(constraint.columns), ["sdqa_metricId", "ampVisitId"]) 

151 self.assertEqual(constraint.annotations, {}) 

152 constraint = table.constraints[1] 

153 self.assertIsInstance(constraint, ForeignKeyConstraint) 

154 assert isinstance(constraint, ForeignKeyConstraint) # for mypy 

155 self.assertEqual(constraint.name, "FK_sdqa_Rating_ForAmpVisit_sdqa_Metric") 

156 self.assertEqual(_names(constraint.columns), ["sdqa_metricId"]) 

157 self.assertEqual(_names(constraint.referenced_columns), ["sdqa_metricId"]) 

158 self.assertIs(constraint.referenced_columns[0].table, tables["sdqa_Metric"]) 

159 self.assertEqual(constraint.annotations, {}) 

160 

161 # It has a bunch of indices. 

162 self.assertEqual(len(table.indexes), 3) 

163 index = table.indexes[0] 

164 self.assertEqual(index.name, "IDX_sdqaRatingForAmpVisit_metricId") 

165 self.assertEqual(_names(index.columns), ["sdqa_metricId"]) 

166 self.assertEqual(index.annotations, {}) 

167 index = table.indexes[1] 

168 self.assertEqual(index.name, "IDX_sdqaRatingForAmpVisit_thresholdId") 

169 self.assertEqual(_names(index.columns), ["sdqa_thresholdId"]) 

170 self.assertEqual(index.annotations, {}) 

171 index = table.indexes[2] 

172 self.assertEqual(index.name, "IDX_sdqaRatingForAmpVisit_ampVisitId") 

173 self.assertEqual(_names(index.columns), ["ampVisitId"]) 

174 self.assertEqual(index.annotations, {}) 

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()