def __init__(self): self.account_endpoint = Configurations.ENDPOINT self.account_key = Configurations.ACCOUNT_KEY self.regions = Configurations.REGIONS.split(';') self.database_name = Configurations.DATABASE_NAME self.manual_collection_name = Configurations.MANUAL_COLLECTION_NAME self.lww_collection_name = Configurations.LWW_COLLECTION_NAME self.udp_collection_name = Configurations.UDP_COLLECTION_NAME self.basic_collection_name = Configurations.BASIC_COLLECTION_NAME self.workers = [] self.conflict_worker = ConflictWorker(self.database_name, self.basic_collection_name, self.manual_collection_name, self.lww_collection_name, self.udp_collection_name) self.pool = ThreadPool(processes=len(self.regions)) for region in self.regions: connection_policy = documents.ConnectionPolicy() connection_policy.UseMultipleWriteLocations = True connection_policy.PreferredLocations = [region] client = cosmos_client_connection.CosmosClientConnection( self.account_endpoint, {'masterKey': self.account_key}, connection_policy, documents.ConsistencyLevel.Session) self.workers.append( Worker(client, self.database_name, self.basic_collection_name)) self.conflict_worker.add_client(client)
def test_success_with_correct_proxy(self): connection_policy.ProxyConfiguration.Port = self.serverPort client = cosmos_client_connection.CosmosClientConnection( self.host, {'masterKey': self.masterKey}, connection_policy) created_db = client.CreateDatabase({'id': self.testDbName}) self.assertEqual(created_db['id'], self.testDbName, msg="Database id is incorrect")
def test_globaldb_endpoint_discovery_retry_policy(self): connection_policy = documents.ConnectionPolicy() connection_policy.EnableEndpointDiscovery = True write_location_client = cosmos_client_connection.CosmosClientConnection(Test_globaldb_mock_tests.write_location_host, {'masterKey': Test_globaldb_mock_tests.masterKey}, connection_policy) self.assertEqual(write_location_client._global_endpoint_manager.WriteEndpoint, Test_globaldb_mock_tests.write_location_host) self.MockCreateDatabase(write_location_client, { 'id': 'mock database' }) self.assertEqual(write_location_client._global_endpoint_manager.WriteEndpoint, Test_globaldb_mock_tests.read_location_host)
def test_failure_with_wrong_proxy(self): connection_policy.ProxyConfiguration.Port = self.serverPort + 1 try: # client does a getDatabaseAccount on initialization, which fails client = cosmos_client_connection.CosmosClientConnection( self.host, {'masterKey': self.masterKey}, connection_policy) self.fail("Client instantiation is not expected") except Exception as e: self.assertTrue(type(e) is ProxyError, msg="Error is not a ProxyError")
def test_globaldb_database_account_unavailable(self): connection_policy = documents.ConnectionPolicy() connection_policy.EnableEndpointDiscovery = True client = cosmos_client_connection.CosmosClientConnection(Test_globaldb_mock_tests.host, {'masterKey': Test_globaldb_mock_tests.masterKey}, connection_policy) self.assertEqual(client._global_endpoint_manager.WriteEndpoint, Test_globaldb_mock_tests.write_location_host) self.assertEqual(client._global_endpoint_manager.ReadEndpoint, Test_globaldb_mock_tests.write_location_host) global_endpoint_manager._GlobalEndpointManager._GetDatabaseAccountStub = self.MockGetDatabaseAccountStub client._global_endpoint_manager.DatabaseAccountAvailable = False client._global_endpoint_manager.RefreshEndpointList() self.assertEqual(client._global_endpoint_manager.WriteEndpoint, Test_globaldb_mock_tests.host) self.assertEqual(client._global_endpoint_manager.ReadEndpoint, Test_globaldb_mock_tests.host)
def create_spy_client(self, use_multiple_write_locations, enable_endpoint_discovery, is_preferred_locations_list_empty): self.preferred_locations = [ "location1", "location2", "location3", "location4" ] connectionPolicy = documents.ConnectionPolicy() connectionPolicy.DisableSSLVerification = True connectionPolicy.PreferredLocations = [] if is_preferred_locations_list_empty else self.preferred_locations connectionPolicy.EnableEndpointDiscovery = enable_endpoint_discovery connectionPolicy.UseMultipleWriteLocations = use_multiple_write_locations client = cosmos_client_connection.CosmosClientConnection( self.DEFAULT_ENDPOINT, {'masterKey': "SomeKeyValue"}, connection_policy=connectionPolicy) return client
def test_retry_policy_does_not_mark_null_locations_unavailable(self): self.original_get_database_account = cosmos_client_connection.CosmosClientConnection.GetDatabaseAccount cosmos_client_connection.CosmosClientConnection.GetDatabaseAccount = self.mock_get_database_account client = cosmos_client_connection.CosmosClientConnection( self.DEFAULT_ENDPOINT, {'masterKey': self.MASTER_KEY}, None, documents.ConsistencyLevel.Eventual) endpoint_manager = global_endpoint_manager._GlobalEndpointManager( client) self.original_mark_endpoint_unavailable_for_read_function = endpoint_manager.mark_endpoint_unavailable_for_read endpoint_manager.mark_endpoint_unavailable_for_read = self._mock_mark_endpoint_unavailable_for_read self.original_mark_endpoint_unavailable_for_write_function = endpoint_manager.mark_endpoint_unavailable_for_write endpoint_manager.mark_endpoint_unavailable_for_write = self._mock_mark_endpoint_unavailable_for_write self.original_resolve_service_endpoint = endpoint_manager.resolve_service_endpoint endpoint_manager.resolve_service_endpoint = self._mock_resolve_service_endpoint # Read and write counters count the number of times the endpoint manager's # mark_endpoint_unavailable_for_read() and mark_endpoint_unavailable_for_read() # functions were called. When a 'None' location is returned by resolve_service_endpoint(), # these functions should not be called self._read_counter = 0 self._write_counter = 0 request = _RequestObject(http_constants.ResourceType.Document, documents._OperationType.Read) endpointDiscovery_retry_policy = endpoint_discovery_retry_policy._EndpointDiscoveryRetryPolicy( documents.ConnectionPolicy(), endpoint_manager, request) endpointDiscovery_retry_policy.ShouldRetry( errors.HTTPFailure(http_constants.StatusCodes.FORBIDDEN)) self.assertEqual(self._read_counter, 0) self.assertEqual(self._write_counter, 0) self._read_counter = 0 self._write_counter = 0 request = _RequestObject(http_constants.ResourceType.Document, documents._OperationType.Create) endpointDiscovery_retry_policy = endpoint_discovery_retry_policy._EndpointDiscoveryRetryPolicy( documents.ConnectionPolicy(), endpoint_manager, request) endpointDiscovery_retry_policy.ShouldRetry( errors.HTTPFailure(http_constants.StatusCodes.FORBIDDEN)) self.assertEqual(self._read_counter, 0) self.assertEqual(self._write_counter, 0) endpoint_manager.mark_endpoint_unavailable_for_read = self.original_mark_endpoint_unavailable_for_read_function endpoint_manager.mark_endpoint_unavailable_for_write = self.original_mark_endpoint_unavailable_for_write_function cosmos_client_connection.CosmosClientConnection.GetDatabaseAccount = self.original_get_database_account
def initialize(self, use_multiple_write_locations, enable_endpoint_discovery, is_preferred_locations_list_empty): self.database_account = self.create_database_account( use_multiple_write_locations) preferred_locations = ["location1", "location2", "location3"] self.preferred_locations = [] if is_preferred_locations_list_empty else preferred_locations self.location_cache = LocationCache(self.preferred_locations, self.DEFAULT_ENDPOINT, enable_endpoint_discovery, use_multiple_write_locations, self.REFRESH_TIME_INTERVAL_IN_MS) self.location_cache.perform_on_database_account_read( self.database_account) connectionPolicy = documents.ConnectionPolicy() connectionPolicy.PreferredLocations = self.preferred_locations client = cosmos_client_connection.CosmosClientConnection( "", {}, connection_policy=connectionPolicy) self.global_endpoint_manager = client._global_endpoint_manager
def test_streaming_failover(self): self.OriginalExecuteFunction = retry_utility._ExecuteFunction retry_utility._ExecuteFunction = self._MockExecuteFunctionEndpointDiscover connection_policy = documents.ConnectionPolicy() connection_policy.PreferredLocations = self.preferred_regional_endpoints connection_policy.DisableSSLVerification = True self.original_get_database_account = cosmos_client_connection.CosmosClientConnection.GetDatabaseAccount cosmos_client_connection.CosmosClientConnection.GetDatabaseAccount = self.mock_get_database_account client = cosmos_client_connection.CosmosClientConnection( self.DEFAULT_ENDPOINT, {'masterKey': self.MASTER_KEY}, connection_policy, documents.ConsistencyLevel.Eventual) document_definition = { 'id': 'doc', 'name': 'sample document', 'key': 'value' } created_document = {} created_document = client.CreateItem("dbs/mydb/colls/mycoll", document_definition) self.assertDictEqual(created_document, {}) self.assertDictEqual(client.last_response_headers, {}) self.assertEqual(self.counter, 10) # First request is an initial read collection. # Next 8 requests hit forbidden write exceptions and the endpoint retry policy keeps # flipping the resolved endpoint between the 2 write endpoints. # The 10th request returns the actual read document. for i in range(0, 8): if i % 2 == 0: self.assertEqual(self.endpoint_sequence[i], self.WRITE_ENDPOINT1) else: self.assertEqual(self.endpoint_sequence[i], self.WRITE_ENDPOINT2) cosmos_client_connection.CosmosClientConnection.GetDatabaseAccount = self.original_get_database_account retry_utility._ExecuteFunction = self.OriginalExecuteFunction