start_port_server.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. # Copyright 2015 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. from __future__ import print_function
  15. import logging
  16. import os
  17. import socket
  18. import subprocess
  19. import sys
  20. import tempfile
  21. import time
  22. import six.moves.urllib.request as request
  23. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  24. import jobset
  25. # must be synchronized with test/core/util/port_server_client.h
  26. _PORT_SERVER_PORT = 32766
  27. def start_port_server():
  28. # check if a compatible port server is running
  29. # if incompatible (version mismatch) ==> start a new one
  30. # if not running ==> start a new one
  31. # otherwise, leave it up
  32. try:
  33. version = int(
  34. request.urlopen('http://localhost:%d/version_number' %
  35. _PORT_SERVER_PORT).read())
  36. logging.info('detected port server running version %d', version)
  37. running = True
  38. except Exception as e:
  39. logging.exception('failed to detect port server')
  40. running = False
  41. if running:
  42. current_version = int(
  43. subprocess.check_output([
  44. sys.executable, # use the same python binary as this process
  45. os.path.abspath('tools/run_tests/python_utils/port_server.py'),
  46. 'dump_version'
  47. ]).decode())
  48. logging.info('my port server is version %d', current_version)
  49. running = (version >= current_version)
  50. if not running:
  51. logging.info('port_server version mismatch: killing the old one')
  52. request.urlopen('http://localhost:%d/quitquitquit' %
  53. _PORT_SERVER_PORT).read()
  54. time.sleep(1)
  55. if not running:
  56. fd, logfile = tempfile.mkstemp()
  57. os.close(fd)
  58. logging.info('starting port_server, with log file %s', logfile)
  59. args = [
  60. sys.executable,
  61. os.path.abspath('tools/run_tests/python_utils/port_server.py'),
  62. '-p',
  63. '%d' % _PORT_SERVER_PORT, '-l', logfile
  64. ]
  65. env = dict(os.environ)
  66. env['BUILD_ID'] = 'pleaseDontKillMeJenkins'
  67. if jobset.platform_string() == 'windows':
  68. # Working directory of port server needs to be outside of Jenkins
  69. # workspace to prevent file lock issues.
  70. tempdir = tempfile.mkdtemp()
  71. if sys.version_info.major == 2:
  72. creationflags = 0x00000008 # detached process
  73. else:
  74. creationflags = 0 # DETACHED_PROCESS doesn't seem to work with python3
  75. port_server = subprocess.Popen(args,
  76. env=env,
  77. cwd=tempdir,
  78. creationflags=creationflags,
  79. close_fds=True)
  80. else:
  81. port_server = subprocess.Popen(args,
  82. env=env,
  83. preexec_fn=os.setsid,
  84. close_fds=True)
  85. time.sleep(1)
  86. # ensure port server is up
  87. waits = 0
  88. while True:
  89. if waits > 10:
  90. logging.warning(
  91. 'killing port server due to excessive start up waits')
  92. port_server.kill()
  93. if port_server.poll() is not None:
  94. logging.error('port_server failed to start')
  95. # try one final time: maybe another build managed to start one
  96. time.sleep(1)
  97. try:
  98. request.urlopen('http://localhost:%d/get' %
  99. _PORT_SERVER_PORT).read()
  100. logging.info(
  101. 'last ditch attempt to contact port server succeeded')
  102. break
  103. except:
  104. logging.exception(
  105. 'final attempt to contact port server failed')
  106. port_log = open(logfile, 'r').read()
  107. print(port_log)
  108. sys.exit(1)
  109. try:
  110. port_server_url = 'http://localhost:%d/get' % _PORT_SERVER_PORT
  111. request.urlopen(port_server_url).read()
  112. logging.info('port server is up and ready')
  113. break
  114. except socket.timeout:
  115. logging.exception('while waiting for port_server')
  116. time.sleep(1)
  117. waits += 1
  118. except IOError:
  119. logging.exception('while waiting for port_server')
  120. time.sleep(1)
  121. waits += 1
  122. except:
  123. logging.exception(
  124. 'error while contacting port server at "%s".'
  125. 'Will try killing it.', port_server_url)
  126. port_server.kill()
  127. raise