Skip to content

Commit b12b117

Browse files
committed
Ephemeris sleep - hopefully makes serve tests a bit more robust.
Copying the function until I migrate it and release Ephemeris with changes.
1 parent 016b923 commit b12b117

File tree

4 files changed

+101
-29
lines changed

4 files changed

+101
-29
lines changed

planemo/galaxy/ephemeris_sleep.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python
2+
'''Utility to do a blocking sleep until a Galaxy instance is responsive.
3+
This is useful in docker images, in RUN steps, where one needs to wait
4+
for a currently starting Galaxy to be alive, before API requests can be
5+
made successfully.
6+
The script functions by making repeated requests to
7+
``http(s)://fqdn/api/version``, an API which requires no authentication
8+
to access.'''
9+
10+
import sys
11+
import time
12+
from argparse import ArgumentParser
13+
14+
import requests
15+
16+
try:
17+
from .common_parser import get_common_args
18+
except ImportError:
19+
# This won't stay in Planemo long, main no longer functional.
20+
get_common_args = None
21+
22+
23+
def _parser():
24+
'''Constructs the parser object'''
25+
parent = get_common_args(login_required=False)
26+
parser = ArgumentParser(parents=[parent], usage="usage: python %(prog)s <options>",
27+
description="Script to sleep and wait for Galaxy to be alive.")
28+
parser.add_argument("--timeout",
29+
default=0, type=int,
30+
help="Galaxy startup timeout in seconds. The default value of 0 waits forever")
31+
return parser
32+
33+
34+
def _parse_cli_options():
35+
"""
36+
Parse command line options, returning `parse_args` from `ArgumentParser`.
37+
"""
38+
parser = _parser()
39+
return parser.parse_args()
40+
41+
42+
def sleep(galaxy_url, verbose=False, timeout=0):
43+
count = 0
44+
while True:
45+
try:
46+
result = requests.get(galaxy_url + '/api/version')
47+
try:
48+
result = result.json()
49+
if verbose:
50+
sys.stdout.write("Galaxy Version: %s\n" % result['version_major'])
51+
break
52+
except ValueError:
53+
if verbose:
54+
sys.stdout.write("[%02d] No valid json returned... %s\n" % (count, result.__str__()))
55+
sys.stdout.flush()
56+
except requests.exceptions.ConnectionError as e:
57+
if verbose:
58+
sys.stdout.write("[%02d] Galaxy not up yet... %s\n" % (count, str(e)[0:100]))
59+
sys.stdout.flush()
60+
count += 1
61+
62+
# If we cannot talk to galaxy and are over the timeout
63+
if timeout != 0 and count > timeout:
64+
sys.stderr.write("Failed to contact Galaxy\n")
65+
return False
66+
67+
time.sleep(1)
68+
69+
return True
70+
71+
72+
def main():
73+
"""
74+
Main function
75+
"""
76+
options = _parse_cli_options()
77+
78+
galaxy_alive = sleep(galaxy_url=options.galaxy, verbose=options.verbose, timeout=options.timeout)
79+
exit_code = 0 if galaxy_alive else 1
80+
sys.exit(exit_code)
81+
82+
83+
if __name__ == "__main__":
84+
main()

planemo/galaxy/serve.py

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33

44
import contextlib
55
import os
6-
import time
76

87
from planemo import io
98
from planemo import network_util
109
from .config import galaxy_config
10+
from .ephemeris_sleep import sleep
1111
from .run import (
1212
run_galaxy_command,
1313
)
@@ -50,19 +50,12 @@ def _serve(ctx, runnables, **kwds):
5050
io.warn(message)
5151
raise Exception(message)
5252
host = kwds.get("host", "127.0.0.1")
53+
5354
timeout = 500
5455
galaxy_url = "http://%s:%s" % (host, port)
55-
ctx.vlog("Waiting for URL %s" % galaxy_url)
56-
assert network_util.wait_http_service(galaxy_url, timeout=timeout)
57-
time.sleep(.1)
58-
ctx.vlog("Waiting for URL %s" % galaxy_url)
59-
assert network_util.wait_http_service(galaxy_url, timeout=timeout)
60-
time.sleep(5)
61-
ctx.vlog("Waiting for URL %s" % galaxy_url)
62-
assert network_util.wait_http_service(galaxy_url, timeout=timeout)
63-
version_url = "%s/api/version" % galaxy_url
64-
ctx.vlog("Waiting for URL %s" % version_url)
65-
assert network_util.wait_http_service(version_url, timeout=timeout)
56+
galaxy_alive = sleep(galaxy_url, verbose=ctx.verbose, timeout=timeout)
57+
if not galaxy_alive:
58+
raise Exception("Attempted to serve Galaxy at %s, but it failed to start in %d seconds." % (galaxy_url, timeout))
6659
config.install_workflows()
6760
if kwds.get("pid_file"):
6861
real_pid_file = config.pid_file

