Skip to content

Commit d5baa79

Browse files
authored
Merge branch 'development' into feature/telemetryv2
2 parents 5a68bbd + 6cb418d commit d5baa79

File tree

8 files changed

+50
-25
lines changed

8 files changed

+50
-25
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,20 @@ on:
1010

1111
jobs:
1212
test:
13-
runs-on: ubuntu-latest
13+
runs-on: ubuntu-20.04
1414
services:
1515
redis:
1616
image: redis
1717
ports:
1818
- 6379:6379
1919
steps:
2020
- name: Checkout code
21-
uses: actions/checkout@v2
21+
uses: actions/checkout@v3
2222
with:
2323
fetch-depth: 0
2424

2525
- name: Set up Python
26-
uses: actions/setup-python@v2
26+
uses: actions/setup-python@v3
2727
with:
2828
python-version: '3.6'
2929

splitio/client/factory.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
_MIN_DEFAULT_DATA_SAMPLING_ALLOWED = 0.1 # 10%
6969
_MAX_RETRY_SYNC_ALL = 3
7070

71+
7172
class Status(Enum):
7273
"""Factory Status."""
7374

splitio/engine/impressions/adapters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ def flush_counters(self, to_send):
8888
"""
8989
post the impression counters to redis.
9090
91-
:param uniques: unique keys disctionary
92-
:type uniques: Dictionary {'feature1': set(), 'feature2': set(), .. }
91+
:param to_send: unique keys disctionary
92+
:type to_send: Dictionary {'feature1': set(), 'feature2': set(), .. }
9393
"""
9494
try:
9595
resulted = 0

splitio/engine/impressions/strategies.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,6 @@ def process_impressions(self, impressions):
9999
:rtype: list[tuple[splitio.models.impression.Impression, dict]]
100100
"""
101101
imps = [(self._observer.test_and_set(imp), attrs) for imp, attrs in impressions]
102-
self._counter.track([imp for imp, _ in imps])
103-
this_hour = truncate_time(utctime_ms())
102+
self._counter.track([imp for imp, _ in imps if imp.previous_time != None])
103+
this_hour = truncate_time(util.utctime_ms())
104104
return [i for i, _ in imps if i.previous_time is None or i.previous_time < this_hour], imps

splitio/sync/synchronizer.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from splitio.api import APIException
99
from splitio.util.backoff import Backoff
1010

11+
1112
_LOGGER = logging.getLogger(__name__)
1213
_SYNC_ALL_NO_RETRIES = -1
1314

@@ -306,6 +307,7 @@ def synchronize_splits(self, till, sync_segments=True):
306307
def sync_all(self, max_retry_attempts=_SYNC_ALL_NO_RETRIES):
307308
"""
308309
Synchronize all splits.
310+
309311
:param max_retry_attempts: apply max attempts if it set to absilute integer.
310312
:type max_retry_attempts: int
311313
"""
@@ -332,7 +334,10 @@ def sync_all(self, max_retry_attempts=_SYNC_ALL_NO_RETRIES):
332334
how_long = self._backoff.get()
333335
time.sleep(how_long)
334336

335-
_LOGGER.error("Could not correctly synchronize splits and segments after %d attempts.", retry_attempts)
337+
_LOGGER.error("Could not correctly synchronize splits and segments after %d attempts.", retry_attempts)
338+
339+
def _retry_block(self, max_retry_attempts, retry_attempts):
340+
return retry_attempts
336341

337342
def shutdown(self, blocking):
338343
"""
@@ -504,6 +509,7 @@ def __init__(self, split_synchronizers, split_tasks):
504509
def sync_all(self, max_retry_attempts=-1):
505510
"""
506511
Synchronize all splits.
512+
507513
:param max_retry_attempts: Not used, added for compatibility
508514
"""
509515
try:

