157 lines
5.4 KiB
Python
157 lines
5.4 KiB
Python
#
|
|
# Copyright (c) 2023 Airbyte, Inc., all rights reserved.
|
|
#
|
|
|
|
import pytest
|
|
import requests
|
|
from airbyte_cdk.sources.streams.http.error_handlers.response_models import ResponseAction
|
|
from source_google_analytics_data_api.api_quota import GoogleAnalyticsApiQuota
|
|
|
|
TEST_QUOTA_INSTANCE: GoogleAnalyticsApiQuota = GoogleAnalyticsApiQuota()
|
|
|
|
|
|
@pytest.fixture(name="expected_quota_list")
|
|
def expected_quota_list():
|
|
"""The Quota were currently handle"""
|
|
return ["concurrentRequests", "tokensPerProjectPerHour", "potentiallyThresholdedRequestsPerHour"]
|
|
|
|
|
|
def test_check_initial_quota_is_empty():
|
|
"""
|
|
Check the initial quota property is empty (== None), but ready to be fullfield.
|
|
"""
|
|
assert not TEST_QUOTA_INSTANCE.initial_quota
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("response_quota", "partial_quota", "response_action_exp", "backoff_time_exp", "stop_iter_exp"),
|
|
[
|
|
# Full Quota
|
|
(
|
|
{
|
|
"propertyQuota": {
|
|
"concurrentRequests": {"consumed": 0, "remaining": 10},
|
|
"tokensPerProjectPerHour": {"consumed": 1, "remaining": 1735},
|
|
"potentiallyThresholdedRequestsPerHour": {"consumed": 1, "remaining": 26},
|
|
}
|
|
},
|
|
False, # partial_quota
|
|
ResponseAction.RETRY,
|
|
None, # backoff_time_exp
|
|
False, # stop_iter_exp
|
|
),
|
|
# Partial Quota
|
|
(
|
|
{
|
|
"propertyQuota": {
|
|
"concurrentRequests": {"consumed": 0, "remaining": 10},
|
|
"tokensPerProjectPerHour": {"consumed": 5, "remaining": 955},
|
|
"potentiallyThresholdedRequestsPerHour": {"consumed": 3, "remaining": 26},
|
|
}
|
|
},
|
|
True, # partial_quota
|
|
ResponseAction.RETRY,
|
|
None, # backoff_time_exp
|
|
False, # stop_iter_exp
|
|
),
|
|
# Running out `tokensPerProjectPerHour`
|
|
(
|
|
{
|
|
"propertyQuota": {
|
|
"concurrentRequests": {"consumed": 2, "remaining": 8},
|
|
"tokensPerProjectPerHour": {
|
|
"consumed": 5,
|
|
# ~9% from original quota is left
|
|
"remaining": 172,
|
|
},
|
|
"potentiallyThresholdedRequestsPerHour": {"consumed": 3, "remaining": 26},
|
|
}
|
|
},
|
|
True, # partial_quota
|
|
ResponseAction.RETRY,
|
|
1800, # backoff_time_exp
|
|
False, # stop_iter_exp
|
|
),
|
|
# Running out `concurrentRequests`
|
|
(
|
|
{
|
|
"propertyQuota": {
|
|
"concurrentRequests": {
|
|
"consumed": 9,
|
|
# 10% from original quota is left
|
|
"remaining": 1,
|
|
},
|
|
"tokensPerProjectPerHour": {"consumed": 5, "remaining": 935},
|
|
"potentiallyThresholdedRequestsPerHour": {"consumed": 1, "remaining": 26},
|
|
}
|
|
},
|
|
True, # partial_quota
|
|
ResponseAction.RETRY,
|
|
30, # backoff_time_exp
|
|
False, # stop_iter_exp
|
|
),
|
|
# Running out `potentiallyThresholdedRequestsPerHour`
|
|
(
|
|
{
|
|
"propertyQuota": {
|
|
"concurrentRequests": {"consumed": 1, "remaining": 9},
|
|
"tokensPerProjectPerHour": {"consumed": 5, "remaining": 935},
|
|
"potentiallyThresholdedRequestsPerHour": {
|
|
# 7% from original quota is left
|
|
"consumed": 26,
|
|
"remaining": 2,
|
|
},
|
|
}
|
|
},
|
|
True, # partial_quota
|
|
ResponseAction.RETRY,
|
|
1800, # backoff_time_exp
|
|
False, # stop_iter_exp
|
|
),
|
|
],
|
|
ids=[
|
|
"Full",
|
|
"Partial",
|
|
"Running out tokensPerProjectPerHour",
|
|
"Running out concurrentRequests",
|
|
"Running out potentiallyThresholdedRequestsPerHour",
|
|
],
|
|
)
|
|
def test_check_full_quota(
|
|
requests_mock,
|
|
expected_quota_list,
|
|
response_quota,
|
|
partial_quota,
|
|
response_action_exp,
|
|
backoff_time_exp,
|
|
stop_iter_exp,
|
|
):
|
|
"""
|
|
Check the quota and prepare the initial values for subsequent comparison with subsequent response calls.
|
|
The default values for the scenario are expected when the quota is full.
|
|
"""
|
|
# Prepare instance
|
|
url = "https://analyticsdata.googleapis.com/v1beta/"
|
|
payload = response_quota
|
|
requests_mock.post(url, json=payload)
|
|
response = requests.post(url)
|
|
# process and prepare the scenario
|
|
TEST_QUOTA_INSTANCE._check_quota(response)
|
|
|
|
# TEST BLOCK
|
|
|
|
# Check the INITIAL QUOTA is saved properly
|
|
assert [quota in expected_quota_list for quota in TEST_QUOTA_INSTANCE.initial_quota.keys()]
|
|
|
|
# Check the CURRENT QUOTA is different from Initial
|
|
if partial_quota:
|
|
current_quota = TEST_QUOTA_INSTANCE._get_known_quota_from_response(response.json().get("propertyQuota"))
|
|
assert not current_quota == TEST_QUOTA_INSTANCE.initial_quota
|
|
|
|
# Check the scenario is applied based on Quota Values
|
|
assert TEST_QUOTA_INSTANCE.response_action is response_action_exp
|
|
# backoff_time
|
|
assert TEST_QUOTA_INSTANCE.backoff_time == backoff_time_exp
|
|
# stop_iter
|
|
assert TEST_QUOTA_INSTANCE.stop_iter is stop_iter_exp
|