tests/test_cmd_serve.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66
from planemo.galaxy import api
77
from planemo.io import kill_pid_file
88
from .test_utils import (
9-
cli_daemon_service,
9+
cli_daemon_galaxy,
1010
CliTestCase,
11-
launch_and_wait_for_service,
11+
launch_and_wait_for_galaxy,
1212
mark,
1313
PROJECT_TEMPLATES_DIR,
1414
skip_if_environ,
@@ -95,13 +95,13 @@ def _test_serve_profile(self, *db_options):
9595
"--profile", new_profile,
9696
]
9797
serve_cmd = self._serve_command_list(extra_args)
98-
with cli_daemon_service(self._runner, self._pid_file, self._port, serve_cmd):
98+
with cli_daemon_galaxy(self._runner, self._pid_file, self._port, serve_cmd):
9999
user_gi = self._user_gi
100100
assert len(user_gi.histories.get_histories(name=TEST_HISTORY_NAME)) == 0
101101
user_gi.histories.create_history(TEST_HISTORY_NAME)
102102

103103
# TODO: Pretty sure this is getting killed, but we should verify.
104-
with cli_daemon_service(self._runner, self._pid_file, self._port, serve_cmd):
104+
with cli_daemon_galaxy(self._runner, self._pid_file, self._port, serve_cmd):
105105
assert len(user_gi.histories.get_histories(name=TEST_HISTORY_NAME)) == 1
106106

107107
def setUp(self):
@@ -118,7 +118,7 @@ def _user_gi(self):
118118
return user_gi
119119

120120
def _launch_thread_and_wait(self, func, args=[]):
121-
launch_and_wait_for_service(self._port, func, [args])
121+
launch_and_wait_for_galaxy(self._port, func, [args])
122122

123123
def _run_shed(self, serve_args=[]):
124124
return self._run(serve_args=serve_args, serve_cmd="shed_serve")

tests/test_utils.py

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import os
77
import shutil
88
import threading
9-
import time
109
import traceback
1110
from sys import version_info
1211
from tempfile import mkdtemp
@@ -16,9 +15,9 @@
1615

1716
from planemo import cli
1817
from planemo import io
19-
from planemo import network_util
2018
from planemo import shed
2119
from planemo.config import PLANEMO_CONFIG_ENV_PROP
20+
from planemo.galaxy.ephemeris_sleep import sleep
2221
from .shed_app_test_utils import (
2322
mock_shed,
2423
setup_mock_shed,
@@ -305,14 +304,14 @@ def check_exit_code(runner, command_list, exit_code=0):
305304

306305

307306
@contextlib.contextmanager
308-
def cli_daemon_service(runner, pid_file, port, command_list, exit_code=0):
309-
t = launch_and_wait_for_service(port, check_exit_code, args=[runner, command_list, exit_code])
307+
def cli_daemon_galaxy(runner, pid_file, port, command_list, exit_code=0):
308+
t = launch_and_wait_for_galaxy(port, check_exit_code, args=[runner, command_list, exit_code])
310309
yield
311310
io.kill_pid_file(pid_file)
312311
t.join(timeout=60)
313312

314313

315-
def launch_and_wait_for_service(port, func, args=[]):
314+
def launch_and_wait_for_galaxy(port, func, args=[]):
316315
"""Run func(args) in a thread and wait on port for service.
317316
318317
Service should remain up so check network a few times, this prevents
@@ -323,19 +322,15 @@ def launch_and_wait_for_service(port, func, args=[]):
323322
t = threading.Thread(target=target)
324323
t.daemon = True
325324
t.start()
326-
time.sleep(5)
327-
assert network_util.wait_net_service("127.0.0.1", port, timeout=600)
328-
time.sleep(1)
329-
assert network_util.wait_net_service("127.0.0.1", port, timeout=600)
330-
time.sleep(1)
331-
assert network_util.wait_net_service("127.0.0.1", port, timeout=600)
325+
sleep("http://localhost:%d" % port, timeout=600)
332326
return t
333327

334328

335329
# TODO: everything should be considered "exported".
336330
__all__ = (
337331
"assert_exists",
338-
"launch_and_wait_for_service",
332+
"cli_daemon_galaxy",
333+
"launch_and_wait_for_galaxy",
339334
"TestCase",
340335
"CliTestCase",
341336
)

0 commit comments

Comments
 (0)