From 2adfb502eeaa83545013bbb7d40d3f7481891e81 Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Wed, 24 Apr 2024 09:46:17 -0700 Subject: [PATCH 1/2] added spec query parameter --- splitio/api/auth.py | 3 +- splitio/api/commons.py | 15 ++- splitio/sync/segment.py | 4 +- tests/api/test_auth.py | 2 +- tests/api/test_segments_api.py | 6 +- tests/api/test_splits_api.py | 6 +- tests/integration/test_streaming_e2e.py | 122 +++++++++++------------ tests/sync/test_segments_synchronizer.py | 22 ++-- tests/tasks/test_segment_sync.py | 2 +- 9 files changed, 96 insertions(+), 86 deletions(-) diff --git a/splitio/api/auth.py b/splitio/api/auth.py index 06491ffd..db2cf599 100644 --- a/splitio/api/auth.py +++ b/splitio/api/auth.py @@ -5,6 +5,7 @@ from splitio.api import APIException from splitio.api.commons import headers_from_metadata, record_telemetry +from splitio.api.commons import _SPEC_VERSION from splitio.util.time import get_current_epoch_time_ms from splitio.api.client import HttpClientException from splitio.models.token import from_raw @@ -43,7 +44,7 @@ def authenticate(self): try: response = self._client.get( 'auth', - '/v2/auth', + '/v2/auth?s=' + _SPEC_VERSION, self._sdk_key, extra_headers=self._metadata, ) diff --git a/splitio/api/commons.py b/splitio/api/commons.py index 0766ae49..f11eef41 100644 --- a/splitio/api/commons.py +++ b/splitio/api/commons.py @@ -3,7 +3,7 @@ _CACHE_CONTROL = 'Cache-Control' _CACHE_CONTROL_NO_CACHE = 'no-cache' - +_SPEC_VERSION = '1.1' def headers_from_metadata(sdk_metadata, client_key=None): """ @@ -57,7 +57,7 @@ def record_telemetry(status_code, elapsed, metric_name, telemetry_runtime_produc class FetchOptions(object): """Fetch Options object.""" - def __init__(self, cache_control_headers=False, change_number=None, sets=None): + def __init__(self, cache_control_headers=False, change_number=None, sets=None, spec=_SPEC_VERSION): """ Class constructor. @@ -73,6 +73,7 @@ def __init__(self, cache_control_headers=False, change_number=None, sets=None): self._cache_control_headers = cache_control_headers self._change_number = change_number self._sets = sets + self._spec = spec @property def cache_control_headers(self): @@ -89,6 +90,11 @@ def sets(self): """Return sets.""" return self._sets + @property + def spec(self): + """Return sets.""" + return self._spec + def __eq__(self, other): """Match between other options.""" if self._cache_control_headers != other._cache_control_headers: @@ -97,6 +103,8 @@ def __eq__(self, other): return False if self._sets != other._sets: return False + if self._spec != other._spec: + return False return True @@ -116,7 +124,8 @@ def build_fetch(change_number, fetch_options, metadata): :return: Objects for fetch :rtype: dict, dict """ - query = {'since': change_number} + query = {'s': fetch_options.spec} if fetch_options.spec is not None else {} + query['since'] = change_number extra_headers = metadata if fetch_options is None: return query, extra_headers diff --git a/splitio/sync/segment.py b/splitio/sync/segment.py index 8d676e8b..1b726504 100644 --- a/splitio/sync/segment.py +++ b/splitio/sync/segment.py @@ -144,13 +144,13 @@ def synchronize_segment(self, segment_name, till=None): :return: True if no error occurs. False otherwise. :rtype: bool """ - fetch_options = FetchOptions(True) # Set Cache-Control to no-cache + fetch_options = FetchOptions(True, None, None, None) # Set Cache-Control to no-cache successful_sync, remaining_attempts, change_number = self._attempt_segment_sync(segment_name, fetch_options, till) attempts = _ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES - remaining_attempts if successful_sync: # succedeed sync _LOGGER.debug('Refresh completed in %d attempts.', attempts) return True - with_cdn_bypass = FetchOptions(True, change_number) # Set flag for bypassing CDN + with_cdn_bypass = FetchOptions(True, change_number, None, None) # Set flag for bypassing CDN without_cdn_successful_sync, remaining_attempts, change_number = self._attempt_segment_sync(segment_name, with_cdn_bypass, till) without_cdn_attempts = _ON_DEMAND_FETCH_BACKOFF_MAX_RETRIES - remaining_attempts if without_cdn_successful_sync: diff --git a/tests/api/test_auth.py b/tests/api/test_auth.py index 9362b9f2..9e1ecc0d 100644 --- a/tests/api/test_auth.py +++ b/tests/api/test_auth.py @@ -37,7 +37,7 @@ def test_auth(self, mocker): call_made = httpclient.get.mock_calls[0] # validate positional arguments - assert call_made[1] == ('auth', '/v2/auth', 'some_api_key') + assert call_made[1] == ('auth', '/v2/auth?s=1.1', 'some_api_key') # validate key-value args (headers) assert call_made[2]['extra_headers'] == { diff --git a/tests/api/test_segments_api.py b/tests/api/test_segments_api.py index 1255236f..afe86ccb 100644 --- a/tests/api/test_segments_api.py +++ b/tests/api/test_segments_api.py @@ -18,7 +18,7 @@ def test_fetch_segment_changes(self, mocker): httpclient.get.return_value = client.HttpResponse(200, '{"prop1": "value1"}') segment_api = segments.SegmentsAPI(httpclient, 'some_api_key', SdkMetadata('1.0', 'some', '1.2.3.4'), mocker.Mock()) - response = segment_api.fetch_segment('some_segment', 123, FetchOptions()) + response = segment_api.fetch_segment('some_segment', 123, FetchOptions(None, None, None, None)) assert response['prop1'] == 'value1' assert httpclient.get.mock_calls == [mocker.call('sdk', '/segmentChanges/some_segment', 'some_api_key', extra_headers={ @@ -29,7 +29,7 @@ def test_fetch_segment_changes(self, mocker): query={'since': 123})] httpclient.reset_mock() - response = segment_api.fetch_segment('some_segment', 123, FetchOptions(True)) + response = segment_api.fetch_segment('some_segment', 123, FetchOptions(True, None, None, None)) assert response['prop1'] == 'value1' assert httpclient.get.mock_calls == [mocker.call('sdk', '/segmentChanges/some_segment', 'some_api_key', extra_headers={ @@ -41,7 +41,7 @@ def test_fetch_segment_changes(self, mocker): query={'since': 123})] httpclient.reset_mock() - response = segment_api.fetch_segment('some_segment', 123, FetchOptions(True, 123)) + response = segment_api.fetch_segment('some_segment', 123, FetchOptions(True, 123, None, None)) assert response['prop1'] == 'value1' assert httpclient.get.mock_calls == [mocker.call('sdk', '/segmentChanges/some_segment', 'some_api_key', extra_headers={ diff --git a/tests/api/test_splits_api.py b/tests/api/test_splits_api.py index e8d1784e..8fc1120c 100644 --- a/tests/api/test_splits_api.py +++ b/tests/api/test_splits_api.py @@ -27,7 +27,7 @@ def test_fetch_split_changes(self, mocker): 'SplitSDKMachineIP': '1.2.3.4', 'SplitSDKMachineName': 'some' }, - query={'since': 123, 'sets': 'set1,set2'})] + query={'s': '1.1', 'since': 123, 'sets': 'set1,set2'})] httpclient.reset_mock() response = split_api.fetch_splits(123, FetchOptions(True)) @@ -39,7 +39,7 @@ def test_fetch_split_changes(self, mocker): 'SplitSDKMachineName': 'some', 'Cache-Control': 'no-cache' }, - query={'since': 123})] + query={'s': '1.1', 'since': 123})] httpclient.reset_mock() response = split_api.fetch_splits(123, FetchOptions(True, 123, 'set3')) @@ -51,7 +51,7 @@ def test_fetch_split_changes(self, mocker): 'SplitSDKMachineName': 'some', 'Cache-Control': 'no-cache' }, - query={'since': 123, 'till': 123, 'sets': 'set3'})] + query={'s': '1.1', 'since': 123, 'till': 123, 'sets': 'set3'})] httpclient.reset_mock() def raise_exception(*args, **kwargs): diff --git a/tests/integration/test_streaming_e2e.py b/tests/integration/test_streaming_e2e.py index b8c2032e..fa8b4900 100644 --- a/tests/integration/test_streaming_e2e.py +++ b/tests/integration/test_streaming_e2e.py @@ -141,49 +141,49 @@ def test_happiness(self): # Initial splits fetch req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=-1' + assert req.path == '/api/splitChanges?s=1.1&since=-1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Auth req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/v2/auth' + assert req.path == '/api/v2/auth?s=1.1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after streaming connected req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Fetch after first notification req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Fetch after second notification req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=3' + assert req.path == '/api/splitChanges?s=1.1&since=3' assert req.headers['authorization'] == 'Bearer some_apikey' # Segment change notification @@ -342,73 +342,73 @@ def test_occupancy_flicker(self): # Initial splits fetch req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=-1' + assert req.path == '/api/splitChanges?s=1.1&since=-1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Auth req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/v2/auth' + assert req.path == '/api/v2/auth?s=1.1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after streaming connected req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Fetch after first notification req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Fetch after second notification req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=3' + assert req.path == '/api/splitChanges?s=1.1&since=3' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=3' + assert req.path == '/api/splitChanges?s=1.1&since=3' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=4' + assert req.path == '/api/splitChanges?s=1.1&since=4' assert req.headers['authorization'] == 'Bearer some_apikey' # Split kill req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=4' + assert req.path == '/api/splitChanges?s=1.1&since=4' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=5' + assert req.path == '/api/splitChanges?s=1.1&since=5' assert req.headers['authorization'] == 'Bearer some_apikey' # Cleanup @@ -516,43 +516,43 @@ def test_start_without_occupancy(self): # Initial splits fetch req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=-1' + assert req.path == '/api/splitChanges?s=1.1&since=-1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Auth req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/v2/auth' + assert req.path == '/api/v2/auth?s=1.1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after streaming connected req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after push down req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after push restored req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Second iteration of previous syncAll req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Cleanup @@ -700,73 +700,73 @@ def test_streaming_status_changes(self): # Initial splits fetch req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=-1' + assert req.path == '/api/splitChanges?s=1.1&since=-1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Auth req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/v2/auth' + assert req.path == '/api/v2/auth?s=1.1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after streaming connected req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll on push down req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after push is up req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=3' + assert req.path == '/api/splitChanges?s=1.1&since=3' assert req.headers['authorization'] == 'Bearer some_apikey' # Fetch after notification req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=3' + assert req.path == '/api/splitChanges?s=1.1&since=3' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=4' + assert req.path == '/api/splitChanges?s=1.1&since=4' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after streaming disabled req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=4' + assert req.path == '/api/splitChanges?s=1.1&since=4' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=5' + assert req.path == '/api/splitChanges?s=1.1&since=5' assert req.headers['authorization'] == 'Bearer some_apikey' # Cleanup @@ -921,67 +921,67 @@ def test_server_closes_connection(self): # Initial splits fetch req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=-1' + assert req.path == '/api/splitChanges?s=1.1&since=-1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Auth req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/v2/auth' + assert req.path == '/api/v2/auth?s=1.1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after streaming connected req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Fetch after first notification req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll on retryable error handling req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Auth after connection breaks req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/v2/auth' + assert req.path == '/api/v2/auth?s=1.1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after streaming connected again req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Fetch after new notification req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=3' + assert req.path == '/api/splitChanges?s=1.1&since=3' assert req.headers['authorization'] == 'Bearer some_apikey' # Cleanup @@ -1152,67 +1152,67 @@ def test_ably_errors_handling(self): # Initial splits fetch req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=-1' + assert req.path == '/api/splitChanges?s=1.1&since=-1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Auth req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/v2/auth' + assert req.path == '/api/v2/auth?s=1.1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after streaming connected req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll retriable error req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=1' + assert req.path == '/api/splitChanges?s=1.1&since=1' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Auth again req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/v2/auth' + assert req.path == '/api/v2/auth?s=1.1' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after push is up req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Fetch after notification req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=2' + assert req.path == '/api/splitChanges?s=1.1&since=2' assert req.headers['authorization'] == 'Bearer some_apikey' # Iteration until since == till req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=3' + assert req.path == '/api/splitChanges?s=1.1&since=3' assert req.headers['authorization'] == 'Bearer some_apikey' # SyncAll after non recoverable ably error req = split_backend_requests.get() assert req.method == 'GET' - assert req.path == '/api/splitChanges?since=3' + assert req.path == '/api/splitChanges?s=1.1&since=3' assert req.headers['authorization'] == 'Bearer some_apikey' # Cleanup diff --git a/tests/sync/test_segments_synchronizer.py b/tests/sync/test_segments_synchronizer.py index 4612937a..3a7909b6 100644 --- a/tests/sync/test_segments_synchronizer.py +++ b/tests/sync/test_segments_synchronizer.py @@ -83,12 +83,12 @@ def fetch_segment_mock(segment_name, change_number, fetch_options): assert segments_synchronizer.synchronize_segments() api_calls = [call for call in api.fetch_segment.mock_calls] - assert mocker.call('segmentA', -1, FetchOptions(True)) in api_calls - assert mocker.call('segmentB', -1, FetchOptions(True)) in api_calls - assert mocker.call('segmentC', -1, FetchOptions(True)) in api_calls - assert mocker.call('segmentA', 123, FetchOptions(True)) in api_calls - assert mocker.call('segmentB', 123, FetchOptions(True)) in api_calls - assert mocker.call('segmentC', 123, FetchOptions(True)) in api_calls + assert mocker.call('segmentA', -1, FetchOptions(True, None, None, None)) in api_calls + assert mocker.call('segmentB', -1, FetchOptions(True, None, None, None)) in api_calls + assert mocker.call('segmentC', -1, FetchOptions(True, None, None, None)) in api_calls + assert mocker.call('segmentA', 123, FetchOptions(True, None, None, None)) in api_calls + assert mocker.call('segmentB', 123, FetchOptions(True, None, None, None)) in api_calls + assert mocker.call('segmentC', 123, FetchOptions(True, None, None, None)) in api_calls segment_put_calls = storage.put.mock_calls segments_to_validate = set(['segmentA', 'segmentB', 'segmentC']) @@ -127,8 +127,8 @@ def fetch_segment_mock(segment_name, change_number, fetch_options): segments_synchronizer.synchronize_segment('segmentA') api_calls = [call for call in api.fetch_segment.mock_calls] - assert mocker.call('segmentA', -1, FetchOptions(True)) in api_calls - assert mocker.call('segmentA', 123, FetchOptions(True)) in api_calls + assert mocker.call('segmentA', -1, FetchOptions(True, None, None, None)) in api_calls + assert mocker.call('segmentA', 123, FetchOptions(True, None, None, None)) in api_calls def test_synchronize_segment_cdn(self, mocker): """Test particular segment update cdn bypass.""" @@ -172,12 +172,12 @@ def fetch_segment_mock(segment_name, change_number, fetch_options): segments_synchronizer = SegmentSynchronizer(api, split_storage, storage) segments_synchronizer.synchronize_segment('segmentA') - assert mocker.call('segmentA', -1, FetchOptions(True)) in api.fetch_segment.mock_calls - assert mocker.call('segmentA', 123, FetchOptions(True)) in api.fetch_segment.mock_calls + assert mocker.call('segmentA', -1, FetchOptions(True, None, None, None)) in api.fetch_segment.mock_calls + assert mocker.call('segmentA', 123, FetchOptions(True, None, None, None)) in api.fetch_segment.mock_calls segments_synchronizer._backoff = Backoff(1, 0.1) segments_synchronizer.synchronize_segment('segmentA', 12345) - assert mocker.call('segmentA', 12345, FetchOptions(True, 1234)) in api.fetch_segment.mock_calls + assert mocker.call('segmentA', 12345, FetchOptions(True, 1234, None, None)) in api.fetch_segment.mock_calls assert len(api.fetch_segment.mock_calls) == 8 # 2 ok + BACKOFF(2 since==till + 2 re-attempts) + CDN(2 since==till) def test_recreate(self, mocker): diff --git a/tests/tasks/test_segment_sync.py b/tests/tasks/test_segment_sync.py index 91482a40..19020219 100644 --- a/tests/tasks/test_segment_sync.py +++ b/tests/tasks/test_segment_sync.py @@ -60,7 +60,7 @@ def fetch_segment_mock(segment_name, change_number, fetch_options): fetch_segment_mock._count_c = 0 api = mocker.Mock() - fetch_options = FetchOptions(True) + fetch_options = FetchOptions(True, None, None, None) api.fetch_segment.side_effect = fetch_segment_mock segments_synchronizer = SegmentSynchronizer(api, split_storage, storage) From 83bc37d07f84d84a883dc2411ceb52667b746ada Mon Sep 17 00:00:00 2001 From: Bilal Al Date: Thu, 25 Apr 2024 14:23:43 -0700 Subject: [PATCH 2/2] moved spec to separate file. --- splitio/api/auth.py | 4 ++-- splitio/api/commons.py | 4 ++-- splitio/spec.py | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 splitio/spec.py diff --git a/splitio/api/auth.py b/splitio/api/auth.py index db2cf599..2a09ecd9 100644 --- a/splitio/api/auth.py +++ b/splitio/api/auth.py @@ -5,7 +5,7 @@ from splitio.api import APIException from splitio.api.commons import headers_from_metadata, record_telemetry -from splitio.api.commons import _SPEC_VERSION +from splitio.spec import SPEC_VERSION from splitio.util.time import get_current_epoch_time_ms from splitio.api.client import HttpClientException from splitio.models.token import from_raw @@ -44,7 +44,7 @@ def authenticate(self): try: response = self._client.get( 'auth', - '/v2/auth?s=' + _SPEC_VERSION, + '/v2/auth?s=' + SPEC_VERSION, self._sdk_key, extra_headers=self._metadata, ) diff --git a/splitio/api/commons.py b/splitio/api/commons.py index f11eef41..49e67e9e 100644 --- a/splitio/api/commons.py +++ b/splitio/api/commons.py @@ -1,9 +1,9 @@ """Commons module.""" from splitio.util.time import get_current_epoch_time_ms +from splitio.spec import SPEC_VERSION _CACHE_CONTROL = 'Cache-Control' _CACHE_CONTROL_NO_CACHE = 'no-cache' -_SPEC_VERSION = '1.1' def headers_from_metadata(sdk_metadata, client_key=None): """ @@ -57,7 +57,7 @@ def record_telemetry(status_code, elapsed, metric_name, telemetry_runtime_produc class FetchOptions(object): """Fetch Options object.""" - def __init__(self, cache_control_headers=False, change_number=None, sets=None, spec=_SPEC_VERSION): + def __init__(self, cache_control_headers=False, change_number=None, sets=None, spec=SPEC_VERSION): """ Class constructor. diff --git a/splitio/spec.py b/splitio/spec.py new file mode 100644 index 00000000..1388fcda --- /dev/null +++ b/splitio/spec.py @@ -0,0 +1 @@ +SPEC_VERSION = '1.1'