From ea55695715ce5e8d78319a4b49f333ce556ce130 Mon Sep 17 00:00:00 2001 From: Nikolay Stanchev <ns17@it-innovation.soton.ac.uk> Date: Tue, 22 May 2018 09:54:02 +0100 Subject: [PATCH] Added tests for the aggregator starter. --- src/clmc-webservice/clmcservice/tests.py | 91 ++++++++++++++++++++---- src/clmc-webservice/clmcservice/views.py | 12 +++- 2 files changed, 86 insertions(+), 17 deletions(-) diff --git a/src/clmc-webservice/clmcservice/tests.py b/src/clmc-webservice/clmcservice/tests.py index a0212fb..00aa9e2 100644 --- a/src/clmc-webservice/clmcservice/tests.py +++ b/src/clmc-webservice/clmcservice/tests.py @@ -24,13 +24,15 @@ import pytest from pyramid import testing from pyramid.httpexceptions import HTTPBadRequest - +from time import sleep from clmcservice.utilities import CONFIG_ATTRIBUTES +import os +import signal -class TestAggregatorConfig(object): +class TestAggregator(object): """ - A pytest-implementation test for the aggregator configuration API calls + A pytest-implementation test for the aggregator API calls """ @pytest.fixture(autouse=True) @@ -123,20 +125,81 @@ class TestAggregatorConfig(object): assert error_raised, "Error must be raised in case of an invalid argument." + def test_start(self): + """ + Tests the case of starting the aggregator through an API call. + """ -class TestAggregatorStarter(object): - """ - A pytest-implementation test for the aggregator starter API calls - """ + from clmcservice.views import aggregator_starter # nested import so that importing the class view is part of the test itself - def test_start(self): - #TODO - pass + assert not self.config.get_settings().get('aggregator_running'), "Initially aggregator is not running." + + request = testing.DummyRequest() + input_body = '{"action": "start"}' + request.body = input_body.encode(request.charset) + + response = aggregator_starter(request) + assert response == {'aggregator_running': True}, "The aggregator should have been started." + assert self.config.get_settings().get('aggregator_running'), "The aggregator should have been started." + + # kill the started process after the test is over + pid = request.registry.settings["aggregator_pid"] + os.kill(pid, signal.SIGTERM) def test_stop(self): - #TODO - pass + from clmcservice.views import aggregator_starter # nested import so that importing the class view is part of the test itself + + assert not self.config.get_settings().get('aggregator_running'), "Initially aggregator is not running." + + # send a start request to trigger the aggregator + request = testing.DummyRequest() + input_body = '{"action": "start"}' + request.body = input_body.encode(request.charset) + aggregator_starter(request) + + # test stopping the aggregator process when it is running + request = testing.DummyRequest() + input_body = '{"action": "stop"}' + request.body = input_body.encode(request.charset) + + response = aggregator_starter(request) + assert response == {'aggregator_running': False}, "The aggregator should have been started." + assert not self.config.get_settings().get('aggregator_running'), "The aggregator should have been started." + + sleep(2) + + # test stopping the aggregator process when it is not running + request = testing.DummyRequest() + input_body = '{"action": "stop"}' + request.body = input_body.encode(request.charset) + + response = aggregator_starter(request) + assert response == {'aggregator_running': False}, "The aggregator should have been started." + assert not self.config.get_settings().get('aggregator_running'), "The aggregator should have been started." def test_restart(self): - #TODO - pass + from clmcservice.views import aggregator_starter # nested import so that importing the class view is part of the test itself + + assert not self.config.get_settings().get('aggregator_running'), "Initially aggregator is not running." + + # test restarting the aggregator process when it is stopped + request = testing.DummyRequest() + input_body = '{"action": "restart"}' + request.body = input_body.encode(request.charset) + + response = aggregator_starter(request) + assert response == {'aggregator_running': True}, "The aggregator should have been started." + assert self.config.get_settings().get('aggregator_running'), "The aggregator should have been started." + + # test restarting the aggregator process when it is running + request = testing.DummyRequest() + input_body = '{"action": "restart"}' + request.body = input_body.encode(request.charset) + + response = aggregator_starter(request) + assert response == {'aggregator_running': True}, "The aggregator should have been started." + assert self.config.get_settings().get('aggregator_running'), "The aggregator should have been started." + + # kill the started process after the test is over + pid = request.registry.settings["aggregator_pid"] + os.kill(pid, signal.SIGTERM) diff --git a/src/clmc-webservice/clmcservice/views.py b/src/clmc-webservice/clmcservice/views.py index 70e4838..4fc47ff 100644 --- a/src/clmc-webservice/clmcservice/views.py +++ b/src/clmc-webservice/clmcservice/views.py @@ -36,6 +36,7 @@ def start_aggregator(config): An auxiliary method to start the aggregator. :param config: the configuration containing the arguments for the aggregator + :return: the process ID of the started aggregator script """ global _process @@ -44,7 +45,9 @@ def start_aggregator(config): command = ['python', 'aggregator.py', '--period', str(config.get('aggregator_report_period')), '--database', config.get('aggregator_database_name'), '--url', config.get('aggregator_database_url')] _process = Popen(command, cwd=dir_path, stdout=DEVNULL, stderr=DEVNULL, stdin=DEVNULL) - print("Started aggregator process with ID: {0}".format(_process.pid)) + print("\nStarted aggregator process with PID: {0}\n".format(_process.pid)) + + return _process.pid def stop_aggregator(): @@ -57,6 +60,7 @@ def stop_aggregator(): # check if the process is started before trying to terminate it - _process.poll() only returns something if the process has terminated, hence we check for a None value if _process is not None and _process.poll() is None: _process.terminate() + print("\nStopped aggregator process with PID: {0}\n".format(_process.pid)) @view_defaults(route_name='aggregator_config', renderer='json') @@ -133,15 +137,17 @@ def aggregator_starter(request): action = content['action'] if action == 'start': - start_aggregator(config) + pid = start_aggregator(config) request.registry.settings[STATUS_ATTRIBUTE] = True + request.registry.settings["aggregator_pid"] = pid elif action == 'stop': stop_aggregator() request.registry.settings[STATUS_ATTRIBUTE] = False elif action == 'restart': stop_aggregator() - start_aggregator(config) + pid = start_aggregator(config) request.registry.settings[STATUS_ATTRIBUTE] = True + request.registry.settings["aggregator_pid"] = pid return {STATUS_ATTRIBUTE: request.registry.settings.get(STATUS_ATTRIBUTE)} -- GitLab