blob: 165e733a9dbde305fe918b41ea93ab75d135c23b [file] [log] [blame]
# Copyright 2015 gRPC authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
from . import jobset
import six.moves.urllib.request as request
import logging
import os
import socket
import subprocess
import sys
import tempfile
import time
# must be synchronized with test/core/util/port_server_client.h
_PORT_SERVER_PORT = 32766
def start_port_server():
# check if a compatible port server is running
# if incompatible (version mismatch) ==> start a new one
# if not running ==> start a new one
# otherwise, leave it up
try:
version = int(
request.urlopen('http://localhost:%d/version_number' %
_PORT_SERVER_PORT).read())
logging.info('detected port server running version %d', version)
running = True
except Exception as e:
logging.exception('failed to detect port server')
running = False
if running:
current_version = int(
subprocess.check_output([
sys.executable, # use the same python binary as this process
os.path.abspath('tools/run_tests/python_utils/port_server.py'),
'dump_version'
]))
logging.info('my port server is version %d', current_version)
running = (version >= current_version)
if not running:
logging.info('port_server version mismatch: killing the old one')
request.urlopen('http://localhost:%d/quitquitquit' %
_PORT_SERVER_PORT).read()
time.sleep(1)
if not running:
fd, logfile = tempfile.mkstemp()
os.close(fd)
logging.info('starting port_server, with log file %s', logfile)
args = [
sys.executable,
os.path.abspath('tools/run_tests/python_utils/port_server.py'),
'-p',
'%d' % _PORT_SERVER_PORT, '-l', logfile
]
env = dict(os.environ)
env['BUILD_ID'] = 'pleaseDontKillMeJenkins'
if jobset.platform_string() == 'windows':
# Working directory of port server needs to be outside of Jenkins
# workspace to prevent file lock issues.
tempdir = tempfile.mkdtemp()
if sys.version_info.major == 2:
creationflags = 0x00000008 # detached process
else:
creationflags = 0 # DETACHED_PROCESS doesn't seem to work with python3
port_server = subprocess.Popen(args,
env=env,
cwd=tempdir,
creationflags=creationflags,
close_fds=True)
else:
port_server = subprocess.Popen(args,
env=env,
preexec_fn=os.setsid,
close_fds=True)
time.sleep(1)
# ensure port server is up
waits = 0
while True:
if waits > 10:
logging.warning(
'killing port server due to excessive start up waits')
port_server.kill()
if port_server.poll() is not None:
logging.error('port_server failed to start')
# try one final time: maybe another build managed to start one
time.sleep(1)
try:
request.urlopen('http://localhost:%d/get' %
_PORT_SERVER_PORT).read()
logging.info(
'last ditch attempt to contact port server succeeded')
break
except:
logging.exception(
'final attempt to contact port server failed')
port_log = open(logfile, 'r').read()
print(port_log)
sys.exit(1)
try:
port_server_url = 'http://localhost:%d/get' % _PORT_SERVER_PORT
request.urlopen(port_server_url).read()
logging.info('port server is up and ready')
break
except socket.timeout:
logging.exception('while waiting for port_server')
time.sleep(1)
waits += 1
except IOError:
logging.exception('while waiting for port_server')
time.sleep(1)
waits += 1
except:
logging.exception(
'error while contacting port server at "%s".'
'Will try killing it.', port_server_url)
port_server.kill()
raise