Skip to content

Commit 236f211

Browse files
committed
Merge branch 'main' into ct-client-cleanup
2 parents b4d54e9 + 05aa056 commit 236f211

22 files changed

Lines changed: 35 additions & 66 deletions

‎dev_utils/dev_utils/service_helper.py‎

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,23 @@ def __init__(
1414
iothub_connection_string,
1515
eventhub_connection_string,
1616
eventhub_consumer_group,
17-
event_loop=None,
1817
executor=None,
1918
):
20-
self._event_loop = event_loop or asyncio.get_event_loop()
2119
self._owns_executor = executor is None
2220
self._executor = executor or concurrent.futures.ThreadPoolExecutor()
2321
self._inner_object = ServiceHelperSync(
2422
iothub_connection_string, eventhub_connection_string, eventhub_consumer_group
2523
)
2624

25+
async def _run_in_executor(self, func, *args):
26+
loop = asyncio.get_running_loop()
27+
return await loop.run_in_executor(self._executor, func, *args)
28+
2729
def set_identity(self, device_id, module_id):
2830
return self._inner_object.set_identity(device_id, module_id)
2931

3032
async def set_desired_properties(self, desired_props):
31-
return await self._event_loop.run_in_executor(
32-
self._executor,
33-
self._inner_object.set_desired_properties,
34-
desired_props,
35-
)
33+
return await self._run_in_executor(self._inner_object.set_desired_properties, desired_props)
3634

