X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/4470ba26b332cb92d347af00cdb26c716b1a6953..0c8f599d598f36d67daf0e0e39756ba4d064cbd0:/sdk/python/tests/run_test_server.py diff --git a/sdk/python/tests/run_test_server.py b/sdk/python/tests/run_test_server.py index ddc2799008..4f7cbb1a6c 100644 --- a/sdk/python/tests/run_test_server.py +++ b/sdk/python/tests/run_test_server.py @@ -61,17 +61,17 @@ def find_server_pid(PID_PATH, wait=10): return server_pid -def kill_server_pid(pidfile, wait=10, passenger=False): +def kill_server_pid(pidfile, wait=10, passenger_root=False): # Must re-import modules in order to work during atexit import os import signal import subprocess import time try: - if passenger: + if passenger_root: # First try to shut down nicely restore_cwd = os.getcwd() - os.chdir(os.path.join(SERVICES_SRC_DIR, 'api')) + os.chdir(passenger_root) subprocess.call([ 'bundle', 'exec', 'passenger', 'stop', '--pid-file', pidfile]) os.chdir(restore_cwd) @@ -80,7 +80,7 @@ def kill_server_pid(pidfile, wait=10, passenger=False): with open(pidfile, 'r') as f: server_pid = int(f.read()) while now <= timeout: - if not passenger or timeout - now < wait / 2: + if not passenger_root or timeout - now < wait / 2: # Half timeout has elapsed. Start sending SIGTERM os.kill(server_pid, signal.SIGTERM) # Raise OSError if process has disappeared @@ -95,6 +95,17 @@ def kill_server_pid(pidfile, wait=10, passenger=False): def run(leave_running_atexit=False): """Ensure an API server is running, and ARVADOS_API_* env vars have admin credentials for it. + + If ARVADOS_TEST_API_HOST is set, a parent process has started a + test server for us to use: we just need to reset() it using the + admin token fixture. + + If a previous call to run() started a new server process, and it + is still running, we just need to reset() it to fixture state and + return. + + If neither of those options work out, we'll really start a new + server. """ global my_api_host @@ -107,15 +118,18 @@ def run(leave_running_atexit=False): pid_file = os.path.join(SERVICES_SRC_DIR, 'api', SERVER_PID_PATH) pid_file_ok = find_server_pid(pid_file, 0) - if pid_file_ok: + existing_api_host = os.environ.get('ARVADOS_TEST_API_HOST', my_api_host) + if existing_api_host and pid_file_ok: try: + os.environ['ARVADOS_API_HOST'] = existing_api_host reset() return except: pass restore_cwd = os.getcwd() - os.chdir(os.path.join(SERVICES_SRC_DIR, 'api')) + api_src_dir = os.path.join(SERVICES_SRC_DIR, 'api') + os.chdir(api_src_dir) # Either we haven't started a server of our own yet, or it has # died, or we have lost our credentials, or something else is @@ -154,7 +168,7 @@ def run(leave_running_atexit=False): env=env) if not leave_running_atexit: - atexit.register(kill_server_pid, pidfile, passenger=True) + atexit.register(kill_server_pid, pid_file, passenger_root=api_src_dir) match = re.search(r'Accessible via: https://(.*?)/', start_msg) if not match: @@ -170,17 +184,33 @@ def run(leave_running_atexit=False): os.chdir(restore_cwd) def reset(): + """Reset the test server to fixture state. + + This resets the ARVADOS_TEST_API_HOST provided by a parent process + if any, otherwise the server started by run(). + """ + existing_api_host = os.environ.get('ARVADOS_TEST_API_HOST', my_api_host) token = auth_token('admin') httpclient = httplib2.Http(ca_certs=os.path.join( SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.pem')) httpclient.request( - 'https://{}/database/reset'.format(os.environ['ARVADOS_API_HOST']), + 'https://{}/database/reset'.format(existing_api_host), 'POST', headers={'Authorization': 'OAuth2 {}'.format(token)}) def stop(force=False): - """Stop the API server, if one is running. If force==True, kill it - even if we didn't start it ourselves. + """Stop the API server, if one is running. + + If force==False, kill it only if we started it ourselves. (This + supports the use case where a Python test suite calls run(), but + run() just uses the ARVADOS_TEST_API_HOST provided by the parent + process, and the test suite cleans up after itself by calling + stop(). In this case the test server provided by the parent + process should be left alone.) + + If force==True, kill it even if we didn't start it + ourselves. (This supports the use case in __main__, where "run" + and "stop" happen in different processes.) """ global my_api_host if force or my_api_host is not None: