|
17 | 17 | from concurrent.futures import ThreadPoolExecutor |
18 | 18 | from unittest.mock import Mock, ANY, call |
19 | 19 |
|
20 | | -from cassandra import OperationTimedOut, SchemaTargetType, SchemaChangeType |
| 20 | +from cassandra import OperationTimedOut, SchemaTargetType, SchemaChangeType, ConsistencyLevel |
21 | 21 | from cassandra.protocol import ResultMessage, RESULT_KIND_ROWS, QueryMessage |
22 | 22 | from cassandra.cluster import ControlConnection, _Scheduler, ProfileManager, EXEC_PROFILE_DEFAULT, ExecutionProfile |
23 | 23 | from cassandra.pool import Host |
@@ -323,6 +323,54 @@ def test_topology_queries_use_paging(self): |
323 | 323 | assert isinstance(query_msg, QueryMessage) |
324 | 324 | assert query_msg.fetch_size == self.control_connection._schema_meta_page_size |
325 | 325 |
|
| 326 | + def test_topology_queries_fetch_all_pages(self): |
| 327 | + """ |
| 328 | + Test that topology queries fetch all pages when results are paged |
| 329 | + """ |
| 330 | + from unittest.mock import MagicMock |
| 331 | + |
| 332 | + # Create mock connection |
| 333 | + mock_connection = MagicMock() |
| 334 | + mock_connection.endpoint = DefaultEndPoint("192.168.1.0") |
| 335 | + mock_connection.original_endpoint = mock_connection.endpoint |
| 336 | + |
| 337 | + # Create first page of peers results with paging_state |
| 338 | + first_page = ResultMessage(kind=RESULT_KIND_ROWS) |
| 339 | + first_page.column_names = ["rpc_address", "peer", "schema_version", "data_center", "rack", "tokens", "host_id"] |
| 340 | + first_page.parsed_rows = [["192.168.1.1", "10.0.0.1", "a", "dc1", "rack1", ["1", "101", "201"], "uuid2"]] |
| 341 | + first_page.paging_state = b"has_more_pages" |
| 342 | + |
| 343 | + # Create second page of peers results without paging_state |
| 344 | + second_page = ResultMessage(kind=RESULT_KIND_ROWS) |
| 345 | + second_page.column_names = ["rpc_address", "peer", "schema_version", "data_center", "rack", "tokens", "host_id"] |
| 346 | + second_page.parsed_rows = [["192.168.1.2", "10.0.0.2", "a", "dc1", "rack1", ["2", "102", "202"], "uuid3"]] |
| 347 | + second_page.paging_state = None |
| 348 | + |
| 349 | + # Create local result without paging |
| 350 | + local_result = ResultMessage(kind=RESULT_KIND_ROWS) |
| 351 | + local_result.column_names = ["rpc_address", "schema_version", "cluster_name", "data_center", "rack", "partitioner", "release_version", "tokens", "host_id"] |
| 352 | + local_result.parsed_rows = [["192.168.1.0", "a", "foocluster", "dc1", "rack1", "Murmur3Partitioner", "2.2.0", ["0", "100", "200"], "uuid1"]] |
| 353 | + local_result.paging_state = None |
| 354 | + |
| 355 | + # Setup mock: first call returns first page, second call returns second page |
| 356 | + mock_connection.wait_for_responses.return_value = (first_page, local_result) |
| 357 | + mock_connection.wait_for_response.return_value = second_page |
| 358 | + |
| 359 | + # Test _fetch_all_pages |
| 360 | + self.control_connection._connection = mock_connection |
| 361 | + query_msg = QueryMessage(query="SELECT * FROM system.peers", consistency_level=ConsistencyLevel.ONE, fetch_size=1000) |
| 362 | + |
| 363 | + result = self.control_connection._fetch_all_pages(mock_connection, first_page, query_msg, timeout=5) |
| 364 | + |
| 365 | + # Verify that both pages were fetched |
| 366 | + assert len(result.parsed_rows) == 2 |
| 367 | + assert result.parsed_rows[0][0] == "192.168.1.1" |
| 368 | + assert result.parsed_rows[1][0] == "192.168.1.2" |
| 369 | + assert result.paging_state is None |
| 370 | + |
| 371 | + # Verify wait_for_response was called once to fetch the second page |
| 372 | + assert mock_connection.wait_for_response.called |
| 373 | + |
326 | 374 | def test_refresh_nodes_and_tokens_with_invalid_peers(self): |
327 | 375 | def refresh_and_validate_added_hosts(): |
328 | 376 | self.connection.wait_for_responses = Mock(return_value=_node_meta_results( |
|
0 commit comments