tests/client/test_factory.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import os
66
import time
77
import threading
8+
import pytest
89
from splitio.client.factory import get_factory, SplitFactory, _INSTANTIATED_FACTORIES, Status,\
910
_LOGGER as _logger
1011
from splitio.client.config import DEFAULT_CONFIG
@@ -126,7 +127,7 @@ def test_redis_client_creation(self, mocker):
126127
ssl_certfile='some_cert_file',
127128
ssl_cert_reqs='some_cert_req',
128129
ssl_ca_certs='some_ca_cert',
129-
max_connections=999
130+
max_connections=999,
130131
)
131132
assert factory._labels_enabled is False
132133
assert isinstance(factory._recorder, PipelinedRecorder)
@@ -238,6 +239,7 @@ def _split_synchronizer(self, ready_flag, some, auth_api, streaming_enabled, sdk
238239
mocker.patch('splitio.sync.manager.Manager.__init__', new=_split_synchronizer)
239240

240241
# Start factory and make assertions
242+
# Using invalid key should result in a timeout exception
241243
factory = get_factory('some_api_key')
242244
try:
243245
factory.block_until_ready(1)
@@ -338,6 +340,7 @@ def _split_synchronizer(self, ready_flag, some, auth_api, streaming_enabled, sdk
338340
factory.block_until_ready(1)
339341
except:
340342
pass
343+
341344
assert factory.ready is True
342345
assert factory.destroyed is False
343346

tests/engine/test_impressions.py

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,6 @@ def test_standalone_optimized(self, mocker):
121121
assert imps == [Impression('k1', 'f1', 'on', 'l1', 123, None, utc_now-3),
122122
Impression('k1', 'f2', 'on', 'l1', 123, None, utc_now-3)]
123123

124-
assert [Counter.CountPerFeature(k.feature, k.timeframe, v)
125-
for (k, v) in manager._strategy._counter._data.items()] == [
126-
Counter.CountPerFeature('f1', truncate_time(utc_now-3), 1),
127-
Counter.CountPerFeature('f2', truncate_time(utc_now-3), 1)]
128-
129124
# Tracking the same impression a ms later should be empty
130125
imps = manager.process_impressions([
131126
(Impression('k1', 'f1', 'on', 'l1', 123, None, utc_now-2), None)
@@ -154,14 +149,26 @@ def test_standalone_optimized(self, mocker):
154149
Impression('k2', 'f1', 'on', 'l1', 123, None, utc_now-2, old_utc-1)]
155150

156151
assert len(manager._strategy._observer._cache._data) == 3 # distinct impressions seen
157-
assert len(manager._strategy._counter._data) == 3 # 2 distinct features. 1 seen in 2 different timeframes
152+
assert len(manager._strategy._counter._data) == 2 # 2 distinct features. 1 seen in 2 different timeframes
158153

159154
assert set(manager._strategy._counter.pop_all()) == set([
160-
Counter.CountPerFeature('f1', truncate_time(old_utc), 3),
161-
Counter.CountPerFeature('f2', truncate_time(old_utc), 1),
155+
Counter.CountPerFeature('f1', truncate_time(old_utc), 1),
162156
Counter.CountPerFeature('f1', truncate_time(utc_now), 2)
163157
])
164158

159+
# Test counting only from the second impression
160+
imps = manager.process_impressions([
161+
(Impression('k3', 'f3', 'on', 'l1', 123, None, utc_now-1), None)
162+
])
163+
assert set(manager._strategy._counter.pop_all()) == set([])
164+
165+
imps = manager.process_impressions([
166+
(Impression('k3', 'f3', 'on', 'l1', 123, None, utc_now-1), None)
167+
])
168+
assert set(manager._strategy._counter.pop_all()) == set([
169+
Counter.CountPerFeature('f3', truncate_time(utc_now), 1)
170+
])
171+
165172
def test_standalone_debug(self, mocker):
166173
"""Test impressions manager in debug mode with sdk in standalone mode."""
167174

@@ -304,10 +311,6 @@ def test_standalone_optimized_listener(self, mocker):
304311
])
305312
assert imps == [Impression('k1', 'f1', 'on', 'l1', 123, None, utc_now-3),
306313
Impression('k1', 'f2', 'on', 'l1', 123, None, utc_now-3)]
307-
assert [Counter.CountPerFeature(k.feature, k.timeframe, v)
308-
for (k, v) in manager._strategy._counter._data.items()] == [
309-
Counter.CountPerFeature('f1', truncate_time(utc_now-3), 1),
310-
Counter.CountPerFeature('f2', truncate_time(utc_now-3), 1)]
311314

312315
# Tracking the same impression a ms later should return empty
313316
imps = manager.process_impressions([
@@ -336,11 +339,10 @@ def test_standalone_optimized_listener(self, mocker):
336339
Impression('k2', 'f1', 'on', 'l1', 123, None, utc_now-2, old_utc-1)]
337340

338341
assert len(manager._strategy._observer._cache._data) == 3 # distinct impressions seen
339-
assert len(manager._strategy._counter._data) == 3 # 2 distinct features. 1 seen in 2 different timeframes
342+
assert len(manager._strategy._counter._data) == 2 # 2 distinct features. 1 seen in 2 different timeframes
340343

341344
assert set(manager._strategy._counter.pop_all()) == set([
342-
Counter.CountPerFeature('f1', truncate_time(old_utc), 3),
343-
Counter.CountPerFeature('f2', truncate_time(old_utc), 1),
345+
Counter.CountPerFeature('f1', truncate_time(old_utc), 1),
344346
Counter.CountPerFeature('f1', truncate_time(utc_now), 2)
345347
])
346348

@@ -353,6 +355,19 @@ def test_standalone_optimized_listener(self, mocker):
353355
mocker.call(Impression('k2', 'f1', 'on', 'l1', 123, None, utc_now-2, old_utc-1), None)
354356
]
355357

358+
# Test counting only from the second impression
359+
imps = manager.process_impressions([
360+
(Impression('k3', 'f3', 'on', 'l1', 123, None, utc_now-1), None)
361+
])
362+
assert set(manager._strategy._counter.pop_all()) == set([])
363+
364+
imps = manager.process_impressions([
365+
(Impression('k3', 'f3', 'on', 'l1', 123, None, utc_now-1), None)
366+
])
367+
assert set(manager._strategy._counter.pop_all()) == set([
368+
Counter.CountPerFeature('f3', truncate_time(utc_now), 1)
369+
])
370+
356371
def test_standalone_debug_listener(self, mocker):
357372
"""Test impressions manager in optimized mode with sdk in standalone mode."""
358373

tests/sync/test_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def run(x):
5656
manager = Manager(threading.Event(), synchronizer, mocker.Mock(), False, SdkMetadata('1.0', 'some', '1.2.3.4'), mocker.Mock())
5757

5858
manager._SYNC_ALL_ATTEMPTS = 1
59-
manager.start(2) # should not throw!
59+
manager.start(2) # should not throw!
6060

6161
def test_start_streaming_false(self, mocker):
6262
splits_ready_event = threading.Event()

0 commit comments

Comments
 (0)