_gevent_test_main.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. # Copyright 2021 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. import gevent
  15. from gevent import monkey
  16. monkey.patch_all()
  17. threadpool = gevent.hub.get_hub().threadpool
  18. # Currently, each channel corresponds to a single native thread in the
  19. # gevent threadpool. Thus, when the unit test suite spins up hundreds of
  20. # channels concurrently, some will be starved out, causing the test to
  21. # increase in duration. We increase the max size here so this does not
  22. # happen.
  23. threadpool.maxsize = 1024
  24. threadpool.size = 32
  25. import traceback, signal
  26. from typing import Sequence
  27. import grpc.experimental.gevent
  28. grpc.experimental.gevent.init_gevent()
  29. import gevent
  30. import greenlet
  31. import datetime
  32. import grpc
  33. import unittest
  34. import sys
  35. import os
  36. import pkgutil
  37. def trace_callback(event, args):
  38. if event in ("switch", "throw"):
  39. origin, target = args
  40. sys.stderr.write("{} Transfer from {} to {} with {}\n".format(datetime.datetime.now(), origin, target, event))
  41. else:
  42. sys.stderr.write("Unknown event {}.\n".format(event))
  43. sys.stderr.flush()
  44. if os.getenv("GREENLET_TRACE") is not None:
  45. greenlet.settrace(trace_callback)
  46. def debug(sig, frame):
  47. d={'_frame':frame}
  48. d.update(frame.f_globals)
  49. d.update(frame.f_locals)
  50. sys.stderr.write("Traceback:\n{}".format("\n".join(traceback.format_stack(frame))))
  51. import gevent.util; gevent.util.print_run_info()
  52. sys.stderr.flush()
  53. signal.signal(signal.SIGTERM, debug)
  54. class SingleLoader(object):
  55. def __init__(self, pattern: str):
  56. loader = unittest.TestLoader()
  57. self.suite = unittest.TestSuite()
  58. tests = []
  59. for importer, module_name, is_package in pkgutil.walk_packages([os.path.dirname(os.path.relpath(__file__))]):
  60. if pattern in module_name:
  61. module = importer.find_module(module_name).load_module(module_name)
  62. tests.append(loader.loadTestsFromModule(module))
  63. if len(tests) != 1:
  64. raise AssertionError("Expected only 1 test module. Found {}".format(tests))
  65. self.suite.addTest(tests[0])
  66. def loadTestsFromNames(self, names: Sequence[str], module: str = None) -> unittest.TestSuite:
  67. return self.suite
  68. if __name__ == "__main__":
  69. if len(sys.argv) != 2:
  70. print(f"USAGE: {sys.argv[0]} TARGET_MODULE", file=sys.stderr)
  71. target_module = sys.argv[1]
  72. loader = SingleLoader(target_module)
  73. runner = unittest.TextTestRunner()
  74. result = gevent.spawn(runner.run, loader.suite)
  75. result.join()
  76. if not result.value.wasSuccessful():
  77. sys.exit("Test failure.")