1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: Apache-2.0
5 from __future__ import print_function
6 from __future__ import division
7 from builtins import str
8 from builtins import range
29 MY_DIRNAME = os.path.dirname(os.path.realpath(__file__))
30 if __name__ == '__main__' and os.path.exists(
31 os.path.join(MY_DIRNAME, '..', 'arvados', '__init__.py')):
32 # We're being launched to support another test suite.
33 # Add the Python SDK source to the library path.
34 sys.path.insert(1, os.path.dirname(MY_DIRNAME))
39 ARVADOS_DIR = os.path.realpath(os.path.join(MY_DIRNAME, '../../..'))
40 SERVICES_SRC_DIR = os.path.join(ARVADOS_DIR, 'services')
41 if 'GOPATH' in os.environ:
42 # Add all GOPATH bin dirs to PATH -- but insert them after the
43 # ruby gems bin dir, to ensure "bundle" runs the Ruby bundler
44 # command, not the golang.org/x/tools/cmd/bundle command.
45 gopaths = os.environ['GOPATH'].split(':')
46 addbins = [os.path.join(path, 'bin') for path in gopaths]
48 for path in os.environ['PATH'].split(':'):
50 if os.path.exists(os.path.join(path, 'bundle')):
54 os.environ['PATH'] = ':'.join(newbins)
56 TEST_TMPDIR = os.path.join(ARVADOS_DIR, 'tmp')
57 if not os.path.exists(TEST_TMPDIR):
62 _cached_db_config = {}
64 def find_server_pid(PID_PATH, wait=10):
68 while (not good_pid) and (now <= timeout):
71 with open(PID_PATH, 'r') as f:
72 server_pid = int(f.read())
73 good_pid = (os.kill(server_pid, 0) is None)
74 except EnvironmentError:
83 def kill_server_pid(pidfile, wait=10, passenger_root=False):
84 # Must re-import modules in order to work during atexit
95 # First try to shut down nicely
96 restore_cwd = os.getcwd()
97 os.chdir(passenger_root)
99 'bundle', 'exec', 'passenger', 'stop', '--pid-file', pidfile])
100 os.chdir(restore_cwd)
101 # Use up to half of the +wait+ period waiting for "passenger
102 # stop" to work. If the process hasn't exited by then, start
103 # sending TERM signals.
107 while now <= deadline and server_pid is None:
109 with open(pidfile, 'r') as f:
110 server_pid = int(f.read())
112 # No pidfile = nothing to kill.
114 except ValueError as error:
115 # Pidfile exists, but we can't parse it. Perhaps the
116 # server has created the file but hasn't written its PID
118 print("Parse error reading pidfile {}: {}".format(pidfile, error),
123 while now <= deadline:
125 exited, _ = os.waitpid(server_pid, os.WNOHANG)
127 _remove_pidfile(pidfile)
130 # already exited, or isn't our child process
134 os.kill(server_pid, signal.SIGTERM)
135 print("Sent SIGTERM to {} ({})".format(server_pid, pidfile),
137 except OSError as error:
138 if error.errno == errno.ESRCH:
139 # Thrown by os.getpgid() or os.kill() if the process
140 # does not exist, i.e., our work here is done.
141 _remove_pidfile(pidfile)
147 print("Server PID {} ({}) did not exit, giving up after {}s".
148 format(server_pid, pidfile, wait),
151 def _remove_pidfile(pidfile):
155 if os.path.lexists(pidfile):
158 def find_available_port():
159 """Return an IPv4 port number that is not in use right now.
161 We assume whoever needs to use the returned port is able to reuse
162 a recently used port without waiting for TIME_WAIT (see
163 SO_REUSEADDR / SO_REUSEPORT).
165 Some opportunity for races here, but it's better than choosing
166 something at random and not checking at all. If all of our servers
167 (hey Passenger) knew that listening on port 0 was a thing, the OS
168 would take care of the races, and this wouldn't be needed at all.
171 sock = socket.socket()
172 sock.bind(('0.0.0.0', 0))
173 port = sock.getsockname()[1]
177 def _wait_until_port_listens(port, timeout=10):
178 """Wait for a process to start listening on the given port.
180 If nothing listens on the port within the specified timeout (given
181 in seconds), print a warning on stderr before returning.
184 subprocess.check_output(['which', 'lsof'])
185 except subprocess.CalledProcessError:
186 print("WARNING: No `lsof` -- cannot wait for port to listen. "+
187 "Sleeping 0.5 and hoping for the best.",
191 deadline = time.time() + timeout
192 while time.time() < deadline:
194 subprocess.check_output(
195 ['lsof', '-t', '-i', 'tcp:'+str(port)])
196 except subprocess.CalledProcessError:
201 "WARNING: Nothing is listening on port {} (waited {} seconds).".
202 format(port, timeout),
205 def _fifo2stderr(label):
206 """Create a fifo, and copy it to stderr, prepending label to each line.
208 Return value is the path to the new FIFO.
210 +label+ should contain only alphanumerics: it is also used as part
211 of the FIFO filename.
213 fifo = os.path.join(TEST_TMPDIR, label+'.fifo')
216 except OSError as error:
217 if error.errno != errno.ENOENT:
219 os.mkfifo(fifo, 0o700)
221 ['stdbuf', '-i0', '-oL', '-eL', 'sed', '-e', 's/^/['+label+'] /', fifo],
225 def run(leave_running_atexit=False):
226 """Ensure an API server is running, and ARVADOS_API_* env vars have
227 admin credentials for it.
229 If ARVADOS_TEST_API_HOST is set, a parent process has started a
230 test server for us to use: we just need to reset() it using the
233 If a previous call to run() started a new server process, and it
234 is still running, we just need to reset() it to fixture state and
237 If neither of those options work out, we'll really start a new
242 # Delete cached discovery documents.
244 # This will clear cached docs that belong to other processes (like
245 # concurrent test suites) even if they're still running. They should
246 # be able to tolerate that.
247 for fn in glob.glob(os.path.join(
248 str(arvados.http_cache('discovery')),
249 '*,arvados,v1,rest,*')):
252 pid_file = _pidfile('api')
253 pid_file_ok = find_server_pid(pid_file, 0)
255 existing_api_host = os.environ.get('ARVADOS_TEST_API_HOST', my_api_host)
256 if existing_api_host and pid_file_ok:
257 if existing_api_host == my_api_host:
261 # Fall through to shutdown-and-start case.
264 # Server was provided by parent. Can't recover if it's
268 # Before trying to start up our own server, call stop() to avoid
269 # "Phusion Passenger Standalone is already running on PID 12345".
270 # (If we've gotten this far, ARVADOS_TEST_API_HOST isn't set, so
271 # we know the server is ours to kill.)
274 restore_cwd = os.getcwd()
275 api_src_dir = os.path.join(SERVICES_SRC_DIR, 'api')
276 os.chdir(api_src_dir)
278 # Either we haven't started a server of our own yet, or it has
279 # died, or we have lost our credentials, or something else is
280 # preventing us from calling reset(). Start a new one.
282 if not os.path.exists('tmp'):
285 if not os.path.exists('tmp/api'):
286 os.makedirs('tmp/api')
288 if not os.path.exists('tmp/logs'):
289 os.makedirs('tmp/logs')
291 # Install the git repository fixtures.
292 gitdir = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'git')
293 gittarball = os.path.join(SERVICES_SRC_DIR, 'api', 'test', 'test.git.tar')
294 if not os.path.isdir(gitdir):
296 subprocess.check_output(['tar', '-xC', gitdir, '-f', gittarball])
298 # The nginx proxy isn't listening here yet, but we need to choose
299 # the wss:// port now so we can write the API server config file.
300 wss_port = find_available_port()
301 _setport('wss', wss_port)
303 port = find_available_port()
304 env = os.environ.copy()
305 env['RAILS_ENV'] = 'test'
306 env['ARVADOS_TEST_WSS_PORT'] = str(wss_port)
307 env.pop('ARVADOS_WEBSOCKETS', None)
308 env.pop('ARVADOS_TEST_API_HOST', None)
309 env.pop('ARVADOS_API_HOST', None)
310 env.pop('ARVADOS_API_HOST_INSECURE', None)
311 env.pop('ARVADOS_API_TOKEN', None)
312 start_msg = subprocess.check_output(
314 'passenger', 'start', '-d', '-p{}'.format(port),
315 '--pid-file', pid_file,
316 '--log-file', os.path.join(os.getcwd(), 'log/test.log'),
318 '--ssl-certificate', 'tmp/self-signed.pem',
319 '--ssl-certificate-key', 'tmp/self-signed.key'],
322 if not leave_running_atexit:
323 atexit.register(kill_server_pid, pid_file, passenger_root=api_src_dir)
325 match = re.search(r'Accessible via: https://(.*?)/', start_msg)
328 "Passenger did not report endpoint: {}".format(start_msg))
329 my_api_host = match.group(1)
330 os.environ['ARVADOS_API_HOST'] = my_api_host
332 # Make sure the server has written its pid file and started
333 # listening on its TCP port
334 find_server_pid(pid_file)
335 _wait_until_port_listens(port)
338 os.chdir(restore_cwd)
341 """Reset the test server to fixture state.
343 This resets the ARVADOS_TEST_API_HOST provided by a parent process
344 if any, otherwise the server started by run().
346 It also resets ARVADOS_* environment vars to point to the test
347 server with admin credentials.
349 existing_api_host = os.environ.get('ARVADOS_TEST_API_HOST', my_api_host)
350 token = auth_token('admin')
351 httpclient = httplib2.Http(ca_certs=os.path.join(
352 SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.pem'))
354 'https://{}/database/reset'.format(existing_api_host),
356 headers={'Authorization': 'OAuth2 {}'.format(token)})
357 os.environ['ARVADOS_API_HOST_INSECURE'] = 'true'
358 os.environ['ARVADOS_API_HOST'] = existing_api_host
359 os.environ['ARVADOS_API_TOKEN'] = token
361 def stop(force=False):
362 """Stop the API server, if one is running.
364 If force==False, kill it only if we started it ourselves. (This
365 supports the use case where a Python test suite calls run(), but
366 run() just uses the ARVADOS_TEST_API_HOST provided by the parent
367 process, and the test suite cleans up after itself by calling
368 stop(). In this case the test server provided by the parent
369 process should be left alone.)
371 If force==True, kill it even if we didn't start it
372 ourselves. (This supports the use case in __main__, where "run"
373 and "stop" happen in different processes.)
376 if force or my_api_host is not None:
377 kill_server_pid(_pidfile('api'))
381 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
384 port = find_available_port()
385 conf = os.path.join(TEST_TMPDIR, 'ws.yml')
386 with open(conf, 'w') as f:
399 """.format(os.environ['ARVADOS_API_HOST'],
401 ('info' if os.environ.get('ARVADOS_DEBUG', '') in ['','0'] else 'debug'),
403 _dbconfig('database'),
404 _dbconfig('username'),
405 _dbconfig('password')))
406 logf = open(_fifo2stderr('ws'), 'w')
407 ws = subprocess.Popen(
408 ["ws", "-config", conf],
409 stdin=open('/dev/null'), stdout=logf, stderr=logf, close_fds=True)
410 with open(_pidfile('ws'), 'w') as f:
412 _wait_until_port_listens(port)
417 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
419 kill_server_pid(_pidfile('ws'))
421 def _start_keep(n, keep_args):
422 keep0 = tempfile.mkdtemp()
423 port = find_available_port()
424 keep_cmd = ["keepstore",
425 "-volume={}".format(keep0),
426 "-listen=:{}".format(port),
427 "-pid="+_pidfile('keep{}'.format(n))]
429 for arg, val in keep_args.items():
430 keep_cmd.append("{}={}".format(arg, val))
432 logf = open(_fifo2stderr('keep{}'.format(n)), 'w')
433 kp0 = subprocess.Popen(
434 keep_cmd, stdin=open('/dev/null'), stdout=logf, stderr=logf, close_fds=True)
436 with open(_pidfile('keep{}'.format(n)), 'w') as f:
437 f.write(str(kp0.pid))
439 with open("{}/keep{}.volume".format(TEST_TMPDIR, n), 'w') as f:
442 _wait_until_port_listens(port)
446 def run_keep(blob_signing_key=None, enforce_permissions=False, num_servers=2):
447 stop_keep(num_servers)
450 if not blob_signing_key:
451 blob_signing_key = 'zfhgfenhffzltr9dixws36j1yhksjoll2grmku38mi7yxd66h5j4q9w4jzanezacp8s6q0ro3hxakfye02152hncy6zml2ed0uc'
452 with open(os.path.join(TEST_TMPDIR, "keep.blob_signing_key"), "w") as f:
453 keep_args['-blob-signing-key-file'] = f.name
454 f.write(blob_signing_key)
455 keep_args['-enforce-permissions'] = str(enforce_permissions).lower()
456 with open(os.path.join(TEST_TMPDIR, "keep.data-manager-token-file"), "w") as f:
457 keep_args['-data-manager-token-file'] = f.name
458 f.write(auth_token('data_manager'))
459 keep_args['-never-delete'] = 'false'
463 host=os.environ['ARVADOS_API_HOST'],
464 token=os.environ['ARVADOS_API_TOKEN'],
467 for d in api.keep_services().list(filters=[['service_type','=','disk']]).execute()['items']:
468 api.keep_services().delete(uuid=d['uuid']).execute()
469 for d in api.keep_disks().list().execute()['items']:
470 api.keep_disks().delete(uuid=d['uuid']).execute()
472 for d in range(0, num_servers):
473 port = _start_keep(d, keep_args)
474 svc = api.keep_services().create(body={'keep_service': {
475 'uuid': 'zzzzz-bi6l4-keepdisk{:07d}'.format(d),
476 'service_host': 'localhost',
477 'service_port': port,
478 'service_type': 'disk',
479 'service_ssl_flag': False,
481 api.keep_disks().create(body={
482 'keep_disk': {'keep_service_uuid': svc['uuid'] }
485 # If keepproxy and/or keep-web is running, send SIGHUP to make
486 # them discover the new keepstore services.
487 for svc in ('keepproxy', 'keep-web'):
488 pidfile = _pidfile('keepproxy')
489 if os.path.exists(pidfile):
491 os.kill(int(open(pidfile).read()), signal.SIGHUP)
496 kill_server_pid(_pidfile('keep{}'.format(n)))
497 if os.path.exists("{}/keep{}.volume".format(TEST_TMPDIR, n)):
498 with open("{}/keep{}.volume".format(TEST_TMPDIR, n), 'r') as r:
499 shutil.rmtree(r.read(), True)
500 os.unlink("{}/keep{}.volume".format(TEST_TMPDIR, n))
501 if os.path.exists(os.path.join(TEST_TMPDIR, "keep.blob_signing_key")):
502 os.remove(os.path.join(TEST_TMPDIR, "keep.blob_signing_key"))
504 def stop_keep(num_servers=2):
505 for n in range(0, num_servers):
508 def run_keep_proxy():
509 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
513 port = find_available_port()
514 env = os.environ.copy()
515 env['ARVADOS_API_TOKEN'] = auth_token('anonymous')
516 logf = open(_fifo2stderr('keepproxy'), 'w')
517 kp = subprocess.Popen(
519 '-pid='+_pidfile('keepproxy'),
520 '-listen=:{}'.format(port)],
521 env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf, close_fds=True)
525 host=os.environ['ARVADOS_API_HOST'],
526 token=auth_token('admin'),
528 for d in api.keep_services().list(
529 filters=[['service_type','=','proxy']]).execute()['items']:
530 api.keep_services().delete(uuid=d['uuid']).execute()
531 api.keep_services().create(body={'keep_service': {
532 'service_host': 'localhost',
533 'service_port': port,
534 'service_type': 'proxy',
535 'service_ssl_flag': False,
537 os.environ["ARVADOS_KEEP_SERVICES"] = "http://localhost:{}".format(port)
538 _setport('keepproxy', port)
539 _wait_until_port_listens(port)
541 def stop_keep_proxy():
542 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
544 kill_server_pid(_pidfile('keepproxy'))
546 def run_arv_git_httpd():
547 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
551 gitdir = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'git')
552 gitport = find_available_port()
553 env = os.environ.copy()
554 env.pop('ARVADOS_API_TOKEN', None)
555 logf = open(_fifo2stderr('arv-git-httpd'), 'w')
556 agh = subprocess.Popen(
558 '-repo-root='+gitdir+'/test',
559 '-address=:'+str(gitport)],
560 env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf)
561 with open(_pidfile('arv-git-httpd'), 'w') as f:
562 f.write(str(agh.pid))
563 _setport('arv-git-httpd', gitport)
564 _wait_until_port_listens(gitport)
566 def stop_arv_git_httpd():
567 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
569 kill_server_pid(_pidfile('arv-git-httpd'))
572 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
576 keepwebport = find_available_port()
577 env = os.environ.copy()
578 env['ARVADOS_API_TOKEN'] = auth_token('anonymous')
579 logf = open(_fifo2stderr('keep-web'), 'w')
580 keepweb = subprocess.Popen(
583 '-attachment-only-host=download:'+str(keepwebport),
584 '-listen=:'+str(keepwebport)],
585 env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf)
586 with open(_pidfile('keep-web'), 'w') as f:
587 f.write(str(keepweb.pid))
588 _setport('keep-web', keepwebport)
589 _wait_until_port_listens(keepwebport)
592 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
594 kill_server_pid(_pidfile('keep-web'))
597 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
601 nginxconf['KEEPWEBPORT'] = _getport('keep-web')
602 nginxconf['KEEPWEBDLSSLPORT'] = find_available_port()
603 nginxconf['KEEPWEBSSLPORT'] = find_available_port()
604 nginxconf['KEEPPROXYPORT'] = _getport('keepproxy')
605 nginxconf['KEEPPROXYSSLPORT'] = find_available_port()
606 nginxconf['GITPORT'] = _getport('arv-git-httpd')
607 nginxconf['GITSSLPORT'] = find_available_port()
608 nginxconf['WSPORT'] = _getport('ws')
609 nginxconf['WSSPORT'] = _getport('wss')
610 nginxconf['SSLCERT'] = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.pem')
611 nginxconf['SSLKEY'] = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.key')
612 nginxconf['ACCESSLOG'] = _fifo2stderr('nginx_access_log')
614 conftemplatefile = os.path.join(MY_DIRNAME, 'nginx.conf')
615 conffile = os.path.join(TEST_TMPDIR, 'nginx.conf')
616 with open(conffile, 'w') as f:
619 lambda match: str(nginxconf.get(match.group(1))),
620 open(conftemplatefile).read()))
622 env = os.environ.copy()
623 env['PATH'] = env['PATH']+':/sbin:/usr/sbin:/usr/local/sbin'
625 nginx = subprocess.Popen(
627 '-g', 'error_log stderr info;',
628 '-g', 'pid '+_pidfile('nginx')+';',
630 env=env, stdin=open('/dev/null'), stdout=sys.stderr)
631 _setport('keep-web-dl-ssl', nginxconf['KEEPWEBDLSSLPORT'])
632 _setport('keep-web-ssl', nginxconf['KEEPWEBSSLPORT'])
633 _setport('keepproxy-ssl', nginxconf['KEEPPROXYSSLPORT'])
634 _setport('arv-git-httpd-ssl', nginxconf['GITSSLPORT'])
637 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
639 kill_server_pid(_pidfile('nginx'))
641 def _pidfile(program):
642 return os.path.join(TEST_TMPDIR, program + '.pid')
644 def _portfile(program):
645 return os.path.join(TEST_TMPDIR, program + '.port')
647 def _setport(program, port):
648 with open(_portfile(program), 'w') as f:
651 # Returns 9 if program is not up.
652 def _getport(program):
654 return int(open(_portfile(program)).read())
659 global _cached_db_config
660 if not _cached_db_config:
661 _cached_db_config = yaml.load(open(os.path.join(
662 SERVICES_SRC_DIR, 'api', 'config', 'database.yml')))
663 return _cached_db_config['test'][key]
666 global _cached_config
668 return _cached_config[key]
669 def _load(f, required=True):
670 fullpath = os.path.join(SERVICES_SRC_DIR, 'api', 'config', f)
671 if not required and not os.path.exists(fullpath):
673 return yaml.load(fullpath)
674 cdefault = _load('application.default.yml')
675 csite = _load('application.yml', required=False)
677 for section in [cdefault.get('common',{}), cdefault.get('test',{}),
678 csite.get('common',{}), csite.get('test',{})]:
679 _cached_config.update(section)
680 return _cached_config[key]
683 '''load a fixture yaml file'''
684 with open(os.path.join(SERVICES_SRC_DIR, 'api', "test", "fixtures",
688 trim_index = yaml_file.index("# Test Helper trims the rest of the file")
689 yaml_file = yaml_file[0:trim_index]
692 return yaml.load(yaml_file)
694 def auth_token(token_name):
695 return fixture("api_client_authorizations")[token_name]["api_token"]
697 def authorize_with(token_name):
698 '''token_name is the symbolic name of the token from the api_client_authorizations fixture'''
699 arvados.config.settings()["ARVADOS_API_TOKEN"] = auth_token(token_name)
700 arvados.config.settings()["ARVADOS_API_HOST"] = os.environ.get("ARVADOS_API_HOST")
701 arvados.config.settings()["ARVADOS_API_HOST_INSECURE"] = "true"
703 class TestCaseWithServers(unittest.TestCase):
704 """TestCase to start and stop supporting Arvados servers.
706 Define any of MAIN_SERVER, KEEP_SERVER, and/or KEEP_PROXY_SERVER
707 class variables as a dictionary of keyword arguments. If you do,
708 setUpClass will start the corresponding servers by passing these
709 keyword arguments to the run, run_keep, and/or run_keep_server
710 functions, respectively. It will also set Arvados environment
711 variables to point to these servers appropriately. If you don't
712 run a Keep or Keep proxy server, setUpClass will set up a
713 temporary directory for Keep local storage, and set it as
716 tearDownClass will stop any servers started, and restore the
717 original environment.
722 KEEP_PROXY_SERVER = None
723 KEEP_WEB_SERVER = None
726 def _restore_dict(src, dest):
727 for key in list(dest.keys()):
734 cls._orig_environ = os.environ.copy()
735 cls._orig_config = arvados.config.settings().copy()
736 cls._cleanup_funcs = []
737 os.environ.pop('ARVADOS_KEEP_SERVICES', None)
738 os.environ.pop('ARVADOS_EXTERNAL_CLIENT', None)
739 for server_kwargs, start_func, stop_func in (
740 (cls.MAIN_SERVER, run, reset),
741 (cls.WS_SERVER, run_ws, stop_ws),
742 (cls.KEEP_SERVER, run_keep, stop_keep),
743 (cls.KEEP_PROXY_SERVER, run_keep_proxy, stop_keep_proxy),
744 (cls.KEEP_WEB_SERVER, run_keep_web, stop_keep_web)):
745 if server_kwargs is not None:
746 start_func(**server_kwargs)
747 cls._cleanup_funcs.append(stop_func)
748 if (cls.KEEP_SERVER is None) and (cls.KEEP_PROXY_SERVER is None):
749 cls.local_store = tempfile.mkdtemp()
750 os.environ['KEEP_LOCAL_STORE'] = cls.local_store
751 cls._cleanup_funcs.append(
752 lambda: shutil.rmtree(cls.local_store, ignore_errors=True))
754 os.environ.pop('KEEP_LOCAL_STORE', None)
755 arvados.config.initialize()
758 def tearDownClass(cls):
759 for clean_func in cls._cleanup_funcs:
761 cls._restore_dict(cls._orig_environ, os.environ)
762 cls._restore_dict(cls._orig_config, arvados.config.settings())
765 if __name__ == "__main__":
768 'start_ws', 'stop_ws',
769 'start_keep', 'stop_keep',
770 'start_keep_proxy', 'stop_keep_proxy',
771 'start_keep-web', 'stop_keep-web',
772 'start_arv-git-httpd', 'stop_arv-git-httpd',
773 'start_nginx', 'stop_nginx',
775 parser = argparse.ArgumentParser()
776 parser.add_argument('action', type=str, help="one of {}".format(actions))
777 parser.add_argument('--auth', type=str, metavar='FIXTURE_NAME', help='Print authorization info for given api_client_authorizations fixture')
778 parser.add_argument('--num-keep-servers', metavar='int', type=int, default=2, help="Number of keep servers desired")
779 parser.add_argument('--keep-enforce-permissions', action="store_true", help="Enforce keep permissions")
781 args = parser.parse_args()
783 if args.action not in actions:
784 print("Unrecognized action '{}'. Actions are: {}.".
785 format(args.action, actions),
788 if args.action == 'start':
789 stop(force=('ARVADOS_TEST_API_HOST' not in os.environ))
790 run(leave_running_atexit=True)
791 host = os.environ['ARVADOS_API_HOST']
792 if args.auth is not None:
793 token = auth_token(args.auth)
794 print("export ARVADOS_API_TOKEN={}".format(pipes.quote(token)))
795 print("export ARVADOS_API_HOST={}".format(pipes.quote(host)))
796 print("export ARVADOS_API_HOST_INSECURE=true")
799 elif args.action == 'stop':
800 stop(force=('ARVADOS_TEST_API_HOST' not in os.environ))
801 elif args.action == 'start_ws':
803 elif args.action == 'stop_ws':
805 elif args.action == 'start_keep':
806 run_keep(enforce_permissions=args.keep_enforce_permissions, num_servers=args.num_keep_servers)
807 elif args.action == 'stop_keep':
808 stop_keep(num_servers=args.num_keep_servers)
809 elif args.action == 'start_keep_proxy':
811 elif args.action == 'stop_keep_proxy':
813 elif args.action == 'start_arv-git-httpd':
815 elif args.action == 'stop_arv-git-httpd':
817 elif args.action == 'start_keep-web':
819 elif args.action == 'stop_keep-web':
821 elif args.action == 'start_nginx':
823 elif args.action == 'stop_nginx':
826 raise Exception("action recognized but not implemented!?")