def test_create_communicator(self): """Tests that the factory is correctly able to create a communicator""" communicator = Factory.create_communicator_from_file( PROPERTIES_URI, API_KEY_ID, SECRET_API_KEY) self.assertIs(communicator.marshaller, DefaultMarshaller.INSTANCE()) connection = communicator.connection self.assertIsInstance(connection, DefaultConnection) DefaultConnectionTest.assertConnection(self, connection, None, None, 100, None) authenticator = communicator.authenticator self.assertIsInstance(authenticator, DefaultAuthenticator) with warnings.catch_warnings(): warnings.simplefilter("ignore") self.assertEqual( AuthorizationType.V1HMAC, authenticator._DefaultAuthenticator__authorization_type) self.assertEqual(API_KEY_ID, authenticator._DefaultAuthenticator__api_id_key) self.assertEqual( SECRET_API_KEY, authenticator._DefaultAuthenticator__secret_api_key) meta_data_provider = communicator.meta_data_provider self.assertIsInstance(meta_data_provider, MetaDataProvider) request_headers = meta_data_provider.meta_data_headers self.assertEqual(1, len(request_headers)) self.assertEqual("X-GCS-ServerMetaInfo", request_headers[0].name)
def run_connection_pooling_test(self, request_count, max_connections): """Sends *request_count* requests with a maximum number of connection pools equal to *max_connections*""" communicator_configuration = init_utils.create_communicator_configuration( max_connections=max_connections) with Factory.create_communicator_from_configuration( communicator_configuration) as communicator: # Create a number of runner threads that will execute send_request runner_threads = [ threading.Thread(target=self.send_request, args=(i, communicator)) for i in range(0, request_count) ] for thread in runner_threads: thread.start() self.flag.set() # wait until threads are done before closing the communicator for i in range(0, request_count - 1): runner_threads[i].join() print( "Information on concurrent use of connections for {} connection pools:" .format(max_connections)) print("(*start time*, *end time*)") for item in self.result_list: if isinstance(item, Exception): self.fail("an exception occurred in one of the threads:/n" + str(item)) else: print repr(item)
def send_request(self, i, communicator): """runs a (concurrent) request""" try: client = Factory.create_client_from_communicator(communicator) self.flag.wait() start_time = timeit.default_timer() client.merchant(MERCHANT_ID).services().test_connection() end_time = timeit.default_timer() with self.lock: self.result_list.append((start_time, end_time)) except Exception as e: with self.lock: self.result_list.append(e)
def create_client( http_host, connect_timeout=0.500, socket_timeout=0.500, max_connections=EndpointConfiguration.DEFAULT_MAX_CONNECTIONS): connection = DefaultConnection(connect_timeout, socket_timeout, max_connections) authenticator = DefaultAuthenticator("apiKey", "secret") meta_data_provider = MetaDataProvider("the Online Payments") communicator = Communicator(api_endpoint=http_host, authenticator=authenticator, meta_data_provider=meta_data_provider, connection=connection) return Factory.create_client_from_communicator(communicator)
def test_create_configuration(self): """Tests that the factory is correctly able to create a communicator configuration""" configuration = Factory.create_configuration(PROPERTIES_URI, API_KEY_ID, SECRET_API_KEY) self.assertEqual(urlparse("https://fill_me_in"), configuration.api_endpoint) self.assertEqual(AuthorizationType.get_authorization("v1HMAC"), configuration.authorization_type) self.assertEqual(-1, configuration.connect_timeout) self.assertEqual(-1, configuration.socket_timeout) self.assertEqual(100, configuration.max_connections) self.assertEqual(API_KEY_ID, configuration.api_key_id) self.assertEqual(SECRET_API_KEY, configuration.secret_api_key) self.assertIsNone(configuration.proxy_configuration)
def test_close_expired_connections_not_pooled(self): """ Tests that the setting to close an expired connection in a client does not propagate to the connection for an unpooled connection """ mock = MagicMock(spec=Connection(), autospec=True) function_mock = Mock(name="close_expired_connections_mock") mock.attach_mock(function_mock, "close_expired_connections") client = Factory.create_client_from_file( configuration_file_name=PROPERTIES_URI, api_key_id=API_KEY_ID, secret_api_key=SECRET_API_KEY, connection=mock) client.close_expired_connections() function_mock.assert_not_called()
def test_close_idle_connection_pooled(self): """ Tests that the setting to close an idle connection in a client propagates to the connection for a pooled connection """ pooled_mock = MagicMock(spec=PooledConnection(), autospec=True) function_mock = Mock(name="close_idle_connections_mock") pooled_mock.attach_mock(function_mock, "close_idle_connections") client = Factory.create_client_from_file( configuration_file_name=PROPERTIES_URI, api_key_id=API_KEY_ID, secret_api_key=SECRET_API_KEY, connection=pooled_mock) client.close_idle_connections(timedelta(seconds=5)) # seconds function_mock.assert_called_once_with(timedelta(seconds=5))
def test_create_invalid_request(self): """Tests that a 400 failure response without a payment result will throw a ValidationException""" client = Factory.create_client_from_communicator(self.communicator) response_body = read_resource("invalid_request.json") request_body = create_request() def receive_post(uri, request_headers, body): def generate_response(): for start in range(0, len(response_body), 1024): yield response_body[start: start + 1024].encode('utf-8') return 400, None, generate_response() self.mock_connection.post.side_effect = receive_post with self.assertRaises(ValidationException) as exception: client.merchant("merchantId").payments().create_payment(request_body) self.assertIn(response_body, str(exception.exception))
def test_with_client_meta_info(self): """Tests if the function withClientMetaInfo alters a client when it needs to and does nothing if not required""" client1 = Factory.create_client_from_file(PROPERTIES_URI, API_KEY_ID, SECRET_API_KEY) client2 = client1.with_client_meta_info(None) client_meta_info = DefaultMarshaller.INSTANCE().marshal( {"test": "test"}) client3 = client1.with_client_meta_info(client_meta_info) client4 = client3.with_client_meta_info(client_meta_info) client5 = client3.with_client_meta_info(None) self.assertIsNone(client1._client_headers) self.assertIs(client1, client2) self.assertIsNot(client1, client3) self.assertClientHeaders(client3, client_meta_info) self.assertIs(client3, client4) self.assertIsNot(client3, client5) self.assertIsNone(client5._client_headers)
def test_create_success(self): """Tests that a payment can be created and communicated appropriately when responded to with a 201 message""" client = Factory.create_client_from_communicator(self.communicator) response_body = read_resource("pending_capture.json") request_body = create_request() def receive_post(uri, request_headers, body): def generate_body(): for start in range(0, len(response_body), 1024): yield response_body[start: start + 1024].encode('utf-8') return 201, None, generate_body() self.mock_connection.post.side_effect = receive_post response = client.merchant("merchantId").payments().create_payment(request_body) self.assertEqual("1_1", response.payment.id) self.assertEqual("PENDING_CAPTURE", response.payment.status)
def test_create_method_not_allowed(self): """Tests that a 405 response with a non-JSON response will throw a CommunicationException """ client = Factory.create_client_from_communicator(self.communicator) response_body = read_resource("method_not_allowed.html") request_body = create_request() def receive_post(uri, request_headers, body): def generate_response(): for start in range(0, len(response_body), 1024): yield response_body[start: start + 1024].encode('utf-8') return 405, {"content-type": "text/html"}, generate_response() self.mock_connection.post.side_effect = receive_post with self.assertRaises(CommunicationException) as exception: client.merchant("merchantId").payments().create_payment(request_body) self.assertIsNotNone(exception.exception.cause) self.assertIsInstance(exception.exception.cause, ResponseException) self.assertIn(response_body, str(exception.exception.cause))
def test_create_idempotence_error(self): """Tests that a 409 failure response with a duplicate request code and an idempotence key will throw an IdempotenceException """ client = Factory.create_client_from_communicator(self.communicator) response_body = read_resource("duplicate_request.json") request_body = create_request() context = CallContext("key") def receive_post(uri, request_headers, body): def generate_response(): for start in range(0, len(response_body), 1024): yield response_body[start: start + 1024].encode('utf-8') return 409, None, generate_response() self.mock_connection.post.side_effect = receive_post with self.assertRaises(IdempotenceException) as exception: client.merchant("merchantId").payments().create_payment(request_body, context) self.assertIn(response_body, str(exception.exception)) self.assertEqual(context.idempotence_key, exception.exception.idempotence_key)
def test_create_rejected(self): """Tests that a 400 failure response with a payment result will throw a DeclinedPaymentException""" client = Factory.create_client_from_communicator(self.communicator) response_body = read_resource("rejected.json") request_body = create_request() def receive_post(uri, request_headers, body): def generate_response(): for start in range(0, len(response_body), 1024): yield response_body[start: start + 1024].encode('utf-8') return 400, None, generate_response() self.mock_connection.post.side_effect = receive_post with self.assertRaises(DeclinedPaymentException) as context: client.merchant("merchantId").payments().create_payment(request_body) self.assertIn("payment '1_1'", str(context.exception.args)) self.assertIn("status 'REJECTED'", str(context.exception)) self.assertIn(response_body, str(context.exception)) self.assertIsNotNone(context.exception.create_payment_result) self.assertEqual("1_1", context.exception.create_payment_result.payment.id) self.assertEqual("REJECTED", context.exception.create_payment_result.payment.status)
def create_client(max_connections=False): configuration = create_communicator_configuration( max_connections=max_connections) return Factory.create_client_from_configuration( configuration).with_client_meta_info('{"test":"test"}')