Allow graceful exiting with SIGINT and SIGTERM
The test_loop function was only gracefully interrupted with a keyboard interrupt before. This is fine for interactive testing, but in an automated scenario the script may be running in the background and need to receive a signal from some other process, such as Ansible. This patch adds a handler for SIGINT and SIGTERM that will allow the current iteration of the loop to finish, then exit the program cleanly by putting the test_loop function into a class. The test_loop function is not refactored other than to add the `stop_now` flag, though the internal variables may be amenable to later refactoring to use the class. Change-Id: I0667d2c7093e2821afdfcea987cec6b58515885f
This commit is contained in:
parent
56ac318f21
commit
325076bef6
@ -25,6 +25,7 @@ from keystoneauth1.exceptions.http import InternalServerError
|
|||||||
from keystoneclient.v3 import client as key_client
|
from keystoneclient.v3 import client as key_client
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from glanceclient import Client
|
from glanceclient import Client
|
||||||
@ -145,7 +146,7 @@ class KeystoneTest(ServiceTest):
|
|||||||
# the test_loop function
|
# the test_loop function
|
||||||
try:
|
try:
|
||||||
keystone.projects.list()
|
keystone.projects.list()
|
||||||
msg = "Project lest retrieved"
|
msg = "Project list retrieved"
|
||||||
except InternalServerError:
|
except InternalServerError:
|
||||||
msg = "Failed to get project list"
|
msg = "Failed to get project list"
|
||||||
return msg
|
return msg
|
||||||
@ -196,23 +197,38 @@ class GlanceTest(ServiceTest):
|
|||||||
return glance_endpoint.url
|
return glance_endpoint.url
|
||||||
|
|
||||||
|
|
||||||
def test_loop(test):
|
class TestRunner(object):
|
||||||
"""Main loop to execute tests
|
"""Run a test in a loop, with the option to gracefully exit"""
|
||||||
|
stop_now = False
|
||||||
|
|
||||||
Executes and times interactions with OpenStack services to gather timing
|
def __init__(self):
|
||||||
data.
|
signal.signal(signal.SIGINT, self.prep_exit)
|
||||||
:param: test - on object that performs some action
|
signal.signal(signal.SIGTERM, self.prep_exit)
|
||||||
against an OpenStack service API.
|
|
||||||
"""
|
def prep_exit(self, signum, frame):
|
||||||
disconnected = None
|
self.stop_now = True
|
||||||
# Has to be a tuple for python syntax reasons.
|
logger.info("Received signal, stopping")
|
||||||
# This is currently the set needed for glance; should probably
|
|
||||||
# provide some way of letting a test say which exceptions should
|
def test_loop(self, test):
|
||||||
# be caught for a service.
|
"""Main loop to execute tests
|
||||||
exc_list = (ConnectFailure, InternalServerError, BadGateway,
|
|
||||||
glance_exc.CommunicationError,
|
Executes and times interactions with OpenStack services to gather
|
||||||
glance_exc.HTTPInternalServerError)
|
timing data.
|
||||||
try:
|
|
||||||
|
Execution can be ended by sending SIGINT or SIGTERM and the running
|
||||||
|
test will finish.
|
||||||
|
|
||||||
|
:param: test - on object that performs some action
|
||||||
|
against an OpenStack service API.
|
||||||
|
"""
|
||||||
|
disconnected = None
|
||||||
|
# Has to be a tuple for python syntax reasons.
|
||||||
|
# This is currently the set needed for glance; should probably
|
||||||
|
# provide some way of letting a test say which exceptions should
|
||||||
|
# be caught for a service.
|
||||||
|
exc_list = (ConnectFailure, InternalServerError, BadGateway,
|
||||||
|
glance_exc.CommunicationError,
|
||||||
|
glance_exc.HTTPInternalServerError)
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
# Pause for a bit so we're not generating more data than we
|
# Pause for a bit so we're not generating more data than we
|
||||||
@ -249,8 +265,9 @@ def test_loop(test):
|
|||||||
except (exc_list):
|
except (exc_list):
|
||||||
if not disconnected:
|
if not disconnected:
|
||||||
disconnected = datetime.datetime.now()
|
disconnected = datetime.datetime.now()
|
||||||
except KeyboardInterrupt:
|
|
||||||
sys.exit()
|
if self.stop_now:
|
||||||
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
available_tests = {
|
available_tests = {
|
||||||
@ -294,4 +311,6 @@ if __name__ == "__main__":
|
|||||||
target_test = target_test_class()
|
target_test = target_test_class()
|
||||||
target_test.configure_logger(logger)
|
target_test.configure_logger(logger)
|
||||||
|
|
||||||
test_loop(target_test)
|
runner = TestRunner()
|
||||||
|
|
||||||
|
runner.test_loop(target_test)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user