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)
114 # already exited, or isn't our child process
118 os.kill(server_pid, signal.SIGTERM)
119 print("Sent SIGTERM to {} ({})".format(server_pid, pidfile),
121 except OSError as error:
122 if error.errno == errno.ESRCH:
123 # Thrown by os.getpgid() or os.kill() if the process
124 # does not exist, i.e., our work here is done.
130 print("Server PID {} ({}) did not exit, giving up after {}s".
131 format(server_pid, pidfile, wait),
134 def find_available_port():
135 """Return an IPv4 port number that is not in use right now.
137 We assume whoever needs to use the returned port is able to reuse
138 a recently used port without waiting for TIME_WAIT (see
139 SO_REUSEADDR / SO_REUSEPORT).
141 Some opportunity for races here, but it's better than choosing
142 something at random and not checking at all. If all of our servers
143 (hey Passenger) knew that listening on port 0 was a thing, the OS
144 would take care of the races, and this wouldn't be needed at all.
147 sock = socket.socket()
148 sock.bind(('0.0.0.0', 0))
149 port = sock.getsockname()[1]
153 def _wait_until_port_listens(port, timeout=10):
154 """Wait for a process to start listening on the given port.
156 If nothing listens on the port within the specified timeout (given
157 in seconds), print a warning on stderr before returning.
160 subprocess.check_output(['which', 'lsof'])
161 except subprocess.CalledProcessError:
162 print("WARNING: No `lsof` -- cannot wait for port to listen. "+
163 "Sleeping 0.5 and hoping for the best.",
167 deadline = time.time() + timeout
168 while time.time() < deadline:
170 subprocess.check_output(
171 ['lsof', '-t', '-i', 'tcp:'+str(port)])
172 except subprocess.CalledProcessError:
177 "WARNING: Nothing is listening on port {} (waited {} seconds).".
178 format(port, timeout),
181 def _fifo2stderr(label):
182 """Create a fifo, and copy it to stderr, prepending label to each line.
184 Return value is the path to the new FIFO.
186 +label+ should contain only alphanumerics: it is also used as part
187 of the FIFO filename.
189 fifo = os.path.join(TEST_TMPDIR, label+'.fifo')
192 except OSError as error:
193 if error.errno != errno.ENOENT:
195 os.mkfifo(fifo, 0700)
197 ['stdbuf', '-i0', '-oL', '-eL', 'sed', '-e', 's/^/['+label+'] /', fifo],
201 def run(leave_running_atexit=False):
202 """Ensure an API server is running, and ARVADOS_API_* env vars have
203 admin credentials for it.
205 If ARVADOS_TEST_API_HOST is set, a parent process has started a
206 test server for us to use: we just need to reset() it using the
209 If a previous call to run() started a new server process, and it
210 is still running, we just need to reset() it to fixture state and
213 If neither of those options work out, we'll really start a new
218 # Delete cached discovery documents.
220 # This will clear cached docs that belong to other processes (like
221 # concurrent test suites) even if they're still running. They should
222 # be able to tolerate that.
223 for fn in glob.glob(os.path.join(arvados.http_cache('discovery'),
224 '*,arvados,v1,rest,*')):
227 pid_file = _pidfile('api')
228 pid_file_ok = find_server_pid(pid_file, 0)
230 existing_api_host = os.environ.get('ARVADOS_TEST_API_HOST', my_api_host)
231 if existing_api_host and pid_file_ok:
232 if existing_api_host == my_api_host:
236 # Fall through to shutdown-and-start case.
239 # Server was provided by parent. Can't recover if it's
243 # Before trying to start up our own server, call stop() to avoid
244 # "Phusion Passenger Standalone is already running on PID 12345".
245 # (If we've gotten this far, ARVADOS_TEST_API_HOST isn't set, so
246 # we know the server is ours to kill.)
249 restore_cwd = os.getcwd()
250 api_src_dir = os.path.join(SERVICES_SRC_DIR, 'api')
251 os.chdir(api_src_dir)
253 # Either we haven't started a server of our own yet, or it has
254 # died, or we have lost our credentials, or something else is
255 # preventing us from calling reset(). Start a new one.
257 if not os.path.exists('tmp'):
260 if not os.path.exists('tmp/api'):
261 os.makedirs('tmp/api')
263 if not os.path.exists('tmp/logs'):
264 os.makedirs('tmp/logs')
266 if not os.path.exists('tmp/self-signed.pem'):
267 # We assume here that either passenger reports its listening
268 # address as https:/0.0.0.0:port/. If it reports "127.0.0.1"
269 # then the certificate won't match the host and reset() will
270 # fail certificate verification. If it reports "localhost",
271 # clients (notably Python SDK's websocket client) might
272 # resolve localhost as ::1 and then fail to connect.
273 subprocess.check_call([
274 'openssl', 'req', '-new', '-x509', '-nodes',
275 '-out', 'tmp/self-signed.pem',
276 '-keyout', 'tmp/self-signed.key',
278 '-subj', '/CN=0.0.0.0'],
281 # Install the git repository fixtures.
282 gitdir = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'git')
283 gittarball = os.path.join(SERVICES_SRC_DIR, 'api', 'test', 'test.git.tar')
284 if not os.path.isdir(gitdir):
286 subprocess.check_output(['tar', '-xC', gitdir, '-f', gittarball])
288 # The nginx proxy isn't listening here yet, but we need to choose
289 # the wss:// port now so we can write the API server config file.
290 wss_port = find_available_port()
291 _setport('wss', wss_port)
293 port = find_available_port()
294 env = os.environ.copy()
295 env['RAILS_ENV'] = 'test'
296 env['ARVADOS_TEST_WSS_PORT'] = str(wss_port)
297 env.pop('ARVADOS_WEBSOCKETS', None)
298 env.pop('ARVADOS_TEST_API_HOST', None)
299 env.pop('ARVADOS_API_HOST', None)
300 env.pop('ARVADOS_API_HOST_INSECURE', None)
301 env.pop('ARVADOS_API_TOKEN', None)
302 start_msg = subprocess.check_output(
304 'passenger', 'start', '-d', '-p{}'.format(port),
305 '--pid-file', pid_file,
306 '--log-file', os.path.join(os.getcwd(), 'log/test.log'),
308 '--ssl-certificate', 'tmp/self-signed.pem',
309 '--ssl-certificate-key', 'tmp/self-signed.key'],
312 if not leave_running_atexit:
313 atexit.register(kill_server_pid, pid_file, passenger_root=api_src_dir)
315 match = re.search(r'Accessible via: https://(.*?)/', start_msg)
318 "Passenger did not report endpoint: {}".format(start_msg))
319 my_api_host = match.group(1)
320 os.environ['ARVADOS_API_HOST'] = my_api_host
322 # Make sure the server has written its pid file and started
323 # listening on its TCP port
324 find_server_pid(pid_file)
325 _wait_until_port_listens(port)
328 os.chdir(restore_cwd)
331 """Reset the test server to fixture state.
333 This resets the ARVADOS_TEST_API_HOST provided by a parent process
334 if any, otherwise the server started by run().
336 It also resets ARVADOS_* environment vars to point to the test
337 server with admin credentials.
339 existing_api_host = os.environ.get('ARVADOS_TEST_API_HOST', my_api_host)
340 token = auth_token('admin')
341 httpclient = httplib2.Http(ca_certs=os.path.join(
342 SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.pem'))
344 'https://{}/database/reset'.format(existing_api_host),
346 headers={'Authorization': 'OAuth2 {}'.format(token)})
347 os.environ['ARVADOS_API_HOST_INSECURE'] = 'true'
348 os.environ['ARVADOS_API_HOST'] = existing_api_host
349 os.environ['ARVADOS_API_TOKEN'] = token
351 def stop(force=False):
352 """Stop the API server, if one is running.
354 If force==False, kill it only if we started it ourselves. (This
355 supports the use case where a Python test suite calls run(), but
356 run() just uses the ARVADOS_TEST_API_HOST provided by the parent
357 process, and the test suite cleans up after itself by calling
358 stop(). In this case the test server provided by the parent
359 process should be left alone.)
361 If force==True, kill it even if we didn't start it
362 ourselves. (This supports the use case in __main__, where "run"
363 and "stop" happen in different processes.)
366 if force or my_api_host is not None:
367 kill_server_pid(_pidfile('api'))
371 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
374 port = find_available_port()
375 conf = os.path.join(TEST_TMPDIR, 'ws.yml')
376 with open(conf, 'w') as f:
389 """.format(os.environ['ARVADOS_API_HOST'],
391 ('info' if os.environ.get('ARVADOS_DEBUG', '') in ['','0'] else 'debug'),
393 _dbconfig('database'),
394 _dbconfig('username'),
395 _dbconfig('password')))
396 logf = open(_fifo2stderr('ws'), 'w')
397 ws = subprocess.Popen(
398 ["ws", "-config", conf],
399 stdin=open('/dev/null'), stdout=logf, stderr=logf, close_fds=True)
400 with open(_pidfile('ws'), 'w') as f:
402 _wait_until_port_listens(port)
407 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
409 kill_server_pid(_pidfile('ws'))
411 def _start_keep(n, keep_args):
412 keep0 = tempfile.mkdtemp()
413 port = find_available_port()
414 keep_cmd = ["keepstore",
415 "-volume={}".format(keep0),
416 "-listen=:{}".format(port),
417 "-pid="+_pidfile('keep{}'.format(n))]
419 for arg, val in keep_args.iteritems():
420 keep_cmd.append("{}={}".format(arg, val))
422 logf = open(_fifo2stderr('keep{}'.format(n)), 'w')
423 kp0 = subprocess.Popen(
424 keep_cmd, stdin=open('/dev/null'), stdout=logf, stderr=logf, close_fds=True)
426 with open(_pidfile('keep{}'.format(n)), 'w') as f:
427 f.write(str(kp0.pid))
429 with open("{}/keep{}.volume".format(TEST_TMPDIR, n), 'w') as f:
432 _wait_until_port_listens(port)
436 def run_keep(blob_signing_key=None, enforce_permissions=False, num_servers=2):
437 stop_keep(num_servers)
440 if not blob_signing_key:
441 blob_signing_key = 'zfhgfenhffzltr9dixws36j1yhksjoll2grmku38mi7yxd66h5j4q9w4jzanezacp8s6q0ro3hxakfye02152hncy6zml2ed0uc'
442 with open(os.path.join(TEST_TMPDIR, "keep.blob_signing_key"), "w") as f:
443 keep_args['-blob-signing-key-file'] = f.name
444 f.write(blob_signing_key)
445 keep_args['-enforce-permissions'] = str(enforce_permissions).lower()
446 with open(os.path.join(TEST_TMPDIR, "keep.data-manager-token-file"), "w") as f:
447 keep_args['-data-manager-token-file'] = f.name
448 f.write(auth_token('data_manager'))
449 keep_args['-never-delete'] = 'false'
453 host=os.environ['ARVADOS_API_HOST'],
454 token=os.environ['ARVADOS_API_TOKEN'],
457 for d in api.keep_services().list(filters=[['service_type','=','disk']]).execute()['items']:
458 api.keep_services().delete(uuid=d['uuid']).execute()
459 for d in api.keep_disks().list().execute()['items']:
460 api.keep_disks().delete(uuid=d['uuid']).execute()
462 for d in range(0, num_servers):
463 port = _start_keep(d, keep_args)
464 svc = api.keep_services().create(body={'keep_service': {
465 'uuid': 'zzzzz-bi6l4-keepdisk{:07d}'.format(d),
466 'service_host': 'localhost',
467 'service_port': port,
468 'service_type': 'disk',
469 'service_ssl_flag': False,
471 api.keep_disks().create(body={
472 'keep_disk': {'keep_service_uuid': svc['uuid'] }
475 # If keepproxy is running, send SIGHUP to make it discover the new
476 # keepstore services.
477 proxypidfile = _pidfile('keepproxy')
478 if os.path.exists(proxypidfile):
480 os.kill(int(open(proxypidfile).read()), signal.SIGHUP)
482 os.remove(proxypidfile)
485 kill_server_pid(_pidfile('keep{}'.format(n)))
486 if os.path.exists("{}/keep{}.volume".format(TEST_TMPDIR, n)):
487 with open("{}/keep{}.volume".format(TEST_TMPDIR, n), 'r') as r:
488 shutil.rmtree(r.read(), True)
489 os.unlink("{}/keep{}.volume".format(TEST_TMPDIR, n))
490 if os.path.exists(os.path.join(TEST_TMPDIR, "keep.blob_signing_key")):
491 os.remove(os.path.join(TEST_TMPDIR, "keep.blob_signing_key"))
493 def stop_keep(num_servers=2):
494 for n in range(0, num_servers):
497 def run_keep_proxy():
498 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
502 port = find_available_port()
503 env = os.environ.copy()
504 env['ARVADOS_API_TOKEN'] = auth_token('anonymous')
505 logf = open(_fifo2stderr('keepproxy'), 'w')
506 kp = subprocess.Popen(
508 '-pid='+_pidfile('keepproxy'),
509 '-listen=:{}'.format(port)],
510 env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf, close_fds=True)
514 host=os.environ['ARVADOS_API_HOST'],
515 token=auth_token('admin'),
517 for d in api.keep_services().list(
518 filters=[['service_type','=','proxy']]).execute()['items']:
519 api.keep_services().delete(uuid=d['uuid']).execute()
520 api.keep_services().create(body={'keep_service': {
521 'service_host': 'localhost',
522 'service_port': port,
523 'service_type': 'proxy',
524 'service_ssl_flag': False,
526 os.environ["ARVADOS_KEEP_SERVICES"] = "http://localhost:{}".format(port)
527 _setport('keepproxy', port)
528 _wait_until_port_listens(port)
530 def stop_keep_proxy():
531 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
533 kill_server_pid(_pidfile('keepproxy'))
535 def run_arv_git_httpd():
536 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
540 gitdir = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'git')
541 gitport = find_available_port()
542 env = os.environ.copy()
543 env.pop('ARVADOS_API_TOKEN', None)
544 logf = open(_fifo2stderr('arv-git-httpd'), 'w')
545 agh = subprocess.Popen(
547 '-repo-root='+gitdir+'/test',
548 '-address=:'+str(gitport)],
549 env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf)
550 with open(_pidfile('arv-git-httpd'), 'w') as f:
551 f.write(str(agh.pid))
552 _setport('arv-git-httpd', gitport)
553 _wait_until_port_listens(gitport)
555 def stop_arv_git_httpd():
556 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
558 kill_server_pid(_pidfile('arv-git-httpd'))
561 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
565 keepwebport = find_available_port()
566 env = os.environ.copy()
567 env['ARVADOS_API_TOKEN'] = auth_token('anonymous')
568 logf = open(_fifo2stderr('keep-web'), 'w')
569 keepweb = subprocess.Popen(
572 '-attachment-only-host=download:'+str(keepwebport),
573 '-listen=:'+str(keepwebport)],
574 env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf)
575 with open(_pidfile('keep-web'), 'w') as f:
576 f.write(str(keepweb.pid))
577 _setport('keep-web', keepwebport)
578 _wait_until_port_listens(keepwebport)
581 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
583 kill_server_pid(_pidfile('keep-web'))
586 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
590 nginxconf['KEEPWEBPORT'] = _getport('keep-web')
591 nginxconf['KEEPWEBDLSSLPORT'] = find_available_port()
592 nginxconf['KEEPWEBSSLPORT'] = find_available_port()
593 nginxconf['KEEPPROXYPORT'] = _getport('keepproxy')
594 nginxconf['KEEPPROXYSSLPORT'] = find_available_port()
595 nginxconf['GITPORT'] = _getport('arv-git-httpd')
596 nginxconf['GITSSLPORT'] = find_available_port()
597 nginxconf['WSPORT'] = _getport('ws')
598 nginxconf['WSSPORT'] = _getport('wss')
599 nginxconf['SSLCERT'] = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.pem')
600 nginxconf['SSLKEY'] = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'self-signed.key')
601 nginxconf['ACCESSLOG'] = _fifo2stderr('nginx_access_log')
603 conftemplatefile = os.path.join(MY_DIRNAME, 'nginx.conf')
604 conffile = os.path.join(TEST_TMPDIR, 'nginx.conf')
605 with open(conffile, 'w') as f:
608 lambda match: str(nginxconf.get(match.group(1))),
609 open(conftemplatefile).read()))
611 env = os.environ.copy()
612 env['PATH'] = env['PATH']+':/sbin:/usr/sbin:/usr/local/sbin'
614 nginx = subprocess.Popen(
616 '-g', 'error_log stderr info;',
617 '-g', 'pid '+_pidfile('nginx')+';',
619 env=env, stdin=open('/dev/null'), stdout=sys.stderr)
620 _setport('keep-web-dl-ssl', nginxconf['KEEPWEBDLSSLPORT'])
621 _setport('keep-web-ssl', nginxconf['KEEPWEBSSLPORT'])
622 _setport('keepproxy-ssl', nginxconf['KEEPPROXYSSLPORT'])
623 _setport('arv-git-httpd-ssl', nginxconf['GITSSLPORT'])
626 if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ:
628 kill_server_pid(_pidfile('nginx'))
630 def _pidfile(program):
631 return os.path.join(TEST_TMPDIR, program + '.pid')
633 def _portfile(program):
634 return os.path.join(TEST_TMPDIR, program + '.port')
636 def _setport(program, port):
637 with open(_portfile(program), 'w') as f:
640 # Returns 9 if program is not up.
641 def _getport(program):
643 return int(open(_portfile(program)).read())
648 global _cached_db_config
649 if not _cached_db_config:
650 _cached_db_config = yaml.load(open(os.path.join(
651 SERVICES_SRC_DIR, 'api', 'config', 'database.yml')))
652 return _cached_db_config['test'][key]
655 global _cached_config
657 return _cached_config[key]
658 def _load(f, required=True):
659 fullpath = os.path.join(SERVICES_SRC_DIR, 'api', 'config', f)
660 if not required and not os.path.exists(fullpath):
662 return yaml.load(fullpath)
663 cdefault = _load('application.default.yml')
664 csite = _load('application.yml', required=False)
666 for section in [cdefault.get('common',{}), cdefault.get('test',{}),
667 csite.get('common',{}), csite.get('test',{})]:
668 _cached_config.update(section)
669 return _cached_config[key]
672 '''load a fixture yaml file'''
673 with open(os.path.join(SERVICES_SRC_DIR, 'api', "test", "fixtures",
677 trim_index = yaml_file.index("# Test Helper trims the rest of the file")
678 yaml_file = yaml_file[0:trim_index]
681 return yaml.load(yaml_file)
683 def auth_token(token_name):
684 return fixture("api_client_authorizations")[token_name]["api_token"]
686 def authorize_with(token_name):
687 '''token_name is the symbolic name of the token from the api_client_authorizations fixture'''
688 arvados.config.settings()["ARVADOS_API_TOKEN"] = auth_token(token_name)
689 arvados.config.settings()["ARVADOS_API_HOST"] = os.environ.get("ARVADOS_API_HOST")
690 arvados.config.settings()["ARVADOS_API_HOST_INSECURE"] = "true"
692 class TestCaseWithServers(unittest.TestCase):
693 """TestCase to start and stop supporting Arvados servers.
695 Define any of MAIN_SERVER, KEEP_SERVER, and/or KEEP_PROXY_SERVER
696 class variables as a dictionary of keyword arguments. If you do,
697 setUpClass will start the corresponding servers by passing these
698 keyword arguments to the run, run_keep, and/or run_keep_server
699 functions, respectively. It will also set Arvados environment
700 variables to point to these servers appropriately. If you don't
701 run a Keep or Keep proxy server, setUpClass will set up a
702 temporary directory for Keep local storage, and set it as
705 tearDownClass will stop any servers started, and restore the
706 original environment.
711 KEEP_PROXY_SERVER = None
712 KEEP_WEB_SERVER = None
715 def _restore_dict(src, dest):
716 for key in dest.keys():
723 cls._orig_environ = os.environ.copy()
724 cls._orig_config = arvados.config.settings().copy()
725 cls._cleanup_funcs = []
726 os.environ.pop('ARVADOS_KEEP_SERVICES', None)
727 os.environ.pop('ARVADOS_EXTERNAL_CLIENT', None)
728 for server_kwargs, start_func, stop_func in (
729 (cls.MAIN_SERVER, run, reset),
730 (cls.WS_SERVER, run_ws, stop_ws),
731 (cls.KEEP_SERVER, run_keep, stop_keep),
732 (cls.KEEP_PROXY_SERVER, run_keep_proxy, stop_keep_proxy),
733 (cls.KEEP_WEB_SERVER, run_keep_web, stop_keep_web)):
734 if server_kwargs is not None:
735 start_func(**server_kwargs)
736 cls._cleanup_funcs.append(stop_func)
737 if (cls.KEEP_SERVER is None) and (cls.KEEP_PROXY_SERVER is None):
738 cls.local_store = tempfile.mkdtemp()
739 os.environ['KEEP_LOCAL_STORE'] = cls.local_store
740 cls._cleanup_funcs.append(
741 lambda: shutil.rmtree(cls.local_store, ignore_errors=True))
743 os.environ.pop('KEEP_LOCAL_STORE', None)
744 arvados.config.initialize()
747 def tearDownClass(cls):
748 for clean_func in cls._cleanup_funcs:
750 cls._restore_dict(cls._orig_environ, os.environ)
751 cls._restore_dict(cls._orig_config, arvados.config.settings())
754 if __name__ == "__main__":
757 'start_ws', 'stop_ws',
758 'start_keep', 'stop_keep',
759 'start_keep_proxy', 'stop_keep_proxy',
760 'start_keep-web', 'stop_keep-web',
761 'start_arv-git-httpd', 'stop_arv-git-httpd',
762 'start_nginx', 'stop_nginx',
764 parser = argparse.ArgumentParser()
765 parser.add_argument('action', type=str, help="one of {}".format(actions))
766 parser.add_argument('--auth', type=str, metavar='FIXTURE_NAME', help='Print authorization info for given api_client_authorizations fixture')
767 parser.add_argument('--num-keep-servers', metavar='int', type=int, default=2, help="Number of keep servers desired")
768 parser.add_argument('--keep-enforce-permissions', action="store_true", help="Enforce keep permissions")
770 args = parser.parse_args()
772 if args.action not in actions:
773 print("Unrecognized action '{}'. Actions are: {}.".
774 format(args.action, actions),
777 if args.action == 'start':
778 stop(force=('ARVADOS_TEST_API_HOST' not in os.environ))
779 run(leave_running_atexit=True)
780 host = os.environ['ARVADOS_API_HOST']
781 if args.auth is not None:
782 token = auth_token(args.auth)
783 print("export ARVADOS_API_TOKEN={}".format(pipes.quote(token)))
784 print("export ARVADOS_API_HOST={}".format(pipes.quote(host)))
785 print("export ARVADOS_API_HOST_INSECURE=true")
788 elif args.action == 'stop':
789 stop(force=('ARVADOS_TEST_API_HOST' not in os.environ))
790 elif args.action == 'start_ws':
792 elif args.action == 'stop_ws':
794 elif args.action == 'start_keep':
795 run_keep(enforce_permissions=args.keep_enforce_permissions, num_servers=args.num_keep_servers)
796 elif args.action == 'stop_keep':
797 stop_keep(num_servers=args.num_keep_servers)
798 elif args.action == 'start_keep_proxy':
800 elif args.action == 'stop_keep_proxy':
802 elif args.action == 'start_arv-git-httpd':
804 elif args.action == 'stop_arv-git-httpd':
806 elif args.action == 'start_keep-web':
808 elif args.action == 'stop_keep-web':
810 elif args.action == 'start_nginx':
812 elif args.action == 'stop_nginx':
815 raise Exception("action recognized but not implemented!?")