3 from __future__ import print_function
24 MY_DIRNAME = os.path.dirname(os.path.realpath(__file__))
25 if __name__ == '__main__' and os.path.exists(
26 os.path.join(MY_DIRNAME, '..', 'arvados', '__init__.py')):
27 # We're being launched to support another test suite.
28 # Add the Python SDK source to the library path.
29 sys.path.insert(1, os.path.dirname(MY_DIRNAME))
34 ARVADOS_DIR = os.path.realpath(os.path.join(MY_DIRNAME, '../../..'))
35 SERVICES_SRC_DIR = os.path.join(ARVADOS_DIR, 'services')
36 if 'GOPATH' in os.environ:
37 gopaths = os.environ['GOPATH'].split(':')
38 gobins = [os.path.join(path, 'bin') for path in gopaths]
39 os.environ['PATH'] = ':'.join(gobins) + ':' + os.environ['PATH']
41 TEST_TMPDIR = os.path.join(ARVADOS_DIR, 'tmp')
42 if not os.path.exists(TEST_TMPDIR):
47 _cached_db_config = {}
49 def find_server_pid(PID_PATH, wait=10):
53 while (not good_pid) and (now <= timeout):
56 with open(PID_PATH, 'r') as f:
57 server_pid = int(f.read())
58 good_pid = (os.kill(server_pid, 0) is None)
59 except EnvironmentError:
68 def kill_server_pid(pidfile, wait=10, passenger_root=False):
69 # Must re-import modules in order to work during atexit
80 # First try to shut down nicely
81 restore_cwd = os.getcwd()
82 os.chdir(passenger_root)
84 'bundle', 'exec', 'passenger', 'stop', '--pid-file', pidfile])
86 # Use up to half of the +wait+ period waiting for "passenger
87 # stop" to work. If the process hasn't exited by then, start
88 # sending TERM signals.
92 while now <= deadline and server_pid is None:
94 with open(pidfile, 'r') as f:
95 server_pid = int(f.read())
97 # No pidfile = nothing to kill.
99 except ValueError as error:
100 # Pidfile exists, but we can't parse it. Perhaps the
101 # server has created the file but hasn't written its PID
103 print("Parse error reading pidfile {}: {}".format(pidfile, error),
108 while now <= deadline:
110 exited, _ = os.waitpid(server_pid, os.WNOHANG)
112 _remove_pidfile(pidfile)
115 # already exited, or isn't our child process
119 os.kill(server_pid, signal.SIGTERM)
120 print("Sent SIGTERM to {} ({})".format(server_pid, pidfile),
122 except OSError as error:
123 if error.errno == errno.ESRCH:
124 # Thrown by os.getpgid() or os.kill() if the process
125 # does not exist, i.e., our work here is done.
126 _remove_pidfile(pidfile)
132 print("Server PID {} ({}) did not exit, giving up after {}s".
133 format(server_pid, pidfile, wait),
136 def _remove_pidfile(pidfile):
140 if os.path.lexists(pidfile):
143 def find_available_port():
144 """Return an IPv4 port number that is not in use right now.
146 We assume whoever needs to use the returned port is able to reuse
147 a recently used port without waiting for TIME_WAIT (see
148 SO_REUSEADDR / SO_REUSEPORT).
150 Some opportunity for races here, but it's better than choosing
151 something at random and not checking at all. If all of our servers
152 (hey Passenger) knew that listening on port 0 was a thing, the OS
153 would take care of the races, and this wouldn't be needed at all.
156 sock = socket.socket()
157 sock.bind(('0.0.0.0', 0))
158 port = sock.getsockname()[1]
162 def _wait_until_port_listens(port, timeout=10):
163 """Wait for a process to start listening on the given port.
165 If nothing listens on the port within the specified timeout (given
166 in seconds), print a warning on stderr before returning.
169 subprocess.check_output(['which', 'lsof'])
170 except subprocess.CalledProcessError:
171 print("WARNING: No `lsof` -- cannot wait for port to listen. "+
172 "Sleeping 0.5 and hoping for the best.",
176 deadline = time.time() + timeout
177 while time.time() < deadline:
179 subprocess.check_output(
180 ['lsof', '-t', '-i', 'tcp:'+str(port)])
181 except subprocess.CalledProcessError:
186 "WARNING: Nothing is listening on port {} (waited {} seconds).".
187 format(port, timeout),
190 def _fifo2stderr(label):
191 """Create a fifo, and copy it to stderr, prepending label to each line.
193 Return value is the path to the new FIFO.
195 +label+ should contain only alphanumerics: it is also used as part
196 of the FIFO filename.
198 fifo = os.path.join(TEST_TMPDIR, label+'.fifo')
201 except OSError as error:
202 if error.errno != errno.ENOENT:
204 os.mkfifo(fifo, 0700)
206 ['stdbuf', '-i0', '-oL', '-eL', 'sed', '-e', 's/^/['+label+'] /', fifo],
210 def run(leave_running_atexit=False):
211 """Ensure an API server is running, and ARVADOS_API_* env vars have
212 admin credentials for it.
214 If ARVADOS_TEST_API_HOST is set, a parent process has started a
215 test server for us to use: we just need to reset() it using the
218 If a previous call to run() started a new server process, and it
219 is still running, we just need to reset() it to fixture state and
222 If neither of those options work out, we'll really start a new
227 # Delete cached discovery documents.
229 # This will clear cached docs that belong to other processes (like
230 # concurrent test suites) even if they're still running. They should
231 # be able to tolerate that.
232 for fn in glob.glob(os.path.join(arvados.http_cache('discovery'),
233 '*,arvados,v1,rest,*')):
236 pid_file = _pidfile('api')
237 pid_file_ok = find_server_pid(pid_file, 0)
239 existing_api_host = os.environ.get('ARVADOS_TEST_API_HOST', my_api_host)
240 if existing_api_host and pid_file_ok:
241 if existing_api_host == my_api_host:
245 # Fall through to shutdown-and-start case.
248 # Server was provided by parent. Can't recover if it's
252 # Before trying to start up our own server, call stop() to avoid
253 # "Phusion Passenger Standalone is already running on PID 12345".
254 # (If we've gotten this far, ARVADOS_TEST_API_HOST isn't set, so
255 # we know the server is ours to kill.)
258 restore_cwd = os.getcwd()
259 api_src_dir = os.path.join(SERVICES_SRC_DIR, 'api')
260 os.chdir(api_src_dir)
262 # Either we haven't started a server of our own yet, or it has
263 # died, or we have lost our credentials, or something else is
264 # preventing us from calling reset(). Start a new one.
266 if not os.path.exists('tmp'):
269 if not os.path.exists('tmp/api'):
270 os.makedirs('tmp/api')
272 if not os.path.exists('tmp/logs'):
273 os.makedirs('tmp/logs')
275 if not os.path.exists('tmp/self-signed.pem'):
276 # We assume here that either passenger reports its listening
277 # address as https:/0.0.0.0:port/. If it reports "127.0.0.1"
278 # then the certificate won't match the host and reset() will
279 # fail certificate verification. If it reports "localhost",
280 # clients (notably Python SDK's websocket client) might
281 # resolve localhost as ::1 and then fail to connect.
282 subprocess.check_call([
283 'openssl', 'req', '-new', '-x509', '-nodes',
284 '-out', 'tmp/self-signed.pem',
285 '-keyout', 'tmp/self-signed.key',
287 '-subj', '/CN=0.0.0.0'],
290 # Install the git repository fixtures.
291 gitdir = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'git')
292 gittarball = os.path.join(SERVICES_SRC_DIR, 'api', 'test', 'test.git.tar')
293 if not os.path.isdir(gitdir):
295 subprocess.check_output(['tar', '-xC', gitdir, '-f', gittarball])
297 # The nginx proxy isn't listening here yet, but we need to choose
298 # the wss:// port now so we can write the API server config file.
299 wss_port = find_available_port()
300 _setport('wss', wss_port)
302 port = find_available_port()
303 env = os.environ.copy()
304 env['RAILS_ENV'] = 'test'
305 env['ARVADOS_TEST_WSS_PORT'] = str(wss_port)
306 if env.get('ARVADOS_TEST_EXPERIMENTAL_WS'):
307 env.pop('ARVADOS_WEBSOCKETS', None)
309 env['ARVADOS_WEBSOCKETS'] = 'yes'
310 env.pop('ARVADOS_TEST_API_HOST', None)
311 env.pop('ARVADOS_API_HOST', None)
312 env.pop('ARVADOS_API_HOST_INSECURE', None)
313 env.pop('ARVADOS_API_TOKEN', None)
314 start_msg = subprocess.check_output(
316 'passenger', 'start', '-d', '-p{}'.format(port),
317 '--pid-file', pid_file,
318 '--log-file', os.path.join(os.getcwd(), 'log/test.log'),
320 '--ssl-certificate', 'tmp/self-signed.pem',
321 '--ssl-certificate-key', 'tmp/self-signed.key'],
324 if not leave_running_atexit:
325 atexit.register(kill_server_pid, pid_file, passenger_root=api_src_dir)
327 match = re.search(r'Accessible via: https://(.*?)/', start_msg)
330 "Passenger did not report endpoint: {}".format(start_msg))
331 my_api_host = match.group(1)
332 os.environ['ARVADOS_API_HOST'] = my_api_host
334 # Make sure the server has written its pid file and started
335 # listening on its TCP port
336 find_server_pid(pid_file)
337 _wait_until_port_listens(port)
340 os.chdir(restore_cwd)
343 """Reset the test server to fixture state.
345 This resets the ARVADOS_TEST_API_HOST provided by a parent process
346 if any, otherwise the server started by run().
348 It also resets ARVADOS_* environment vars to point to the test
349 server with admin credentials.
351 existing_api_host = os.environ.get('ARVADOS_TEST_API_HOST', my_api_host)
352 token = auth_token('admin')
353 httpclient = httplib2.Http(ca_certs=os.path.join(
354 SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.pem'))
356 'https://{}/database/reset'.format(existing_api_host),
358 headers={'Authorization': 'OAuth2 {}'.format(token)})
359 os.environ['ARVADOS_API_HOST_INSECURE'] = 'true'
360 os.environ['ARVADOS_API_HOST'] = existing_api_host
361 os.environ['ARVADOS_API_TOKEN'] = token
363 def stop(force=False):
364 """Stop the API server, if one is running.
366 If force==False, kill it only if we started it ourselves. (This
367 supports the use case where a Python test suite calls run(), but
368 run() just uses the ARVADOS_TEST_API_HOST provided by the parent
369 process, and the test suite cleans up after itself by calling
370 stop(). In this case the test server provided by the parent
371 process should be left alone.)
373 If force==True, kill it even if we didn't start it
374 ourselves. (This supports the use case in __main__, where "run"
375 and "stop" happen in different processes.)
378 if force or my_api_host is not None:
379 kill_server_pid(_pidfile('api'))
383 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
386 port = find_available_port()
387 conf = os.path.join(TEST_TMPDIR, 'ws.yml')
388 with open(conf, 'w') as f:
401 """.format(os.environ['ARVADOS_API_HOST'],
403 ('info' if os.environ.get('ARVADOS_DEBUG', '') in ['','0'] else 'debug'),
405 _dbconfig('database'),
406 _dbconfig('username'),
407 _dbconfig('password')))
408 logf = open(_fifo2stderr('ws'), 'w')
409 ws = subprocess.Popen(
410 ["ws", "-config", conf],
411 stdin=open('/dev/null'), stdout=logf, stderr=logf, close_fds=True)
412 with open(_pidfile('ws'), 'w') as f:
414 _wait_until_port_listens(port)
419 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
421 kill_server_pid(_pidfile('ws'))
423 def _start_keep(n, keep_args):
424 keep0 = tempfile.mkdtemp()
425 port = find_available_port()
426 keep_cmd = ["keepstore",
427 "-volume={}".format(keep0),
428 "-listen=:{}".format(port),
429 "-pid="+_pidfile('keep{}'.format(n))]
431 for arg, val in keep_args.iteritems():
432 keep_cmd.append("{}={}".format(arg, val))
434 logf = open(_fifo2stderr('keep{}'.format(n)), 'w')
435 kp0 = subprocess.Popen(
436 keep_cmd, stdin=open('/dev/null'), stdout=logf, stderr=logf, close_fds=True)
438 with open(_pidfile('keep{}'.format(n)), 'w') as f:
439 f.write(str(kp0.pid))
441 with open("{}/keep{}.volume".format(TEST_TMPDIR, n), 'w') as f:
444 _wait_until_port_listens(port)
448 def run_keep(blob_signing_key=None, enforce_permissions=False, num_servers=2):
449 stop_keep(num_servers)
452 if not blob_signing_key:
453 blob_signing_key = 'zfhgfenhffzltr9dixws36j1yhksjoll2grmku38mi7yxd66h5j4q9w4jzanezacp8s6q0ro3hxakfye02152hncy6zml2ed0uc'
454 with open(os.path.join(TEST_TMPDIR, "keep.blob_signing_key"), "w") as f:
455 keep_args['-blob-signing-key-file'] = f.name
456 f.write(blob_signing_key)
457 keep_args['-enforce-permissions'] = str(enforce_permissions).lower()
458 with open(os.path.join(TEST_TMPDIR, "keep.data-manager-token-file"), "w") as f:
459 keep_args['-data-manager-token-file'] = f.name
460 f.write(auth_token('data_manager'))
461 keep_args['-never-delete'] = 'false'
465 host=os.environ['ARVADOS_API_HOST'],
466 token=os.environ['ARVADOS_API_TOKEN'],
469 for d in api.keep_services().list(filters=[['service_type','=','disk']]).execute()['items']:
470 api.keep_services().delete(uuid=d['uuid']).execute()
471 for d in api.keep_disks().list().execute()['items']:
472 api.keep_disks().delete(uuid=d['uuid']).execute()
474 for d in range(0, num_servers):
475 port = _start_keep(d, keep_args)
476 svc = api.keep_services().create(body={'keep_service': {
477 'uuid': 'zzzzz-bi6l4-keepdisk{:07d}'.format(d),
478 'service_host': 'localhost',
479 'service_port': port,
480 'service_type': 'disk',
481 'service_ssl_flag': False,
483 api.keep_disks().create(body={
484 'keep_disk': {'keep_service_uuid': svc['uuid'] }
487 # If keepproxy is running, send SIGHUP to make it discover the new
488 # keepstore services.
489 proxypidfile = _pidfile('keepproxy')
490 if os.path.exists(proxypidfile):
492 os.kill(int(open(proxypidfile).read()), signal.SIGHUP)
494 os.remove(proxypidfile)
497 kill_server_pid(_pidfile('keep{}'.format(n)))
498 if os.path.exists("{}/keep{}.volume".format(TEST_TMPDIR, n)):
499 with open("{}/keep{}.volume".format(TEST_TMPDIR, n), 'r') as r:
500 shutil.rmtree(r.read(), True)
501 os.unlink("{}/keep{}.volume".format(TEST_TMPDIR, n))
502 if os.path.exists(os.path.join(TEST_TMPDIR, "keep.blob_signing_key")):
503 os.remove(os.path.join(TEST_TMPDIR, "keep.blob_signing_key"))
505 def stop_keep(num_servers=2):
506 for n in range(0, num_servers):
509 def run_keep_proxy():
510 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
514 port = find_available_port()
515 env = os.environ.copy()
516 env['ARVADOS_API_TOKEN'] = auth_token('anonymous')
517 logf = open(_fifo2stderr('keepproxy'), 'w')
518 kp = subprocess.Popen(
520 '-pid='+_pidfile('keepproxy'),
521 '-listen=:{}'.format(port)],
522 env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf, close_fds=True)
526 host=os.environ['ARVADOS_API_HOST'],
527 token=auth_token('admin'),
529 for d in api.keep_services().list(
530 filters=[['service_type','=','proxy']]).execute()['items']:
531 api.keep_services().delete(uuid=d['uuid']).execute()
532 api.keep_services().create(body={'keep_service': {
533 'service_host': 'localhost',
534 'service_port': port,
535 'service_type': 'proxy',
536 'service_ssl_flag': False,
538 os.environ["ARVADOS_KEEP_SERVICES"] = "http://localhost:{}".format(port)
539 _setport('keepproxy', port)
540 _wait_until_port_listens(port)
542 def stop_keep_proxy():
543 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
545 kill_server_pid(_pidfile('keepproxy'))
547 def run_arv_git_httpd():
548 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
552 gitdir = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'git')
553 gitport = find_available_port()
554 env = os.environ.copy()
555 env.pop('ARVADOS_API_TOKEN', None)
556 logf = open(_fifo2stderr('arv-git-httpd'), 'w')
557 agh = subprocess.Popen(
559 '-repo-root='+gitdir+'/test',
560 '-address=:'+str(gitport)],
561 env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf)
562 with open(_pidfile('arv-git-httpd'), 'w') as f:
563 f.write(str(agh.pid))
564 _setport('arv-git-httpd', gitport)
565 _wait_until_port_listens(gitport)
567 def stop_arv_git_httpd():
568 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
570 kill_server_pid(_pidfile('arv-git-httpd'))
573 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
577 keepwebport = find_available_port()
578 env = os.environ.copy()
579 env['ARVADOS_API_TOKEN'] = auth_token('anonymous')
580 logf = open(_fifo2stderr('keep-web'), 'w')
581 keepweb = subprocess.Popen(
584 '-attachment-only-host=download:'+str(keepwebport),
585 '-listen=:'+str(keepwebport)],
586 env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf)
587 with open(_pidfile('keep-web'), 'w') as f:
588 f.write(str(keepweb.pid))
589 _setport('keep-web', keepwebport)
590 _wait_until_port_listens(keepwebport)
593 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
595 kill_server_pid(_pidfile('keep-web'))
598 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
602 nginxconf['KEEPWEBPORT'] = _getport('keep-web')
603 nginxconf['KEEPWEBDLSSLPORT'] = find_available_port()
604 nginxconf['KEEPWEBSSLPORT'] = find_available_port()
605 nginxconf['KEEPPROXYPORT'] = _getport('keepproxy')
606 nginxconf['KEEPPROXYSSLPORT'] = find_available_port()
607 nginxconf['GITPORT'] = _getport('arv-git-httpd')
608 nginxconf['GITSSLPORT'] = find_available_port()
609 nginxconf['WSPORT'] = _getport('ws')
610 nginxconf['WSSPORT'] = _getport('wss')
611 nginxconf['SSLCERT'] = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.pem')
612 nginxconf['SSLKEY'] = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.key')
613 nginxconf['ACCESSLOG'] = _fifo2stderr('nginx_access_log')
615 conftemplatefile = os.path.join(MY_DIRNAME, 'nginx.conf')
616 conffile = os.path.join(TEST_TMPDIR, 'nginx.conf')
617 with open(conffile, 'w') as f:
620 lambda match: str(nginxconf.get(match.group(1))),
621 open(conftemplatefile).read()))
623 env = os.environ.copy()
624 env['PATH'] = env['PATH']+':/sbin:/usr/sbin:/usr/local/sbin'
626 nginx = subprocess.Popen(
628 '-g', 'error_log stderr info;',
629 '-g', 'pid '+_pidfile('nginx')+';',
631 env=env, stdin=open('/dev/null'), stdout=sys.stderr)
632 _setport('keep-web-dl-ssl', nginxconf['KEEPWEBDLSSLPORT'])
633 _setport('keep-web-ssl', nginxconf['KEEPWEBSSLPORT'])
634 _setport('keepproxy-ssl', nginxconf['KEEPPROXYSSLPORT'])
635 _setport('arv-git-httpd-ssl', nginxconf['GITSSLPORT'])
638 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
640 kill_server_pid(_pidfile('nginx'))
642 def _pidfile(program):
643 return os.path.join(TEST_TMPDIR, program + '.pid')
645 def _portfile(program):
646 return os.path.join(TEST_TMPDIR, program + '.port')
648 def _setport(program, port):
649 with open(_portfile(program), 'w') as f:
652 # Returns 9 if program is not up.
653 def _getport(program):
655 return int(open(_portfile(program)).read())
660 global _cached_db_config
661 if not _cached_db_config:
662 _cached_db_config = yaml.load(open(os.path.join(
663 SERVICES_SRC_DIR, 'api', 'config', 'database.yml')))
664 return _cached_db_config['test'][key]
667 global _cached_config
669 return _cached_config[key]
670 def _load(f, required=True):
671 fullpath = os.path.join(SERVICES_SRC_DIR, 'api', 'config', f)
672 if not required and not os.path.exists(fullpath):
674 return yaml.load(fullpath)
675 cdefault = _load('application.default.yml')
676 csite = _load('application.yml', required=False)
678 for section in [cdefault.get('common',{}), cdefault.get('test',{}),
679 csite.get('common',{}), csite.get('test',{})]:
680 _cached_config.update(section)
681 return _cached_config[key]
684 '''load a fixture yaml file'''
685 with open(os.path.join(SERVICES_SRC_DIR, 'api', "test", "fixtures",
689 trim_index = yaml_file.index("# Test Helper trims the rest of the file")
690 yaml_file = yaml_file[0:trim_index]
693 return yaml.load(yaml_file)
695 def auth_token(token_name):
696 return fixture("api_client_authorizations")[token_name]["api_token"]
698 def authorize_with(token_name):
699 '''token_name is the symbolic name of the token from the api_client_authorizations fixture'''
700 arvados.config.settings()["ARVADOS_API_TOKEN"] = auth_token(token_name)
701 arvados.config.settings()["ARVADOS_API_HOST"] = os.environ.get("ARVADOS_API_HOST")
702 arvados.config.settings()["ARVADOS_API_HOST_INSECURE"] = "true"
704 class TestCaseWithServers(unittest.TestCase):
705 """TestCase to start and stop supporting Arvados servers.
707 Define any of MAIN_SERVER, KEEP_SERVER, and/or KEEP_PROXY_SERVER
708 class variables as a dictionary of keyword arguments. If you do,
709 setUpClass will start the corresponding servers by passing these
710 keyword arguments to the run, run_keep, and/or run_keep_server
711 functions, respectively. It will also set Arvados environment
712 variables to point to these servers appropriately. If you don't
713 run a Keep or Keep proxy server, setUpClass will set up a
714 temporary directory for Keep local storage, and set it as
717 tearDownClass will stop any servers started, and restore the
718 original environment.
723 KEEP_PROXY_SERVER = None
724 KEEP_WEB_SERVER = None
727 def _restore_dict(src, dest):
728 for key in dest.keys():
735 cls._orig_environ = os.environ.copy()
736 cls._orig_config = arvados.config.settings().copy()
737 cls._cleanup_funcs = []
738 os.environ.pop('ARVADOS_KEEP_SERVICES', None)
739 os.environ.pop('ARVADOS_EXTERNAL_CLIENT', None)
740 for server_kwargs, start_func, stop_func in (
741 (cls.MAIN_SERVER, run, reset),
742 (cls.WS_SERVER, run_ws, stop_ws),
743 (cls.KEEP_SERVER, run_keep, stop_keep),
744 (cls.KEEP_PROXY_SERVER, run_keep_proxy, stop_keep_proxy),
745 (cls.KEEP_WEB_SERVER, run_keep_web, stop_keep_web)):
746 if server_kwargs is not None:
747 start_func(**server_kwargs)
748 cls._cleanup_funcs.append(stop_func)
749 if (cls.KEEP_SERVER is None) and (cls.KEEP_PROXY_SERVER is None):
750 cls.local_store = tempfile.mkdtemp()
751 os.environ['KEEP_LOCAL_STORE'] = cls.local_store
752 cls._cleanup_funcs.append(
753 lambda: shutil.rmtree(cls.local_store, ignore_errors=True))
755 os.environ.pop('KEEP_LOCAL_STORE', None)
756 arvados.config.initialize()
759 def tearDownClass(cls):
760 for clean_func in cls._cleanup_funcs:
762 cls._restore_dict(cls._orig_environ, os.environ)
763 cls._restore_dict(cls._orig_config, arvados.config.settings())
766 if __name__ == "__main__":
769 'start_ws', 'stop_ws',
770 'start_keep', 'stop_keep',
771 'start_keep_proxy', 'stop_keep_proxy',
772 'start_keep-web', 'stop_keep-web',
773 'start_arv-git-httpd', 'stop_arv-git-httpd',
774 'start_nginx', 'stop_nginx',
776 parser = argparse.ArgumentParser()
777 parser.add_argument('action', type=str, help="one of {}".format(actions))
778 parser.add_argument('--auth', type=str, metavar='FIXTURE_NAME', help='Print authorization info for given api_client_authorizations fixture')
779 parser.add_argument('--num-keep-servers', metavar='int', type=int, default=2, help="Number of keep servers desired")
780 parser.add_argument('--keep-enforce-permissions', action="store_true", help="Enforce keep permissions")
782 args = parser.parse_args()
784 if args.action not in actions:
785 print("Unrecognized action '{}'. Actions are: {}.".
786 format(args.action, actions),
789 if args.action == 'start':
790 stop(force=('ARVADOS_TEST_API_HOST' not in os.environ))
791 run(leave_running_atexit=True)
792 host = os.environ['ARVADOS_API_HOST']
793 if args.auth is not None:
794 token = auth_token(args.auth)
795 print("export ARVADOS_API_TOKEN={}".format(pipes.quote(token)))
796 print("export ARVADOS_API_HOST={}".format(pipes.quote(host)))
797 print("export ARVADOS_API_HOST_INSECURE=true")
800 elif args.action == 'stop':
801 stop(force=('ARVADOS_TEST_API_HOST' not in os.environ))
802 elif args.action == 'start_ws':
804 elif args.action == 'stop_ws':
806 elif args.action == 'start_keep':
807 run_keep(enforce_permissions=args.keep_enforce_permissions, num_servers=args.num_keep_servers)
808 elif args.action == 'stop_keep':
809 stop_keep(num_servers=args.num_keep_servers)
810 elif args.action == 'start_keep_proxy':
812 elif args.action == 'stop_keep_proxy':
814 elif args.action == 'start_arv-git-httpd':
816 elif args.action == 'stop_arv-git-httpd':
818 elif args.action == 'start_keep-web':
820 elif args.action == 'stop_keep-web':
822 elif args.action == 'start_nginx':
824 elif args.action == 'stop_nginx':
827 raise Exception("action recognized but not implemented!?")