Coverage for tests/test_apdbCassandra.py: 46%

81 statements  

« prev     ^ index     » next       coverage.py v7.4.0, created at 2024-01-24 10:51 +0000

1# This file is part of dax_apdb. 

2# 

3# Developed for the LSST Data Management System. 

4# This product includes software developed by the LSST Project 

5# (http://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"""Unit test for `ApdbCassandra` class. 

23 

24Notes 

25----- 

26For now this test can only run against actual Cassandra cluster, to specify 

27cluster location use ``DAX_APDB_TEST_CASSANDRA_CLUSTER`` environment variable, 

28e.g.: 

29 

30 export DAX_APDB_TEST_CASSANDRA_CLUSTER=cassandra.example.com 

31 pytest tests/test_apdbCassandra.py 

32 

33Individual tests create and destroy unique keyspaces in the cluster, there is 

34no need to pre-create a keyspace with predefined name. 

35""" 

36 

37import logging 

38import os 

39import unittest 

40import uuid 

41from typing import TYPE_CHECKING, Any 

42 

43try: 

44 from cassandra.cluster import EXEC_PROFILE_DEFAULT, Cluster, ExecutionProfile 

45 from cassandra.policies import RoundRobinPolicy 

46 

47 CASSANDRA_IMPORTED = True 

48except ImportError: 

49 CASSANDRA_IMPORTED = False 

50 

51import lsst.utils.tests 

52from lsst.dax.apdb import ApdbCassandraConfig, ApdbTables 

53from lsst.dax.apdb.apdbCassandra import CASSANDRA_IMPORTED 

54from lsst.dax.apdb.tests import ApdbSchemaUpdateTest, ApdbTest 

55 

56TEST_SCHEMA = os.path.join(os.path.abspath(os.path.dirname(__file__)), "config/schema.yaml") 

57 

58logging.basicConfig(level=logging.INFO) 

59 

60 

61class ApdbCassandraMixin: 

62 """Mixin class which defines common methods for unit tests.""" 

63 

64 @classmethod 

65 def setUpClass(cls) -> None: 

66 """Prepare config for server connection.""" 

67 if not CASSANDRA_IMPORTED: 

68 raise unittest.SkipTest("FAiled to import Cassandra modules") 

69 cluster_host = os.environ.get("DAX_APDB_TEST_CASSANDRA_CLUSTER") 

70 if not cluster_host: 

71 raise unittest.SkipTest("DAX_APDB_TEST_CASSANDRA_CLUSTER is not set") 

72 if not CASSANDRA_IMPORTED: 

73 raise unittest.SkipTest("cassandra_driver cannot be imported") 

74 

75 def _run_query(self, query: str) -> None: 

76 # Used protocol version from default config. 

77 config = ApdbCassandraConfig() 

78 default_profile = ExecutionProfile(load_balancing_policy=RoundRobinPolicy()) 

79 profiles = {EXEC_PROFILE_DEFAULT: default_profile} 

80 cluster = Cluster( 

81 contact_points=[self.cluster_host], 

82 execution_profiles=profiles, 

83 protocol_version=config.protocol_version, 

84 ) 

85 session = cluster.connect() 

86 session.execute(query) 

87 del session 

88 cluster.shutdown() 

89 

90 def setUp(self) -> None: 

91 """Prepare config for server connection.""" 

92 self.cluster_host = os.environ.get("DAX_APDB_TEST_CASSANDRA_CLUSTER") 

93 

94 # create dedicated keyspace for each test 

95 key = uuid.uuid4() 

96 self.keyspace = f"apdb_{key.hex}" 

97 query = ( 

98 f"CREATE KEYSPACE {self.keyspace}" 

99 " WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}" 

100 ) 

101 self._run_query(query) 

102 

103 def tearDown(self) -> None: 

104 query = f"DROP KEYSPACE {self.keyspace}" 

105 self._run_query(query) 

106 

107 if TYPE_CHECKING: 107 ↛ 109line 107 didn't jump to line 109, because the condition on line 107 was never true

108 # For mypy. 

109 def make_config(self, **kwargs: Any) -> ApdbCassandraConfig: 

110 ... 

111 

112 

113class ApdbCassandraTestCase(ApdbCassandraMixin, ApdbTest, unittest.TestCase): 

114 """A test case for ApdbCassandra class""" 

115 

116 allow_visit_query = False 

117 time_partition_tables = False 

118 time_partition_start: str | None = None 

119 time_partition_end: str | None = None 

120 

121 def make_config(self, **kwargs: Any) -> ApdbCassandraConfig: 

122 """Make config class instance used in all tests.""" 

123 kw = { 

124 "contact_points": [self.cluster_host], 

125 "keyspace": self.keyspace, 

126 "schema_file": TEST_SCHEMA, 

127 "time_partition_tables": self.time_partition_tables, 

128 "use_insert_id": self.use_insert_id, 

129 } 

130 if self.time_partition_start: 

131 kw["time_partition_start"] = self.time_partition_start 

132 if self.time_partition_end: 

133 kw["time_partition_end"] = self.time_partition_end 

134 kw.update(kwargs) 

135 return ApdbCassandraConfig(**kw) 

136 

137 def getDiaObjects_table(self) -> ApdbTables: 

138 """Return type of table returned from getDiaObjects method.""" 

139 return ApdbTables.DiaObjectLast 

140 

141 

142class ApdbCassandraPerMonthTestCase(ApdbCassandraTestCase): 

143 """A test case for ApdbCassandra class with per-month tables.""" 

144 

145 time_partition_tables = True 

146 time_partition_start = "2019-12-01T00:00:00" 

147 time_partition_end = "2022-01-01T00:00:00" 

148 

149 

150class ApdbCassandraTestCaseInsertIds(ApdbCassandraTestCase): 

151 """A test case with use_insert_id.""" 

152 

153 use_insert_id = True 

154 

155 

156class ApdbSchemaUpdateCassandraTestCase(ApdbCassandraMixin, ApdbSchemaUpdateTest, unittest.TestCase): 

157 """A test case for schema updates using Cassandra backend.""" 

158 

159 def make_config(self, **kwargs: Any) -> ApdbCassandraConfig: 

160 """Make config class instance used in all tests.""" 

161 kw = { 

162 "contact_points": [self.cluster_host], 

163 "keyspace": self.keyspace, 

164 "schema_file": TEST_SCHEMA, 

165 "time_partition_tables": False, 

166 } 

167 kw.update(kwargs) 

168 return ApdbCassandraConfig(**kw) 

169 

170 

171class MyMemoryTestCase(lsst.utils.tests.MemoryTestCase): 

172 """Run file leak tests.""" 

173 

174 

175def setup_module(module: Any) -> None: 

176 """Configure pytest.""" 

177 lsst.utils.tests.init() 

178 

179 

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

181 lsst.utils.tests.init() 

182 unittest.main()