_cancellation_example_test.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. """Test for cancellation example."""
  15. import contextlib
  16. import os
  17. import signal
  18. import socket
  19. import subprocess
  20. import unittest
  21. _BINARY_DIR = os.path.realpath(
  22. os.path.join(os.path.dirname(os.path.abspath(__file__)), '..'))
  23. _SERVER_PATH = os.path.join(_BINARY_DIR, 'server')
  24. _CLIENT_PATH = os.path.join(_BINARY_DIR, 'client')
  25. @contextlib.contextmanager
  26. def _get_port():
  27. sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
  28. sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1)
  29. if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) == 0:
  30. raise RuntimeError("Failed to set SO_REUSEPORT.")
  31. sock.bind(('', 0))
  32. try:
  33. yield sock.getsockname()[1]
  34. finally:
  35. sock.close()
  36. def _start_client(server_port,
  37. desired_string,
  38. ideal_distance,
  39. interesting_distance=None):
  40. interesting_distance_args = () if interesting_distance is None else (
  41. '--show-inferior', interesting_distance)
  42. return subprocess.Popen((_CLIENT_PATH, desired_string, '--server',
  43. 'localhost:{}'.format(server_port),
  44. '--ideal-distance', str(ideal_distance)) +
  45. interesting_distance_args)
  46. class CancellationExampleTest(unittest.TestCase):
  47. def test_successful_run(self):
  48. with _get_port() as test_port:
  49. server_process = subprocess.Popen(
  50. (_SERVER_PATH, '--port', str(test_port)))
  51. try:
  52. client_process = _start_client(test_port, 'aa', 0)
  53. client_return_code = client_process.wait()
  54. self.assertEqual(0, client_return_code)
  55. self.assertIsNone(server_process.poll())
  56. finally:
  57. server_process.kill()
  58. server_process.wait()
  59. def test_graceful_sigint(self):
  60. with _get_port() as test_port:
  61. server_process = subprocess.Popen(
  62. (_SERVER_PATH, '--port', str(test_port)))
  63. try:
  64. client_process1 = _start_client(test_port, 'aaaaaaaaaa', 0)
  65. client_process1.send_signal(signal.SIGINT)
  66. client_process1.wait()
  67. client_process2 = _start_client(test_port, 'aa', 0)
  68. client_return_code = client_process2.wait()
  69. self.assertEqual(0, client_return_code)
  70. self.assertIsNone(server_process.poll())
  71. finally:
  72. server_process.kill()
  73. server_process.wait()
  74. if __name__ == '__main__':
  75. unittest.main(verbosity=2)