Skip to content

Commit

Permalink
Add test for KOLIBRI_LISTEN_PORT and some start/stop functionality le…
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaoming committed Jul 17, 2017
1 parent c9df722 commit 32e2429
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 20 deletions.
20 changes: 10 additions & 10 deletions kolibri/utils/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,19 +229,17 @@ def start(port=None, daemon=True):
update()

if port is None:
port = os.environ['KOLIBRI_LISTEN_PORT']
try:
port = int(os.environ['KOLIBRI_LISTEN_PORT'])
except ValueError:
logger.error("Invalid KOLIBRI_LISTEN_PORT, must be an integer")
raise

if not daemon:
logger.info("Running 'kolibri start' in foreground...")
else:
logger.info("Running 'kolibri start' as daemon (system service)")

# TODO: moved from server.start() but not sure where it should ideally be
# located. Question is if it should be run every time the server is started
# or if it depends on some kind of state change.
from kolibri.content.utils.annotation import update_channel_metadata_cache
update_channel_metadata_cache()

# Daemonize at this point, no more user output is needed
if daemon:

Expand All @@ -258,7 +256,7 @@ def start(port=None, daemon=True):
server.start(port=port)


def stop():
def stop(sys_exit=True):
"""
Stops the server unless it isn't running
"""
Expand Down Expand Up @@ -293,7 +291,8 @@ def stop():

if stopped:
logger.info("Server stopped")
sys.exit(0)
if sys_exit:
sys.exit(0)


def status():
Expand Down Expand Up @@ -552,7 +551,8 @@ def main(args=None):
return

if arguments['start']:
port = int(arguments['--port']) or None
port = arguments['--port']
port = int(port) if port else None
start(port, daemon=not arguments['--foreground'])
return

Expand Down
28 changes: 18 additions & 10 deletions kolibri/utils/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ def start(port=8080):
with open(PID_FILE, 'w') as f:
f.write("%d\n%d" % (os.getpid(), port))

# TODO: moved from server.start() but not sure where it should ideally be
# located. Question is if it should be run every time the server is started
# or if it depends on some kind of state change.
from kolibri.content.utils.annotation import update_channel_metadata_cache
update_channel_metadata_cache()

def rm_pid_file():
os.unlink(PID_FILE)

Expand Down Expand Up @@ -149,15 +155,17 @@ def _read_pid_file(filename):
if it exists. If the port number doesn't exist, then
port is None.
"""
try:
pid, port = open(filename, "r").readlines()
pid_file_lines = open(filename, "r").readlines()

if len(pid_file_lines) == 2:
pid, port = pid_file_lines
pid, port = int(pid), int(port)
except ValueError:
elif len(pid_file_lines) == 1:
# The file only had one line
try:
pid, port = int(open(filename, "r").read()), None
except ValueError:
pid, port = None, None
pid, port = int(pid_file_lines[0]), None
else:
raise ValueError("PID file must have 1 or two lines")

return pid, port


Expand Down Expand Up @@ -198,8 +206,8 @@ def get_status(): # noqa: max-complexity=16
# It's dead so assuming the startup went badly
else:
raise NotRunning(STATUS_FAILED_TO_START)
# Couldn't parse to int
except TypeError:
# Couldn't parse to int or empty PID file
except (TypeError, ValueError):
raise NotRunning(STATUS_STOPPED)
raise NotRunning(STATUS_STOPPED) # Stopped

Expand All @@ -210,7 +218,7 @@ def get_status(): # noqa: max-complexity=16
raise NotRunning(STATUS_PID_FILE_INVALID) # Invalid PID file

# PID file exists, but process is dead
if not pid_exists(pid):
if pid is None or not pid_exists(pid):
if os.path.isfile(STARTUP_LOCK):
raise NotRunning(STATUS_FAILED_TO_START) # Failed to start
raise NotRunning(STATUS_UNCLEAN_SHUTDOWN) # Unclean shutdown
Expand Down
24 changes: 24 additions & 0 deletions kolibri/utils/tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import copy
import logging
import pytest
import os

from kolibri.utils import cli

Expand Down Expand Up @@ -109,3 +110,26 @@ def test_parsing(self):
assert docopt[k] == v

assert django == django_expected

def test_kolibri_listen_port_env(self):
"""
Starts and stops the server, mocking the actual server.start()
Checks that the correct fallback port is used from the environment.
"""
test_port = 1234
# ENV VARS are always a string
os.environ['KOLIBRI_LISTEN_PORT'] = str(test_port)

def start_mock(port, *args, **kwargs):
assert port == test_port

from kolibri.utils import server

orig_start = server.start

try:
server.start = start_mock
cli.start(daemon=False)
cli.stop(sys_exit=False)
finally:
server.start = orig_start

0 comments on commit 32e2429

Please sign in to comment.