cloud-init/cloud-init-dont-assume-ordering-of-ThreadPoolExecutor.patch
Robert Schweikert ae07dd3a29 - Support python 3.13:
+ pep-594-drop-pipes.patch, gh#canonical/cloud-init#4392
  + cloud-init-fix-python313.patch, gh#canonical/cloud-init#4669
  + cloud-init-dont-assume-ordering-of-ThreadPoolExecutor.patch gh#canonical/cloud-init#5052

OBS-URL: https://build.opensuse.org/package/show/Cloud:Tools/cloud-init?expand=0&rev=241
2025-01-21 21:05:02 +00:00

101 lines
3.6 KiB
Diff

From 4060bed98d2637418955fdb33fc43623c8b95235 Mon Sep 17 00:00:00 2001
From: Brett Holman <brett.holman@canonical.com>
Date: Tue, 12 Mar 2024 22:20:06 -0600
Subject: [PATCH 1/4] fix: Don't assume ordering of ThreadPoolExecutor
submissions
---
tests/unittests/test_url_helper.py | 52 +++++++++++++++++++++++++++---
1 file changed, 47 insertions(+), 5 deletions(-)
Index: cloud-init-23.3/tests/unittests/test_url_helper.py
===================================================================
--- cloud-init-23.3.orig/tests/unittests/test_url_helper.py
+++ cloud-init-23.3/tests/unittests/test_url_helper.py
@@ -4,6 +4,7 @@ import logging
from functools import partial
from threading import Event
from time import process_time
+from unittest.mock import ANY, call
import pytest
import requests
@@ -465,20 +466,72 @@ class TestDualStack:
"""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/"