Skip to content

Commit

Permalink
test: Don't assume ordering of ThreadPoolExecutor submissions (#5052)
Browse files Browse the repository at this point in the history
This test breaks in Python 3.13 and was never guaranteed to
succeed in earlier versions of Python but apparently did due
to the way that cPython was implemented previously.
  • Loading branch information
holmanb committed Mar 13, 2024
1 parent 9c001cf commit f7c1c76
Showing 1 changed file with 58 additions and 5 deletions.
63 changes: 58 additions & 5 deletions tests/unittests/test_url_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from functools import partial
from threading import Event
from time import process_time
from unittest.mock import ANY, call

import pytest
import requests
Expand Down Expand Up @@ -446,20 +447,72 @@ def test_dual_stack_staggered(self):
"""Assert expected call intervals occur"""
stagger = 0.1
with mock.patch(M_PATH + "_run_func_with_delay") as delay_func:

def identity_of_first_arg(x, _):
return x

dual_stack(
lambda x, _y: x,
identity_of_first_arg,
["you", "and", "me", "and", "dog"],
stagger_delay=stagger,
timeout=1,
)

# ensure that stagger delay for each subsequent call is:
# ensure that stagger delay for each call is made with args:
# [ 0 * N, 1 * N, 2 * N, 3 * N, 4 * N, 5 * N] where N = stagger
# it appears that without an explicit wait/join we can't assert
# number of calls
for delay, call_item in enumerate(delay_func.call_args_list):
_, kwargs = call_item
assert stagger * delay == kwargs.get("delay")
calls = [
call(
func=identity_of_first_arg,
addr="you",
timeout=1,
event=ANY,
delay=stagger * 0,
),
call(
func=identity_of_first_arg,
addr="and",
timeout=1,
event=ANY,
delay=stagger * 1,
),
call(
func=identity_of_first_arg,
addr="me",
timeout=1,
event=ANY,
delay=stagger * 2,
),
call(
func=identity_of_first_arg,
addr="and",
timeout=1,
event=ANY,
delay=stagger * 3,
),
call(
func=identity_of_first_arg,
addr="dog",
timeout=1,
event=ANY,
delay=stagger * 4,
),
]
num_calls = 0
for call_instance in calls:
if call_instance in delay_func.call_args_list:
num_calls += 1

# we can't know the order of the submitted functions' execution
# we can't know how many of the submitted functions get called
# in advance
#
# we _do_ know what the possible arg combinations are
# we _do_ know from the mocked function how many got called
# assert that all calls that occurred had known valid arguments
# by checking for the correct number of matches
assert num_calls == len(delay_func.call_args_list)


ADDR1 = "https://addr1/"
Expand Down

0 comments on commit f7c1c76

Please sign in to comment.