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