blob: 67cf5d17e9652d473232d0cb21a4c5254190a232 [file] [log] [blame]
#!/usr/bin/env ${PY_STRING}
##
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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 unicode_literals
from __future__ import division
from __future__ import absolute_import
from __future__ import print_function
"""
Run a tool or test in a build tree with the correct PATH, PYTHONPATH, etc.
Run with no arguments for help.
"""
usage="""
Run a tool or test in a build tree with the correct PATH, PYTHONPATH, etc.
Usage:
run.py <program> [<arg>....] # Run a program, can be an interactive shell. Use PATH.
run.py -m <python-module> [<arg>....] # Run a python module. Use PYTHONPATH.
run.py -s <python-script>.py [<arg>....] # Run a python script.
run.py -x <program> [<arg>....] # Run an executable with the test runner
run.py --sh # Print a shell script to set the run.py environment.
"""
import os, sys, runpy
from subprocess import Popen, PIPE
extra_paths = [
"${CMAKE_SOURCE_DIR}/python",
"${CMAKE_BINARY_DIR}/python",
"${CMAKE_SOURCE_DIR}/tests"
]
def dedup(l):
"""Remove duplicates from list l, keep first instance. Keep order of l."""
s = set()
return [i for i in l if i not in s and (s.add(i) or True)]
def getpath(env):
"""Return a path environment variable split into a list"""
path = os.environ.get(env)
if path:
return path.split(os.pathsep)
return []
sys.path = dedup(extra_paths + sys.path)
python_path = dedup(extra_paths + getpath("PYTHONPATH"))
# runner program (e.g. valgrind) and args used to run qdrouterd
qdrouterd_runner = "${QDROUTERD_RUNNER}"
env_vars = {
'PYTHONPATH': os.pathsep.join(python_path),
'PATH': os.pathsep.join(dedup(["${CMAKE_BINARY_DIR}",
os.path.join("${CMAKE_BINARY_DIR}", 'tests'),
os.path.join("${CMAKE_BINARY_DIR}", 'router'),
os.path.join("${CMAKE_SOURCE_DIR}", 'tools'),
os.path.join("${CMAKE_BINARY_DIR}", 'tools'),
os.path.join("${CMAKE_SOURCE_DIR}", 'bin')] +
getpath('PATH'))),
'MANPATH' : os.pathsep.join([os.path.join("${CMAKE_BINARY_DIR}",'doc','man')] +
getpath('MANPATH')),
'SOURCE_DIR': "${CMAKE_SOURCE_DIR}",
'BUILD_DIR': "${CMAKE_BINARY_DIR}",
'QPID_DISPATCH_HOME': "${CMAKE_SOURCE_DIR}",
'QPID_DISPATCH_LIB': "${CMAKE_BINARY_DIR}/src/${QPID_DISPATCH_LIB}",
'QPID_DISPATCH_RUNNER': qdrouterd_runner,
'MALLOC_CHECK_': "3", # 3 = print error and abort
'MALLOC_PERTURB_': "153", # 153 = 0x99 freed memory pattern
'TSAN_OPTIONS': "${RUNTIME_TSAN_ENV_OPTIONS}",
'ASAN_OPTIONS': "${RUNTIME_ASAN_ENV_OPTIONS}",
'LSAN_OPTIONS': "${RUNTIME_LSAN_ENV_OPTIONS}",
}
os.environ.update(env_vars)
def find_exe(program):
"""Find an executable in the system PATH"""
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
mydir, name = os.path.split(program)
if mydir:
if is_exe(program): return program
else:
for path in os.environ["PATH"].split(os.pathsep):
exe_file = os.path.join(path, program)
if is_exe(exe_file): return exe_file
return None
def is_binary_exe(program):
"""True if the program is a binary executable"""
if not program: return None
p = Popen(['file', '-bi', program], stdout=PIPE, stderr=PIPE)
return p.communicate()[0].startswith('application/x-executable')
def run_path(file_path, run_name=None):
"""Wrapper for run path that falls back to exec python for python < 2.7"""
if hasattr(runpy, 'run_path'):
runpy.run_path(file_path, run_name=run_name)
else: # Python < 2.7
os.execvp(sys.executable, [sys.executable]+sys.argv)
if __name__ == "__main__":
error_prefix = ""
try:
if len(sys.argv) == 1:
print("%s" % usage)
elif sys.argv[1] == '-m':
sys.argv = sys.argv[2:]
error_prefix = "Run python module '%s': "%(sys.argv[0])
runpy.run_module(sys.argv[0], alter_sys=True, run_name="__main__")
elif sys.argv[1] == '-s':
sys.argv = sys.argv[2:]
error_prefix = "Run python script '%s':"%(sys.argv[0])
run_path(sys.argv[0], run_name="__main__")
elif sys.argv[1] == '--sh':
for name, value in env_vars.items(): print('%s="%s"'%(name, value))
print("export %s"%' '.join(env_vars.keys()))
elif sys.argv[1] == '-x':
args = qdrouterd_runner.split() + sys.argv[2:]
error_prefix = "Running '%s': "%(args)
os.execvp(args[0], args)
elif sys.argv[1].startswith('-'):
print(usage)
else:
args = sys.argv[1:]
error_prefix = "Running '%s': "%(args)
os.execvp(args[0], args)
except Exception as e:
print("%s%s: %s"%(error_prefix, type(e).__name__, e))
raise