matrixone-python-sdk 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- matrixone/__init__.py +155 -0
- matrixone/account.py +723 -0
- matrixone/async_client.py +3913 -0
- matrixone/async_metadata_manager.py +311 -0
- matrixone/async_orm.py +123 -0
- matrixone/async_vector_index_manager.py +633 -0
- matrixone/base_client.py +208 -0
- matrixone/client.py +4672 -0
- matrixone/config.py +452 -0
- matrixone/connection_hooks.py +286 -0
- matrixone/exceptions.py +89 -0
- matrixone/logger.py +782 -0
- matrixone/metadata.py +820 -0
- matrixone/moctl.py +219 -0
- matrixone/orm.py +2277 -0
- matrixone/pitr.py +646 -0
- matrixone/pubsub.py +771 -0
- matrixone/restore.py +411 -0
- matrixone/search_vector_index.py +1176 -0
- matrixone/snapshot.py +550 -0
- matrixone/sql_builder.py +844 -0
- matrixone/sqlalchemy_ext/__init__.py +161 -0
- matrixone/sqlalchemy_ext/adapters.py +163 -0
- matrixone/sqlalchemy_ext/dialect.py +534 -0
- matrixone/sqlalchemy_ext/fulltext_index.py +895 -0
- matrixone/sqlalchemy_ext/fulltext_search.py +1686 -0
- matrixone/sqlalchemy_ext/hnsw_config.py +194 -0
- matrixone/sqlalchemy_ext/ivf_config.py +252 -0
- matrixone/sqlalchemy_ext/table_builder.py +351 -0
- matrixone/sqlalchemy_ext/vector_index.py +1721 -0
- matrixone/sqlalchemy_ext/vector_type.py +948 -0
- matrixone/version.py +580 -0
- matrixone_python_sdk-0.1.0.dist-info/METADATA +706 -0
- matrixone_python_sdk-0.1.0.dist-info/RECORD +122 -0
- matrixone_python_sdk-0.1.0.dist-info/WHEEL +5 -0
- matrixone_python_sdk-0.1.0.dist-info/entry_points.txt +5 -0
- matrixone_python_sdk-0.1.0.dist-info/licenses/LICENSE +200 -0
- matrixone_python_sdk-0.1.0.dist-info/top_level.txt +2 -0
- tests/__init__.py +19 -0
- tests/offline/__init__.py +20 -0
- tests/offline/conftest.py +77 -0
- tests/offline/test_account.py +703 -0
- tests/offline/test_async_client_query_comprehensive.py +1218 -0
- tests/offline/test_basic.py +54 -0
- tests/offline/test_case_sensitivity.py +227 -0
- tests/offline/test_connection_hooks_offline.py +287 -0
- tests/offline/test_dialect_schema_handling.py +609 -0
- tests/offline/test_explain_methods.py +346 -0
- tests/offline/test_filter_logical_in.py +237 -0
- tests/offline/test_fulltext_search_comprehensive.py +795 -0
- tests/offline/test_ivf_config.py +249 -0
- tests/offline/test_join_methods.py +281 -0
- tests/offline/test_join_sqlalchemy_compatibility.py +276 -0
- tests/offline/test_logical_in_method.py +237 -0
- tests/offline/test_matrixone_version_parsing.py +264 -0
- tests/offline/test_metadata_offline.py +557 -0
- tests/offline/test_moctl.py +300 -0
- tests/offline/test_moctl_simple.py +251 -0
- tests/offline/test_model_support_offline.py +359 -0
- tests/offline/test_model_support_simple.py +225 -0
- tests/offline/test_pinecone_filter_offline.py +377 -0
- tests/offline/test_pitr.py +585 -0
- tests/offline/test_pubsub.py +712 -0
- tests/offline/test_query_update.py +283 -0
- tests/offline/test_restore.py +445 -0
- tests/offline/test_snapshot_comprehensive.py +384 -0
- tests/offline/test_sql_escaping_edge_cases.py +551 -0
- tests/offline/test_sqlalchemy_integration.py +382 -0
- tests/offline/test_sqlalchemy_vector_integration.py +434 -0
- tests/offline/test_table_builder.py +198 -0
- tests/offline/test_unified_filter.py +398 -0
- tests/offline/test_unified_transaction.py +495 -0
- tests/offline/test_vector_index.py +238 -0
- tests/offline/test_vector_operations.py +688 -0
- tests/offline/test_vector_type.py +174 -0
- tests/offline/test_version_core.py +328 -0
- tests/offline/test_version_management.py +372 -0
- tests/offline/test_version_standalone.py +652 -0
- tests/online/__init__.py +20 -0
- tests/online/conftest.py +216 -0
- tests/online/test_account_management.py +194 -0
- tests/online/test_advanced_features.py +344 -0
- tests/online/test_async_client_interfaces.py +330 -0
- tests/online/test_async_client_online.py +285 -0
- tests/online/test_async_model_insert_online.py +293 -0
- tests/online/test_async_orm_online.py +300 -0
- tests/online/test_async_simple_query_online.py +802 -0
- tests/online/test_async_transaction_simple_query.py +300 -0
- tests/online/test_basic_connection.py +130 -0
- tests/online/test_client_online.py +238 -0
- tests/online/test_config.py +90 -0
- tests/online/test_config_validation.py +123 -0
- tests/online/test_connection_hooks_new_online.py +217 -0
- tests/online/test_dialect_schema_handling_online.py +331 -0
- tests/online/test_filter_logical_in_online.py +374 -0
- tests/online/test_fulltext_comprehensive.py +1773 -0
- tests/online/test_fulltext_label_online.py +433 -0
- tests/online/test_fulltext_search_online.py +842 -0
- tests/online/test_ivf_stats_online.py +506 -0
- tests/online/test_logger_integration.py +311 -0
- tests/online/test_matrixone_query_orm.py +540 -0
- tests/online/test_metadata_online.py +579 -0
- tests/online/test_model_insert_online.py +255 -0
- tests/online/test_mysql_driver_validation.py +213 -0
- tests/online/test_orm_advanced_features.py +2022 -0
- tests/online/test_orm_cte_integration.py +269 -0
- tests/online/test_orm_online.py +270 -0
- tests/online/test_pinecone_filter.py +708 -0
- tests/online/test_pubsub_operations.py +352 -0
- tests/online/test_query_methods.py +225 -0
- tests/online/test_query_update_online.py +433 -0
- tests/online/test_search_vector_index.py +557 -0
- tests/online/test_simple_fulltext_online.py +915 -0
- tests/online/test_snapshot_comprehensive.py +998 -0
- tests/online/test_sqlalchemy_engine_integration.py +336 -0
- tests/online/test_sqlalchemy_integration.py +425 -0
- tests/online/test_transaction_contexts.py +1219 -0
- tests/online/test_transaction_insert_methods.py +356 -0
- tests/online/test_transaction_query_methods.py +288 -0
- tests/online/test_unified_filter_online.py +529 -0
- tests/online/test_vector_comprehensive.py +706 -0
- tests/online/test_version_management.py +291 -0
@@ -0,0 +1,445 @@
|
|
1
|
+
# Copyright 2021 - 2022 Matrix Origin
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
"""
|
16
|
+
Unit tests for RestoreManager
|
17
|
+
"""
|
18
|
+
|
19
|
+
import unittest
|
20
|
+
from unittest.mock import Mock, patch, AsyncMock
|
21
|
+
import sys
|
22
|
+
import os
|
23
|
+
|
24
|
+
# Add the matrixone package to the path
|
25
|
+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'matrixone'))
|
26
|
+
|
27
|
+
from matrixone import Client, AsyncClient, RestoreError
|
28
|
+
from matrixone.exceptions import RestoreError as RestoreErrorClass
|
29
|
+
from matrixone.restore import TransactionRestoreManager
|
30
|
+
|
31
|
+
|
32
|
+
class TestRestoreManager(unittest.TestCase):
|
33
|
+
"""Test cases for RestoreManager"""
|
34
|
+
|
35
|
+
def setUp(self):
|
36
|
+
"""Set up test fixtures"""
|
37
|
+
self.client = Client()
|
38
|
+
self.client._engine = Mock()
|
39
|
+
self.client._escape_identifier = lambda x: f"`{x}`"
|
40
|
+
# Initialize managers manually for testing
|
41
|
+
from matrixone.restore import RestoreManager
|
42
|
+
|
43
|
+
self.restore_manager = RestoreManager(self.client)
|
44
|
+
|
45
|
+
def test_restore_cluster_success(self):
|
46
|
+
"""Test successful cluster restore"""
|
47
|
+
# Mock successful execution
|
48
|
+
mock_result = Mock()
|
49
|
+
self.client.execute = Mock(return_value=mock_result)
|
50
|
+
|
51
|
+
# Test restore cluster
|
52
|
+
result = self.restore_manager.restore_cluster("cluster_snapshot_1")
|
53
|
+
|
54
|
+
# Verify
|
55
|
+
self.assertTrue(result)
|
56
|
+
self.client.execute.assert_called_once_with("RESTORE CLUSTER FROM SNAPSHOT `cluster_snapshot_1`")
|
57
|
+
|
58
|
+
def test_restore_cluster_failure(self):
|
59
|
+
"""Test cluster restore failure"""
|
60
|
+
# Mock execution failure
|
61
|
+
self.client.execute = Mock(side_effect=Exception("Connection failed"))
|
62
|
+
|
63
|
+
# Test restore cluster failure
|
64
|
+
with self.assertRaises(RestoreErrorClass):
|
65
|
+
self.restore_manager.restore_cluster("cluster_snapshot_1")
|
66
|
+
|
67
|
+
def test_restore_tenant_success(self):
|
68
|
+
"""Test successful tenant restore"""
|
69
|
+
# Mock successful execution
|
70
|
+
mock_result = Mock()
|
71
|
+
self.client.execute = Mock(return_value=mock_result)
|
72
|
+
|
73
|
+
# Test restore tenant to itself
|
74
|
+
result = self.restore_manager.restore_tenant("acc1_snap1", "acc1")
|
75
|
+
|
76
|
+
# Verify
|
77
|
+
self.assertTrue(result)
|
78
|
+
self.client.execute.assert_called_once_with("RESTORE ACCOUNT `acc1` FROM SNAPSHOT `acc1_snap1`")
|
79
|
+
|
80
|
+
def test_restore_tenant_to_new_tenant(self):
|
81
|
+
"""Test restore tenant to new tenant"""
|
82
|
+
# Mock successful execution
|
83
|
+
mock_result = Mock()
|
84
|
+
self.client.execute = Mock(return_value=mock_result)
|
85
|
+
|
86
|
+
# Test restore tenant to new tenant
|
87
|
+
result = self.restore_manager.restore_tenant("acc1_snap1", "acc1", "acc2")
|
88
|
+
|
89
|
+
# Verify
|
90
|
+
self.assertTrue(result)
|
91
|
+
self.client.execute.assert_called_once_with("RESTORE ACCOUNT `acc1` FROM SNAPSHOT `acc1_snap1` TO ACCOUNT `acc2`")
|
92
|
+
|
93
|
+
def test_restore_tenant_failure(self):
|
94
|
+
"""Test tenant restore failure"""
|
95
|
+
# Mock execution failure
|
96
|
+
self.client.execute = Mock(side_effect=Exception("Permission denied"))
|
97
|
+
|
98
|
+
# Test restore tenant failure
|
99
|
+
with self.assertRaises(RestoreErrorClass):
|
100
|
+
self.restore_manager.restore_tenant("acc1_snap1", "acc1")
|
101
|
+
|
102
|
+
def test_restore_database_success(self):
|
103
|
+
"""Test successful database restore"""
|
104
|
+
# Mock successful execution
|
105
|
+
mock_result = Mock()
|
106
|
+
self.client.execute = Mock(return_value=mock_result)
|
107
|
+
|
108
|
+
# Test restore database
|
109
|
+
result = self.restore_manager.restore_database("acc1_db_snap1", "acc1", "db1")
|
110
|
+
|
111
|
+
# Verify
|
112
|
+
self.assertTrue(result)
|
113
|
+
self.client.execute.assert_called_once_with("RESTORE ACCOUNT `acc1` DATABASE `db1` FROM SNAPSHOT `acc1_db_snap1`")
|
114
|
+
|
115
|
+
def test_restore_database_to_new_tenant(self):
|
116
|
+
"""Test restore database to new tenant"""
|
117
|
+
# Mock successful execution
|
118
|
+
mock_result = Mock()
|
119
|
+
self.client.execute = Mock(return_value=mock_result)
|
120
|
+
|
121
|
+
# Test restore database to new tenant
|
122
|
+
result = self.restore_manager.restore_database("acc1_db_snap1", "acc1", "db1", "acc2")
|
123
|
+
|
124
|
+
# Verify
|
125
|
+
self.assertTrue(result)
|
126
|
+
self.client.execute.assert_called_once_with(
|
127
|
+
"RESTORE ACCOUNT `acc1` DATABASE `db1` FROM SNAPSHOT `acc1_db_snap1` TO ACCOUNT `acc2`"
|
128
|
+
)
|
129
|
+
|
130
|
+
def test_restore_database_failure(self):
|
131
|
+
"""Test database restore failure"""
|
132
|
+
# Mock execution failure
|
133
|
+
self.client.execute = Mock(side_effect=Exception("Database not found"))
|
134
|
+
|
135
|
+
# Test restore database failure
|
136
|
+
with self.assertRaises(RestoreErrorClass):
|
137
|
+
self.restore_manager.restore_database("acc1_db_snap1", "acc1", "db1")
|
138
|
+
|
139
|
+
def test_restore_table_success(self):
|
140
|
+
"""Test successful table restore"""
|
141
|
+
# Mock successful execution
|
142
|
+
mock_result = Mock()
|
143
|
+
self.client.execute = Mock(return_value=mock_result)
|
144
|
+
|
145
|
+
# Test restore table
|
146
|
+
result = self.restore_manager.restore_table("acc1_tab_snap1", "acc1", "db1", "t1")
|
147
|
+
|
148
|
+
# Verify
|
149
|
+
self.assertTrue(result)
|
150
|
+
self.client.execute.assert_called_once_with(
|
151
|
+
"RESTORE ACCOUNT `acc1` DATABASE `db1` TABLE `t1` FROM SNAPSHOT `acc1_tab_snap1`"
|
152
|
+
)
|
153
|
+
|
154
|
+
def test_restore_table_to_new_tenant(self):
|
155
|
+
"""Test restore table to new tenant"""
|
156
|
+
# Mock successful execution
|
157
|
+
mock_result = Mock()
|
158
|
+
self.client.execute = Mock(return_value=mock_result)
|
159
|
+
|
160
|
+
# Test restore table to new tenant
|
161
|
+
result = self.restore_manager.restore_table("acc1_tab_snap1", "acc1", "db1", "t1", "acc2")
|
162
|
+
|
163
|
+
# Verify
|
164
|
+
self.assertTrue(result)
|
165
|
+
self.client.execute.assert_called_once_with(
|
166
|
+
"RESTORE ACCOUNT `acc1` DATABASE `db1` TABLE `t1` FROM SNAPSHOT `acc1_tab_snap1` TO ACCOUNT `acc2`"
|
167
|
+
)
|
168
|
+
|
169
|
+
def test_restore_table_failure(self):
|
170
|
+
"""Test table restore failure"""
|
171
|
+
# Mock execution failure
|
172
|
+
self.client.execute = Mock(side_effect=Exception("Table not found"))
|
173
|
+
|
174
|
+
# Test restore table failure
|
175
|
+
with self.assertRaises(RestoreErrorClass):
|
176
|
+
self.restore_manager.restore_table("acc1_tab_snap1", "acc1", "db1", "t1")
|
177
|
+
|
178
|
+
def test_restore_with_executor_cluster(self):
|
179
|
+
"""Test restore cluster with custom executor"""
|
180
|
+
# Mock executor
|
181
|
+
mock_executor = Mock()
|
182
|
+
mock_result = Mock()
|
183
|
+
mock_executor.execute = Mock(return_value=mock_result)
|
184
|
+
|
185
|
+
# Test restore cluster with executor
|
186
|
+
result = self.restore_manager.restore_with_executor('cluster', 'cluster_snap1', executor=mock_executor)
|
187
|
+
|
188
|
+
# Verify
|
189
|
+
self.assertTrue(result)
|
190
|
+
mock_executor.execute.assert_called_once_with("RESTORE CLUSTER FROM SNAPSHOT `cluster_snap1`")
|
191
|
+
|
192
|
+
def test_restore_with_executor_tenant(self):
|
193
|
+
"""Test restore tenant with custom executor"""
|
194
|
+
# Mock executor
|
195
|
+
mock_executor = Mock()
|
196
|
+
mock_result = Mock()
|
197
|
+
mock_executor.execute = Mock(return_value=mock_result)
|
198
|
+
|
199
|
+
# Test restore tenant with executor
|
200
|
+
result = self.restore_manager.restore_with_executor(
|
201
|
+
'tenant', 'acc1_snap1', account_name='acc1', executor=mock_executor
|
202
|
+
)
|
203
|
+
|
204
|
+
# Verify
|
205
|
+
self.assertTrue(result)
|
206
|
+
mock_executor.execute.assert_called_once_with("RESTORE ACCOUNT `acc1` FROM SNAPSHOT `acc1_snap1`")
|
207
|
+
|
208
|
+
def test_restore_with_executor_database(self):
|
209
|
+
"""Test restore database with custom executor"""
|
210
|
+
# Mock executor
|
211
|
+
mock_executor = Mock()
|
212
|
+
mock_result = Mock()
|
213
|
+
mock_executor.execute = Mock(return_value=mock_result)
|
214
|
+
|
215
|
+
# Test restore database with executor
|
216
|
+
result = self.restore_manager.restore_with_executor(
|
217
|
+
'database',
|
218
|
+
'acc1_db_snap1',
|
219
|
+
account_name='acc1',
|
220
|
+
database_name='db1',
|
221
|
+
executor=mock_executor,
|
222
|
+
)
|
223
|
+
|
224
|
+
# Verify
|
225
|
+
self.assertTrue(result)
|
226
|
+
mock_executor.execute.assert_called_once_with("RESTORE ACCOUNT `acc1` DATABASE `db1` FROM SNAPSHOT `acc1_db_snap1`")
|
227
|
+
|
228
|
+
def test_restore_with_executor_table(self):
|
229
|
+
"""Test restore table with custom executor"""
|
230
|
+
# Mock executor
|
231
|
+
mock_executor = Mock()
|
232
|
+
mock_result = Mock()
|
233
|
+
mock_executor.execute = Mock(return_value=mock_result)
|
234
|
+
|
235
|
+
# Test restore table with executor
|
236
|
+
result = self.restore_manager.restore_with_executor(
|
237
|
+
'table',
|
238
|
+
'acc1_tab_snap1',
|
239
|
+
account_name='acc1',
|
240
|
+
database_name='db1',
|
241
|
+
table_name='t1',
|
242
|
+
executor=mock_executor,
|
243
|
+
)
|
244
|
+
|
245
|
+
# Verify
|
246
|
+
self.assertTrue(result)
|
247
|
+
mock_executor.execute.assert_called_once_with(
|
248
|
+
"RESTORE ACCOUNT `acc1` DATABASE `db1` TABLE `t1` FROM SNAPSHOT `acc1_tab_snap1`"
|
249
|
+
)
|
250
|
+
|
251
|
+
def test_restore_with_executor_invalid_type(self):
|
252
|
+
"""Test restore with invalid type"""
|
253
|
+
# Test invalid restore type
|
254
|
+
with self.assertRaises(RestoreErrorClass):
|
255
|
+
self.restore_manager.restore_with_executor('invalid', 'snap1')
|
256
|
+
|
257
|
+
def test_restore_with_executor_missing_params(self):
|
258
|
+
"""Test restore with missing required parameters"""
|
259
|
+
# Test missing account name for tenant restore
|
260
|
+
with self.assertRaises(RestoreErrorClass):
|
261
|
+
self.restore_manager.restore_with_executor('tenant', 'snap1')
|
262
|
+
|
263
|
+
# Test missing database name for database restore
|
264
|
+
with self.assertRaises(RestoreErrorClass):
|
265
|
+
self.restore_manager.restore_with_executor('database', 'snap1', account_name='acc1')
|
266
|
+
|
267
|
+
# Test missing table name for table restore
|
268
|
+
with self.assertRaises(RestoreErrorClass):
|
269
|
+
self.restore_manager.restore_with_executor('table', 'snap1', account_name='acc1', database_name='db1')
|
270
|
+
|
271
|
+
|
272
|
+
class TestAsyncRestoreManager(unittest.IsolatedAsyncioTestCase):
|
273
|
+
"""Test cases for AsyncRestoreManager"""
|
274
|
+
|
275
|
+
async def asyncSetUp(self):
|
276
|
+
"""Set up async test fixtures"""
|
277
|
+
self.client = AsyncClient()
|
278
|
+
self.client._engine = Mock()
|
279
|
+
self.client._escape_identifier = lambda x: f"`{x}`"
|
280
|
+
# Initialize managers manually for testing
|
281
|
+
from matrixone.async_client import AsyncRestoreManager
|
282
|
+
|
283
|
+
self.restore_manager = AsyncRestoreManager(self.client)
|
284
|
+
|
285
|
+
async def test_async_restore_cluster_success(self):
|
286
|
+
"""Test successful async cluster restore"""
|
287
|
+
# Mock successful execution
|
288
|
+
mock_result = Mock()
|
289
|
+
self.client.execute = AsyncMock(return_value=mock_result)
|
290
|
+
|
291
|
+
# Test restore cluster
|
292
|
+
result = await self.restore_manager.restore_cluster("cluster_snapshot_1")
|
293
|
+
|
294
|
+
# Verify
|
295
|
+
self.assertTrue(result)
|
296
|
+
self.client.execute.assert_called_once_with("RESTORE CLUSTER FROM SNAPSHOT `cluster_snapshot_1`")
|
297
|
+
|
298
|
+
async def test_async_restore_cluster_failure(self):
|
299
|
+
"""Test async cluster restore failure"""
|
300
|
+
# Mock execution failure
|
301
|
+
self.client.execute = AsyncMock(side_effect=Exception("Connection failed"))
|
302
|
+
|
303
|
+
# Test restore cluster failure
|
304
|
+
with self.assertRaises(RestoreErrorClass):
|
305
|
+
await self.restore_manager.restore_cluster("cluster_snapshot_1")
|
306
|
+
|
307
|
+
async def test_async_restore_tenant_success(self):
|
308
|
+
"""Test successful async tenant restore"""
|
309
|
+
# Mock successful execution
|
310
|
+
mock_result = Mock()
|
311
|
+
self.client.execute = AsyncMock(return_value=mock_result)
|
312
|
+
|
313
|
+
# Test restore tenant
|
314
|
+
result = await self.restore_manager.restore_tenant("acc1_snap1", "acc1")
|
315
|
+
|
316
|
+
# Verify
|
317
|
+
self.assertTrue(result)
|
318
|
+
self.client.execute.assert_called_once_with("RESTORE ACCOUNT `acc1` FROM SNAPSHOT `acc1_snap1`")
|
319
|
+
|
320
|
+
async def test_async_restore_tenant_to_new_tenant(self):
|
321
|
+
"""Test async restore tenant to new tenant"""
|
322
|
+
# Mock successful execution
|
323
|
+
mock_result = Mock()
|
324
|
+
self.client.execute = AsyncMock(return_value=mock_result)
|
325
|
+
|
326
|
+
# Test restore tenant to new tenant
|
327
|
+
result = await self.restore_manager.restore_tenant("acc1_snap1", "acc1", "acc2")
|
328
|
+
|
329
|
+
# Verify
|
330
|
+
self.assertTrue(result)
|
331
|
+
self.client.execute.assert_called_once_with("RESTORE ACCOUNT `acc1` FROM SNAPSHOT `acc1_snap1` TO ACCOUNT `acc2`")
|
332
|
+
|
333
|
+
async def test_async_restore_database_success(self):
|
334
|
+
"""Test successful async database restore"""
|
335
|
+
# Mock successful execution
|
336
|
+
mock_result = Mock()
|
337
|
+
self.client.execute = AsyncMock(return_value=mock_result)
|
338
|
+
|
339
|
+
# Test restore database
|
340
|
+
result = await self.restore_manager.restore_database("acc1_db_snap1", "acc1", "db1")
|
341
|
+
|
342
|
+
# Verify
|
343
|
+
self.assertTrue(result)
|
344
|
+
self.client.execute.assert_called_once_with("RESTORE ACCOUNT `acc1` DATABASE `db1` FROM SNAPSHOT `acc1_db_snap1`")
|
345
|
+
|
346
|
+
async def test_async_restore_table_success(self):
|
347
|
+
"""Test successful async table restore"""
|
348
|
+
# Mock successful execution
|
349
|
+
mock_result = Mock()
|
350
|
+
self.client.execute = AsyncMock(return_value=mock_result)
|
351
|
+
|
352
|
+
# Test restore table
|
353
|
+
result = await self.restore_manager.restore_table("acc1_tab_snap1", "acc1", "db1", "t1")
|
354
|
+
|
355
|
+
# Verify
|
356
|
+
self.assertTrue(result)
|
357
|
+
self.client.execute.assert_called_once_with(
|
358
|
+
"RESTORE ACCOUNT `acc1` DATABASE `db1` TABLE `t1` FROM SNAPSHOT `acc1_tab_snap1`"
|
359
|
+
)
|
360
|
+
|
361
|
+
|
362
|
+
class TestTransactionRestoreManager(unittest.TestCase):
|
363
|
+
"""Test cases for TransactionRestoreManager"""
|
364
|
+
|
365
|
+
def setUp(self):
|
366
|
+
"""Set up test fixtures"""
|
367
|
+
self.client = Client()
|
368
|
+
self.client._engine = Mock()
|
369
|
+
self.client._escape_identifier = lambda x: f"`{x}`"
|
370
|
+
self.transaction_wrapper = Mock()
|
371
|
+
self.transaction_restore_manager = TransactionRestoreManager(self.client, self.transaction_wrapper)
|
372
|
+
|
373
|
+
def test_transaction_restore_cluster(self):
|
374
|
+
"""Test restore cluster within transaction"""
|
375
|
+
# Mock successful execution
|
376
|
+
mock_result = Mock()
|
377
|
+
self.transaction_wrapper.execute = Mock(return_value=mock_result)
|
378
|
+
|
379
|
+
# Test restore cluster
|
380
|
+
result = self.transaction_restore_manager.restore_cluster("cluster_snap1")
|
381
|
+
|
382
|
+
# Verify
|
383
|
+
self.assertTrue(result)
|
384
|
+
self.transaction_wrapper.execute.assert_called_once_with("RESTORE CLUSTER FROM SNAPSHOT `cluster_snap1`")
|
385
|
+
|
386
|
+
def test_transaction_restore_tenant(self):
|
387
|
+
"""Test restore tenant within transaction"""
|
388
|
+
# Mock successful execution
|
389
|
+
mock_result = Mock()
|
390
|
+
self.transaction_wrapper.execute = Mock(return_value=mock_result)
|
391
|
+
|
392
|
+
# Test restore tenant
|
393
|
+
result = self.transaction_restore_manager.restore_tenant("acc1_snap1", "acc1")
|
394
|
+
|
395
|
+
# Verify
|
396
|
+
self.assertTrue(result)
|
397
|
+
self.transaction_wrapper.execute.assert_called_once_with("RESTORE ACCOUNT `acc1` FROM SNAPSHOT `acc1_snap1`")
|
398
|
+
|
399
|
+
def test_transaction_restore_database(self):
|
400
|
+
"""Test restore database within transaction"""
|
401
|
+
# Mock successful execution
|
402
|
+
mock_result = Mock()
|
403
|
+
self.transaction_wrapper.execute = Mock(return_value=mock_result)
|
404
|
+
|
405
|
+
# Test restore database
|
406
|
+
result = self.transaction_restore_manager.restore_database("acc1_db_snap1", "acc1", "db1")
|
407
|
+
|
408
|
+
# Verify
|
409
|
+
self.assertTrue(result)
|
410
|
+
self.transaction_wrapper.execute.assert_called_once_with(
|
411
|
+
"RESTORE ACCOUNT `acc1` DATABASE `db1` FROM SNAPSHOT `acc1_db_snap1`"
|
412
|
+
)
|
413
|
+
|
414
|
+
def test_transaction_restore_table(self):
|
415
|
+
"""Test restore table within transaction"""
|
416
|
+
# Mock successful execution
|
417
|
+
mock_result = Mock()
|
418
|
+
self.transaction_wrapper.execute = Mock(return_value=mock_result)
|
419
|
+
|
420
|
+
# Test restore table
|
421
|
+
result = self.transaction_restore_manager.restore_table("acc1_tab_snap1", "acc1", "db1", "t1")
|
422
|
+
|
423
|
+
# Verify
|
424
|
+
self.assertTrue(result)
|
425
|
+
self.transaction_wrapper.execute.assert_called_once_with(
|
426
|
+
"RESTORE ACCOUNT `acc1` DATABASE `db1` TABLE `t1` FROM SNAPSHOT `acc1_tab_snap1`"
|
427
|
+
)
|
428
|
+
|
429
|
+
|
430
|
+
if __name__ == '__main__':
|
431
|
+
# Create test suite
|
432
|
+
loader = unittest.TestLoader()
|
433
|
+
suite = unittest.TestSuite()
|
434
|
+
|
435
|
+
# Add test cases
|
436
|
+
suite.addTests(loader.loadTestsFromTestCase(TestRestoreManager))
|
437
|
+
suite.addTests(loader.loadTestsFromTestCase(TestAsyncRestoreManager))
|
438
|
+
suite.addTests(loader.loadTestsFromTestCase(TestTransactionRestoreManager))
|
439
|
+
|
440
|
+
# Run tests
|
441
|
+
runner = unittest.TextTestRunner(verbosity=2)
|
442
|
+
result = runner.run(suite)
|
443
|
+
|
444
|
+
# Exit with appropriate code
|
445
|
+
sys.exit(0 if result.wasSuccessful() else 1)
|