Skip to content

Commit 463efcc

Browse files
committed
ci: fix flaky unit tests
1 parent 4f3eeb4 commit 463efcc

File tree

4 files changed

+74
-34
lines changed

4 files changed

+74
-34
lines changed

test/api/open_fga_api_test.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,22 +1526,22 @@ async def test_429_error_retry_configured_with_http_date(
15261526
"message": "Rate Limit exceeded"
15271527
}
15281528
"""
1529-
retry_after_in_sec = 5
1530-
five_seconds_from_now = (
1529+
retry_after_in_sec = 10
1530+
ten_seconds_from_now = (
15311531
datetime.now(timezone.utc) + timedelta(seconds=retry_after_in_sec)
15321532
).strftime("%a, %d %b %Y %H:%M:%S GMT")
15331533
mock_http_response = http_mock_response(
15341534
body=error_response_body,
15351535
status=429,
1536-
headers={"Retry-After": five_seconds_from_now},
1536+
headers={"Retry-After": ten_seconds_from_now},
15371537
)
15381538
mock_request.side_effect = [
15391539
RateLimitExceededError(http_resp=mock_http_response),
15401540
mock_response(response_body, 200),
15411541
]
15421542

15431543
retry = openfga_sdk.configuration.RetryParams(
1544-
max_retry=1, min_wait_in_ms=10, max_wait_in_sec=1
1544+
max_retry=1, min_wait_in_ms=10, max_wait_in_sec=15
15451545
)
15461546
configuration = self.configuration
15471547
configuration.store_id = store_id
@@ -1563,7 +1563,7 @@ async def test_429_error_retry_configured_with_http_date(
15631563
mock_request.assert_called()
15641564
self.assertEqual(mock_request.call_count, 2)
15651565
self.assertTrue(
1566-
retry_after_in_sec - 1
1566+
retry_after_in_sec - 2
15671567
<= mock_sleep.call_args[0][0]
15681568
<= retry_after_in_sec
15691569
)

test/client/client_test.py

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2041,12 +2041,6 @@ async def test_client_batch_check_multiple_request(self, mock_request):
20412041
Check whether a user is authorized to access an object
20422042
"""
20432043

