_test_base.py
Go to the documentation of this file.
1 # Copyright 2019 The gRPC Authors
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 
15 import asyncio
16 import functools
17 import logging
18 from typing import Callable
19 import unittest
20 
21 from grpc.experimental import aio
22 
23 __all__ = 'AioTestBase'
24 
25 _COROUTINE_FUNCTION_ALLOWLIST = ['setUp', 'tearDown']
26 
27 
28 def _async_to_sync_decorator(f: Callable, loop: asyncio.AbstractEventLoop):
29 
30  @functools.wraps(f)
31  def wrapper(*args, **kwargs):
32  return loop.run_until_complete(f(*args, **kwargs))
33 
34  return wrapper
35 
36 
37 def _get_default_loop(debug=True):
38  try:
39  loop = asyncio.get_event_loop()
40  except:
41  loop = asyncio.new_event_loop()
42  asyncio.set_event_loop(loop)
43  finally:
44  loop.set_debug(debug)
45  return loop
46 
47 
48 # NOTE(gnossen) this test class can also be implemented with metaclass.
49 class AioTestBase(unittest.TestCase):
50  # NOTE(lidi) We need to pick a loop for entire testing phase, otherwise it
51  # will trigger create new loops in new threads, leads to deadlock.
52  _TEST_LOOP = _get_default_loop()
53 
54  @property
55  def loop(self):
56  return self._TEST_LOOP
57 
58  def __getattribute__(self, name):
59  """Overrides the loading logic to support coroutine functions."""
60  attr = super().__getattribute__(name)
61 
62  # If possible, converts the coroutine into a sync function.
63  if name.startswith('test_') or name in _COROUTINE_FUNCTION_ALLOWLIST:
64  if asyncio.iscoroutinefunction(attr):
65  return _async_to_sync_decorator(attr, self._TEST_LOOP)
66  # For other attributes, let them pass.
67  return attr
tests_aio.unit._test_base.AioTestBase.loop
def loop(self)
Definition: _test_base.py:55
tests_aio.unit._test_base._async_to_sync_decorator
def _async_to_sync_decorator(Callable f, asyncio.AbstractEventLoop loop)
Definition: _test_base.py:28
tests_aio.unit._test_base._get_default_loop
def _get_default_loop(debug=True)
Definition: _test_base.py:37
grpc::experimental
Definition: include/grpcpp/channel.h:46
tests_aio.unit._test_base.AioTestBase.__getattribute__
def __getattribute__(self, name)
Definition: _test_base.py:58
wrapper
grpc_channel_wrapper * wrapper
Definition: src/php/ext/grpc/channel.h:48
tests_aio.unit._test_base.AioTestBase._TEST_LOOP
_TEST_LOOP
Definition: _test_base.py:52
tests_aio.unit._test_base.AioTestBase
Definition: _test_base.py:49


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:58:27