3735
async def invoke_method(
3836
self,
@@ -41,8 +39,7 @@ async def invoke_method(
4139
connect_timeout_in_seconds=None,
4240
response_timeout_in_seconds=None,
4341
):
44-
return await self._event_loop.run_in_executor(
45-
self._executor,
42+
return await self._run_in_executor(
4643
self._inner_object.invoke_method,
4744
method_name,
4845
payload,
@@ -55,28 +52,25 @@ async def send_c2d(
5552
payload,
5653
properties,
5754
):
58-
return await self._event_loop.run_in_executor(
59-
self._executor, self._inner_object.send_c2d, payload, properties
60-
)
55+
return await self._run_in_executor(self._inner_object.send_c2d, payload, properties)
6156

6257
async def wait_for_eventhub_arrival(self, message_id, timeout=60):
63-
return await self._event_loop.run_in_executor(
64-
self._executor,
58+
return await self._run_in_executor(
6559
self._inner_object.wait_for_eventhub_arrival,
6660
message_id,
6761
timeout,
6862
)
6963

7064
async def get_next_reported_patch_arrival(self, block=True, timeout=240):
71-
return await self._event_loop.run_in_executor(
72-
self._executor,
65+
return await self._run_in_executor(
7366
self._inner_object.get_next_reported_patch_arrival,
7467
block,
7568
timeout,
7669
)
7770

7871
async def shutdown(self):
79-
await self._event_loop.run_in_executor(self._executor, self._inner_object.shutdown)
72+
await self._run_in_executor(self._inner_object.shutdown)
8073

8174
if self._owns_executor:
8275
self._executor.shutdown(wait=True)
76+
return

‎pytest.ini‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
[pytest]
2+
asyncio_mode=auto
23
testdox_format = plaintext
34
addopts = --testdox --timeout 20 --ignore e2e --ignore tests/e2e
45
norecursedirs=__pycache__, *.egg-info

‎requirements_test.txt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
pytest < 8.0.0
2-
pytest-asyncio <= 0.16
1+
pytest>=8,<9
2+
pytest-asyncio~=1.2
33
pytest-mock
44
pytest-testdox>=1.1.1
55
pytest-cov

‎tests/e2e/iothub_e2e/aio/conftest.py‎

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
# Licensed under the MIT License. See License.txt in the project root for
33
# license information.
44
import pytest
5-
import asyncio
65
from dev_utils import test_env, ServiceHelper
76
import logging
87
import datetime
@@ -56,13 +55,6 @@ def pytest_sessionfinish(session, exitstatus):
5655
print("-----------------------------------")
5756

5857

59-
@pytest.fixture(scope="session")
60-
def event_loop():
61-
loop = asyncio.get_event_loop()
62-
yield loop
63-
loop.close()
64-
65-
6658
@pytest.fixture(scope="function")
6759
async def brand_new_client(device_identity, client_kwargs, service_helper, device_id, module_id):
6860
service_helper.set_identity(device_id, module_id)
@@ -104,12 +96,11 @@ async def client(brand_new_client):
10496

10597

10698
@pytest.fixture(scope="session")
107-
async def service_helper(event_loop, executor):
99+
async def service_helper(executor):
108100
service_helper = ServiceHelper(
109101
iothub_connection_string=test_env.IOTHUB_CONNECTION_STRING,
110102
eventhub_connection_string=test_env.EVENTHUB_CONNECTION_STRING,
111103
eventhub_consumer_group=test_env.EVENTHUB_CONSUMER_GROUP,
112-
event_loop=event_loop,
113104
executor=executor,
114105
)
115106
yield service_helper

‎tests/e2e/iothub_e2e/aio/test_c2d.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
logger = logging.getLogger(__name__)
1111
logger.setLevel(level=logging.INFO)
1212

13-
pytestmark = pytest.mark.asyncio
1413

1514
# TODO: add tests for various application properties
1615
# TODO: is there a way to call send_c2d so it arrives as an object rather than a JSON string?
@@ -20,8 +19,9 @@
2019
class TestReceiveC2d(object):
2120
@pytest.mark.it("Can receive C2D")
2221
@pytest.mark.quicktest_suite
23-
async def test_receive_c2d(self, client, service_helper, event_loop, leak_tracker):
22+
async def test_receive_c2d(self, client, service_helper, leak_tracker):
2423
leak_tracker.set_initial_object_list()
24+
event_loop = asyncio.get_running_loop()
2525

2626
message = json.dumps(get_random_dict())
2727

‎tests/e2e/iothub_e2e/aio/test_connect_disconnect.py‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
logger = logging.getLogger(__name__)
1010
logger.setLevel(level=logging.INFO)
1111

12-
pytestmark = pytest.mark.asyncio
13-
1412

1513
@pytest.mark.describe("Client object")
1614
class TestConnectDisconnect(object):
@@ -44,7 +42,7 @@ async def test_connect_disconnect(self, brand_new_client, leak_tracker):
4442
# see "This assert fails because of initial and secondary disconnects" below
4543
@pytest.mark.skip(reason="two stage disconnect causes assertion in test code")
4644
async def test_connect_in_the_middle_of_disconnect(
47-
self, brand_new_client, event_loop, service_helper, random_message, leak_tracker
45+
self, brand_new_client, service_helper, random_message, leak_tracker
4846
):
4947
"""
5048
Explanation: People will call `connect` inside `on_connection_state_change` handlers.
@@ -54,6 +52,7 @@ async def test_connect_in_the_middle_of_disconnect(
5452
assert client
5553

5654
leak_tracker.set_initial_object_list()
55+
event_loop = asyncio.get_running_loop()
5756

5857
reconnected_event = asyncio.Event()
5958

@@ -112,7 +111,6 @@ async def handle_on_connection_state_change():
112111
async def test_disconnect_in_the_middle_of_connect(
113112
self,
114113
brand_new_client,
115-
event_loop,
116114
service_helper,
117115
random_message,
118116
first_connect,
@@ -128,6 +126,7 @@ async def test_disconnect_in_the_middle_of_connect(
128126
disconnect_on_next_connect_event = False
129127

130128
leak_tracker.set_initial_object_list()
129+
event_loop = asyncio.get_running_loop()
131130

132131
disconnected_event = asyncio.Event()
133132

‎tests/e2e/iothub_e2e/aio/test_connect_disconnect_stress.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
logger = logging.getLogger(__name__)
1111
logger.setLevel(level=logging.INFO)
1212

13-
pytestmark = pytest.mark.asyncio
14-
1513

1614
@pytest.mark.stress
1715
@pytest.mark.describe("Client object connect/disconnect stress")

‎tests/e2e/iothub_e2e/aio/test_infrastructure.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
import pytest
55
import uuid
66

7-
pytestmark = pytest.mark.asyncio
8-
97

108
@pytest.mark.describe("ServiceHelper object")
119
class TestServiceHelper(object):

‎tests/e2e/iothub_e2e/aio/test_methods.py‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
logger = logging.getLogger(__name__)
1212
logger.setLevel(level=logging.INFO)
1313

14-
pytestmark = pytest.mark.asyncio
15-
1614

1715
@pytest.fixture
1816
def method_name():

‎tests/e2e/iothub_e2e/aio/test_sas_renewal.py‎

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
logger = logging.getLogger(__name__)
1212
logger.setLevel(level=logging.INFO)
1313

14-
pytestmark = pytest.mark.asyncio
15-
1614

1715
@pytest.mark.skipif(
1816
test_config.config.auth not in test_config.AUTH_WITH_RENEWING_TOKEN,
@@ -24,10 +22,9 @@ class TestSasRenewal(object):
2422
@pytest.mark.it("Renews and reconnects before expiry")
2523
@pytest.mark.parametrize(*parametrize.connection_retry_disabled_and_enabled)
2624
@pytest.mark.parametrize(*parametrize.auto_connect_disabled_and_enabled)
27-
async def test_sas_renews(
28-
self, client, event_loop, service_helper, random_message, leak_tracker
29-
):
25+
async def test_sas_renews(self, client, service_helper, random_message, leak_tracker):
3026
leak_tracker.set_initial_object_list()
27+
event_loop = asyncio.get_running_loop()
3128

3229
connected_event = asyncio.Event()
3330
disconnected_event = asyncio.Event()

0 commit comments

Comments
 (0)