2044-
# First, mock the response
2045-
mock_request.side_effect = [
2046-
mock_response('{"allowed": true, "resolution": "1234"}', 200),
2047-
mock_response('{"allowed": false, "resolution": "1234"}', 200),
2048-
mock_response('{"allowed": true, "resolution": "1234"}', 200),
2049-
]
20502044
body1 = ClientCheckRequest(
20512045
object="document:2021-budget",
20522046
relation="reader",
@@ -2062,6 +2056,20 @@ async def test_client_batch_check_multiple_request(self, mock_request):
20622056
relation="reader",
20632057
user="user:81684243-9356-4421-8fbf-a4f8d36aa31d",
20642058
)
2059+
2060+
# Mock the response based on request body to avoid race conditions
2061+
def mock_side_effect(*args, **kwargs):
2062+
body = kwargs.get("body", {})
2063+
user = body.get("tuple_key", {}).get("user", "")
2064+
if user == "user:81684243-9356-4421-8fbf-a4f8d36aa31b":
2065+
return mock_response('{"allowed": true, "resolution": "1234"}', 200)
2066+
elif user == "user:81684243-9356-4421-8fbf-a4f8d36aa31c":
2067+
return mock_response('{"allowed": false, "resolution": "1234"}', 200)
2068+
elif user == "user:81684243-9356-4421-8fbf-a4f8d36aa31d":
2069+
return mock_response('{"allowed": true, "resolution": "1234"}', 200)
2070+
return mock_response('{"allowed": false, "resolution": "1234"}', 200)
2071+
2072+
mock_request.side_effect = mock_side_effect
20652073
configuration = self.configuration
20662074
configuration.store_id = store_id
20672075
async with OpenFgaClient(configuration) as api_client:
@@ -2150,12 +2158,6 @@ async def test_client_batch_check_multiple_request_fail(self, mock_request):
21502158
}
21512159
"""
21522160

2153-
# First, mock the response
2154-
mock_request.side_effect = [
2155-
mock_response('{"allowed": true, "resolution": "1234"}', 200),
2156-
ValidationException(http_resp=http_mock_response(response_body, 400)),
2157-
mock_response('{"allowed": false, "resolution": "1234"}', 200),
2158-
]
21592161
body1 = ClientCheckRequest(
21602162
object="document:2021-budget",
21612163
relation="reader",
@@ -2171,6 +2173,22 @@ async def test_client_batch_check_multiple_request_fail(self, mock_request):
21712173
relation="reader",
21722174
user="user:81684243-9356-4421-8fbf-a4f8d36aa31d",
21732175
)
2176+
2177+
# Mock the response based on request body to avoid race conditions
2178+
def mock_side_effect(*args, **kwargs):
2179+
body = kwargs.get("body", {})
2180+
user = body.get("tuple_key", {}).get("user", "")
2181+
if user == "user:81684243-9356-4421-8fbf-a4f8d36aa31b":
2182+
return mock_response('{"allowed": true, "resolution": "1234"}', 200)
2183+
elif user == "user:81684243-9356-4421-8fbf-a4f8d36aa31c":
2184+
raise ValidationException(
2185+
http_resp=http_mock_response(response_body, 400)
2186+
)
2187+
elif user == "user:81684243-9356-4421-8fbf-a4f8d36aa31d":
2188+
return mock_response('{"allowed": false, "resolution": "1234"}', 200)
2189+
return mock_response('{"allowed": false, "resolution": "1234"}', 200)
2190+
2191+
mock_request.side_effect = mock_side_effect
21742192
configuration = self.configuration
21752193
configuration.store_id = store_id
21762194
async with OpenFgaClient(configuration) as api_client:

test/sync/client/client_test.py

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2044,12 +2044,6 @@ def test_client_batch_check_multiple_request(self, mock_request):
20442044
Check whether a user is authorized to access an object
20452045
"""
20462046

2047-
# First, mock the response
2048-
mock_request.side_effect = [
2049-
mock_response('{"allowed": true, "resolution": "1234"}', 200),
2050-
mock_response('{"allowed": false, "resolution": "1234"}', 200),
2051-
mock_response('{"allowed": true, "resolution": "1234"}', 200),
2052-
]
20532047
body1 = ClientCheckRequest(
20542048
object="document:2021-budget",
20552049
relation="reader",
@@ -2065,6 +2059,20 @@ def test_client_batch_check_multiple_request(self, mock_request):
20652059
relation="reader",
20662060
user="user:81684243-9356-4421-8fbf-a4f8d36aa31d",
20672061
)
2062+
2063+
# Mock the response based on request body to avoid race conditions
2064+
def mock_side_effect(*args, **kwargs):
2065+
body = kwargs.get("body", {})
2066+
user = body.get("tuple_key", {}).get("user", "")
2067+
if user == "user:81684243-9356-4421-8fbf-a4f8d36aa31b":
2068+
return mock_response('{"allowed": true, "resolution": "1234"}', 200)
2069+
elif user == "user:81684243-9356-4421-8fbf-a4f8d36aa31c":
2070+
return mock_response('{"allowed": false, "resolution": "1234"}', 200)
2071+
elif user == "user:81684243-9356-4421-8fbf-a4f8d36aa31d":
2072+
return mock_response('{"allowed": true, "resolution": "1234"}', 200)
2073+
return mock_response('{"allowed": false, "resolution": "1234"}', 200)
2074+
2075+
mock_request.side_effect = mock_side_effect
20682076
configuration = self.configuration
20692077
configuration.store_id = store_id
20702078
with OpenFgaClient(configuration) as api_client:
@@ -2153,12 +2161,6 @@ def test_client_batch_check_multiple_request_fail(self, mock_request):
21532161
}
21542162
"""
21552163

2156-
# First, mock the response
2157-
mock_request.side_effect = [
2158-
mock_response('{"allowed": true, "resolution": "1234"}', 200),
2159-
ValidationException(http_resp=http_mock_response(response_body, 400)),
2160-
mock_response('{"allowed": false, "resolution": "1234"}', 200),
2161-
]
21622164
body1 = ClientCheckRequest(
21632165
object="document:2021-budget",
21642166
relation="reader",
@@ -2174,6 +2176,22 @@ def test_client_batch_check_multiple_request_fail(self, mock_request):
21742176
relation="reader",
21752177
user="user:81684243-9356-4421-8fbf-a4f8d36aa31d",
21762178
)
2179+
2180+
# Mock the response based on request body to avoid race conditions
2181+
def mock_side_effect(*args, **kwargs):
2182+
body = kwargs.get("body", {})
2183+
user = body.get("tuple_key", {}).get("user", "")
2184+
if user == "user:81684243-9356-4421-8fbf-a4f8d36aa31b":
2185+
return mock_response('{"allowed": true, "resolution": "1234"}', 200)
2186+
elif user == "user:81684243-9356-4421-8fbf-a4f8d36aa31c":
2187+
raise ValidationException(
2188+
http_resp=http_mock_response(response_body, 400)
2189+
)
2190+
elif user == "user:81684243-9356-4421-8fbf-a4f8d36aa31d":
2191+
return mock_response('{"allowed": false, "resolution": "1234"}', 200)
2192+
return mock_response('{"allowed": false, "resolution": "1234"}', 200)
2193+
2194+
mock_request.side_effect = mock_side_effect
21772195
configuration = self.configuration
21782196
configuration.store_id = store_id
21792197
with OpenFgaClient(configuration) as api_client:

test/sync/open_fga_api_test.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,22 +1589,22 @@ async def test_429_error_retry_configured_with_http_date(
15891589
"message": "Rate Limit exceeded"
15901590
}
15911591
"""
1592-
retry_after_in_sec = 5
1593-
five_seconds_from_now = (
1592+
retry_after_in_sec = 10
1593+
ten_seconds_from_now = (
15941594
datetime.now(timezone.utc) + timedelta(seconds=retry_after_in_sec)
15951595
).strftime("%a, %d %b %Y %H:%M:%S GMT")
15961596
mock_http_response = http_mock_response(
15971597
body=error_response_body,
15981598
status=429,
1599-
headers={"Retry-After": five_seconds_from_now},
1599+
headers={"Retry-After": ten_seconds_from_now},
16001600
)
16011601
mock_request.side_effect = [
16021602
RateLimitExceededError(http_resp=mock_http_response),
16031603
mock_response(response_body, 200),
16041604
]
16051605

16061606
retry = openfga_sdk.configuration.RetryParams(
1607-
max_retry=1, min_wait_in_ms=10, max_wait_in_sec=1
1607+
max_retry=1, min_wait_in_ms=10, max_wait_in_sec=15
16081608
)
16091609
configuration = self.configuration
16101610
configuration.store_id = store_id
@@ -1625,7 +1625,11 @@ async def test_429_error_retry_configured_with_http_date(
16251625
self.assertTrue(api_response.allowed)
16261626
mock_request.assert_called()
16271627
self.assertEqual(mock_request.call_count, 2)
1628-
self.assertEqual(mock_sleep.call_args[0][0], retry_after_in_sec)
1628+
self.assertTrue(
1629+
retry_after_in_sec - 2
1630+
<= mock_sleep.call_args[0][0]
1631+
<= retry_after_in_sec
1632+
)
16291633

16301634
@patch("time.sleep")
16311635
@patch.object(rest.RESTClientObject, "request")

0 commit comments

Comments
 (0)