Synergy enhancements

- serializer.py: improved serialization
- manager.py: Managers are now serializable
- command.py, shell.py: improved command shell by using the 'tabulate' module
- service.py: listManagers, startManager, stopManager and getManagerStatus methods now use the Managers serialization
- requirements.txt, test-requirements.txt: 'tabulate' module dependence added
- test_synergy.py, test_manager_abstract.py: updated unit tests
- setup.cfg: changed entry points

Change-Id: I657af749aa3fcb32c27b516c2b9f836c5ba0c690
This commit is contained in:
Lisa Zangrando 2016-08-30 12:16:25 +02:00 committed by Vincent Llorens
parent 07c15e9c93
commit 3c33d51dd4
10 changed files with 316 additions and 342 deletions

View File

@ -15,3 +15,4 @@ eventlet
oslo.config>=2.4.0,<3.0.0
oslo.messaging>=2.5.0,<3.0.0
python-dateutil
tabulate>=0.7.2,<0.8.0

View File

@ -26,13 +26,10 @@ scripts =
[entry_points]
synergy.managers =
timer = synergy.examples.timer_manager:TimerManager
TimerManager = synergy.examples.timer_manager:TimerManager
synergy.commands =
list = synergy.client.command:List
status = synergy.client.command:Status
start = synergy.client.command:Start
stop = synergy.client.command:Stop
manager = synergy.client.command:ManagerCommand
[build_sphinx]
source-dir = doc/source

View File

@ -1,6 +1,10 @@
import json
import requests
from synergy.common import utils
from tabulate import tabulate
__author__ = "Lisa Zangrando"
__email__ = "lisa.zangrando[AT]pd.infn.it"
__copyright__ = """Copyright (c) 2015 INFN - INDIGO-DataCloud
@ -31,10 +35,21 @@ class HTTPCommand(object):
def configureParser(self, subparser):
raise NotImplementedError("not implemented!")
def log(self):
raise NotImplementedError("not implemented!")
def objectHookHandler(self, parsed_dict):
if "synergy_object" in parsed_dict:
synergy_object = parsed_dict["synergy_object"]
try:
objClass = utils.import_class(synergy_object["name"])
def sendRequest(self, synergy_url, payload=None):
objInstance = objClass()
return objInstance.deserialize(parsed_dict)
except Exception as ex:
print(ex)
raise ex
else:
return parsed_dict
def execute(self, synergy_url, payload=None):
request = requests.get(synergy_url, params=payload)
if request.status_code != requests.codes.ok:
@ -44,180 +59,98 @@ class HTTPCommand(object):
self.results = request.json()
return request
try:
return json.loads(request.text, object_hook=self.objectHookHandler)
except Exception:
return request.json()
def getResults(self):
return self.results
class List(HTTPCommand):
class ManagerCommand(HTTPCommand):
def __init__(self):
super(List, self).__init__("list")
super(ManagerCommand, self).__init__("Manager")
def configureParser(self, subparser):
subparser.add_parser("list", add_help=True, help="list the managers")
manager_parser = subparser.add_parser('manager')
manager_parsers = manager_parser.add_subparsers(dest="command")
def sendRequest(self, synergy_url, args=None):
super(List, self).sendRequest(synergy_url + "/synergy/list")
manager_parsers.add_parser(
"list", add_help=True, help="list the managers")
def log(self):
results = self.getResults()
status_parser = manager_parsers.add_parser(
"status", add_help=True, help="show the managers status")
max_project_id = max(len(max(results, key=len)), len("manager"))
separator_str = "-" * (max_project_id + 4) + "\n"
format_str = "| {0:%ss} |\n" % (max_project_id)
status_parser.add_argument(
"manager", nargs='*', help="the managers list")
msg = separator_str
msg += format_str.format("manager")
msg += separator_str
start_parser = manager_parsers.add_parser(
"start", add_help=True, help="start the manager")
for manager in results:
msg += format_str.format(manager)
start_parser.add_argument(
"manager", nargs='+', help="the managers list")
msg += separator_str
print(msg)
stop_parser = manager_parsers.add_parser(
"stop", add_help=True, help="stop the manager")
stop_parser.add_argument(
"manager", nargs='+', help="the managers list")
def execute(self, synergy_url, args=None):
table = []
headers = []
url = synergy_url
if args.command == "list":
headers.append("manager")
url += "/synergy/list"
managers = super(ManagerCommand, self).execute(url)
for manager in managers:
table.append([manager.getName()])
else:
headers.append("manager")
headers.append("status")
headers.append("rate (min)")
url += "/synergy/" + args.command
managers = super(ManagerCommand, self).execute(
url, {"manager": args.manager})
if args.command == "status":
for manager in managers:
table.append([manager.getName(),
manager.getStatus(),
manager.getRate()])
else:
headers.append("details")
for manager in managers:
msg = manager.get("message")
table.append([manager.getName(),
manager.getStatus() + " (%s)" % msg,
manager.getRate()])
print(tabulate(table, headers, tablefmt="fancy_grid"))
class Start(HTTPCommand):
def __init__(self):
super(Start, self).__init__("start")
def configureParser(self, subparser):
parser = subparser.add_parser("start",
add_help=True,
help="start the managers")
parser.add_argument("manager", help="the manager to be started")
def sendRequest(self, synergy_url, args):
super(Start, self).sendRequest(synergy_url + "/synergy/start",
{"manager": args.manager})
def log(self):
results = self.getResults()
max_manager = max(len(max(results.keys(), key=len)), len("manager"))
max_status = len("status")
max_msg = len("message")
for result in results.values():
max_status = max(len(str(result["status"])), max_status)
max_msg = max(len(str(result["message"])), max_msg)
separator_str = "-" * (max_manager + max_status + max_msg + 10) + "\n"
format_str = "| {0:%ss} | {1:%ss} | {2:%ss} |\n" % (max_manager,
max_status,
max_msg)
msg = separator_str
msg += format_str.format("manager", "status", "message")
msg += separator_str
for manager, values in results.items():
msg += format_str.format(manager,
values["status"],
values["message"])
msg += separator_str
print(msg)
class Stop(HTTPCommand):
def __init__(self):
super(Stop, self).__init__("stop")
def configureParser(self, subparser):
parser = subparser.add_parser("stop",
add_help=True,
help="stop the managers")
parser.add_argument("manager", help="the manager to be stopped")
def sendRequest(self, synergy_url, args):
super(Stop, self).sendRequest(synergy_url + "/synergy/stop",
{"manager": args.manager})
def log(self):
results = self.getResults()
max_manager = max(len(max(results.keys(), key=len)), len("manager"))
max_status = len("status")
max_msg = len("message")
for result in results.values():
max_status = max(len(str(result["status"])), max_status)
max_msg = max(len(str(result["message"])), max_msg)
separator_str = "-" * (max_manager + max_status + max_msg + 10) + "\n"
format_str = "| {0:%ss} | {1:%ss} | {2:%ss} |\n" % (max_manager,
max_status,
max_msg)
msg = separator_str
msg += format_str.format("manager", "status", "message")
msg += separator_str
for manager, values in results.items():
msg += format_str.format(manager,
values["status"],
values["message"])
msg += separator_str
print(msg)
class Status(HTTPCommand):
def __init__(self):
super(Status, self).__init__("status")
def configureParser(self, subparser):
parser = subparser.add_parser("status",
add_help=True,
help="retrieve the manager's status")
parser.add_argument("manager", nargs='*', help="the managers list")
def sendRequest(self, synergy_url, args):
super(Status, self).sendRequest(synergy_url + "/synergy/status",
{"manager": args.manager})
def log(self):
results = self.getResults()
max_project_id = max(len(max(results.keys(), key=len)), len("manager"))
max_value = max(len(max(results.values(), key=len)), len("status"))
separator_str = "-" * (max_project_id + max_value + 7) + "\n"
format_str = "| {0:%ss} | {1:%ss} |\n" % (max_project_id, max_value)
msg = separator_str
msg += format_str.format("manager", "status")
msg += separator_str
for manager, status in results.items():
msg += format_str.format(manager, status)
msg += separator_str
print(msg)
class Execute(HTTPCommand):
class ExecuteCommand(HTTPCommand):
def __init__(self, name):
super(Execute, self).__init__(name)
super(ExecuteCommand, self).__init__(name)
def sendRequest(self, synergy_url, manager, command, args=None):
def execute(self, synergy_url, manager, command, args=None):
if args is None:
args = {}
url = synergy_url + "/synergy/execute"
payload = {"manager": manager,
"command": command,
"args": json.dumps(args)}
super(Execute, self).sendRequest(synergy_url + "/synergy/execute",
payload)
return super(ExecuteCommand, self).execute(url, payload)

View File

@ -175,8 +175,8 @@ def main():
if command_name not in commands:
print("command %r not found!" % command_name)
commands[command_name].sendRequest(synergy_url, args)
commands[command_name].log()
commands[command_name].execute(synergy_url, args)
# commands[command_name].log()
except KeyboardInterrupt as e:
print("Shutting down synergyclient")
sys.exit(1)

View File

@ -1,7 +1,9 @@
from serializer import SynergyObject
from threading import Condition
from threading import Event
from threading import Thread
__author__ = "Lisa Zangrando"
__email__ = "lisa.zangrando[AT]pd.infn.it"
__copyright__ = """Copyright (c) 2015 INFN - INDIGO-DataCloud
@ -21,18 +23,17 @@ See the License for the specific language governing
permissions and limitations under the License."""
class Manager(Thread):
class Manager(SynergyObject, Thread):
def __init__(self, name):
def __init__(self, name=None):
super(Manager, self).__init__()
self.setDaemon(True)
self.stop_event = Event()
self.config_opts = []
self.condition = Condition()
self.name = name
self.status = "CREATED"
self.autostart = False
self.rate = -1
self.stop_event = Event()
self.setDaemon(True)
self.setName(name)
self.setStatus("CREATED")
self.setRate(-1)
self.config_opts = []
self.paused = True # start out paused
self.managers = {}
@ -61,24 +62,30 @@ class Manager(Thread):
if manager.getName() != manager_name:
manager.doOnEvent(event_type, *args, **kargs)
def getName(self):
return self.name
def getOptions(self):
return self.config_opts
def getStatus(self):
return self.get("status")
def setStatus(self, status):
with self.condition:
self.set("status", status)
self.condition.notifyAll()
def isAutoStart(self):
return self.autostart
return self.get("autostart")
def setAutoStart(self, autostart):
self.autostart = autostart
self.paused = not self.autostart
self.set("autostart", autostart)
self.paused = not autostart
def getRate(self):
return self.rate
return self.get("rate")
def setRate(self, rate):
self.rate = rate
self.set("rate", rate)
def setup(self):
"""Manager initialization
@ -93,15 +100,6 @@ class Manager(Thread):
def destroy(self):
raise NotImplementedError
def getStatus(self):
return self.status
def setStatus(self, status):
with self.condition:
self.status = status
self.condition.notifyAll()
def stop(self):
if self.isAlive():
# set event to signal thread to terminate
@ -124,13 +122,13 @@ class Manager(Thread):
while not self.stop_event.isSet():
with self.condition:
if self.paused:
self.status = "ACTIVE"
self.setStatus("ACTIVE")
self.condition.wait()
else:
self.status = "RUNNING"
self.setStatus("RUNNING")
try:
self.task()
self.condition.wait(self.rate * 60)
self.condition.wait(self.getRate() * 60)
except Exception as ex:
print("task %r: %s" % (self.name, ex))
print("task %r: %s" % (self.getName(), ex))

View File

@ -1,9 +1,5 @@
try:
import oslo_messaging
except ImportError:
import oslo.messaging as oslo_messaging
from synergy.common import context as ctx
import datetime
from json import JSONEncoder
from synergy.common import utils
@ -35,128 +31,136 @@ class SynergyObject(object):
necessary "get" classmethod routines as well as "set" object methods
as appropriate.
"""
VERSION = "1.0"
def __init__(self, name=None):
def __init__(self):
super(SynergyObject, self).__init__()
self.attributes = {}
if name:
self.attributes["name"] = name
def getId(self):
return self.get("id")
def setId(self, id):
self.set("id", id)
def getName(self):
return self.attributes["name"]
return self.get("name")
def setName(self, name):
self.attributes["name"] = name
self.set("name", name)
def get(self, field=None):
def get(self, field):
return self.attributes.get(field, None)
def set(self, field, value):
self.attributes[field] = value
def setContext(self, context):
self.context = context
if isinstance(value, unicode):
self.attributes[field] = str(value)
else:
self.attributes[field] = value
def setAttributes(self, attributes):
if attributes:
self.attributes = attributes
@classmethod
def deserialize(cls, context, entity):
if "synergy_object.namespace" not in entity:
raise Exception("synergy_object.namespace nof defined!")
def deserialize(cls, entity):
if "synergy_object" not in entity:
raise Exception("it seems not a Synergy object!")
if "synergy_object.name" not in entity:
raise Exception("synergy_object.name nof defined!")
synergy_object = entity["synergy_object"]
if "synergy_object.version" not in entity:
raise Exception("synergy_object.version nof defined!")
if "namespace" not in synergy_object:
raise Exception("synergy_object.namespace not defined!")
if entity["synergy_object.namespace"] != 'synergy':
if "name" not in synergy_object:
raise Exception("synergy_object.name not defined!")
if "version" not in synergy_object:
raise Exception("synergy_object.version mismatch!")
if synergy_object["version"] != cls.VERSION:
raise Exception("synergy_object.version mis!")
if synergy_object["namespace"] != "synergy":
raise Exception("unsupported object objtype='%s.%s"
% (entity["synergy_object.namespace"],
entity["synergy_object.name"]))
% (synergy_object["namespace"],
synergy_object["name"]))
objName = entity['synergy_object.name']
# objVer = entity['synergy_object.version']
objClass = utils.import_class(objName)
objInstance = None
# objInstance = objClass(context=context, data=entity)
try:
objName = synergy_object["name"]
# objVer = synergy_object['version']
objClass = utils.import_class(objName)
objInstance = objClass()
except Exception as ex:
print(ex)
raise Exception("error on deserializing the object %r: %s"
% (objName, ex))
objInstance = objClass(name=None)
objInstance.setContext(context)
objInstance.setAttributes(entity)
del entity["synergy_object"]
for key, value in entity.items():
if isinstance(value, dict):
if "synergy_object" in value:
objInstance.set(key, SynergyObject.deserialize(value))
else:
objInstance.set(key, value)
elif isinstance(value, list):
l = []
objInstance.set(key, l)
for item in value:
if isinstance(item, dict) and "synergy_object" in item:
l.append(SynergyObject.deserialize(item))
else:
l.append(item)
else:
objInstance.set(key, value)
return objInstance
def serialize(self):
name = self.__class__.__module__ + "." + self.__class__.__name__
self.attributes['synergy_object.name'] = name
self.attributes['synergy_object.version'] = self.VERSION
self.attributes['synergy_object.namespace'] = 'synergy'
return self.attributes
"""
def log(self):
result = {"synergy_object": {}}
result["synergy_object"]["name"] = name
result["synergy_object"]["version"] = self.VERSION
result["synergy_object"]["namespace"] = "synergy"
for key, value in self.attributes.items():
LOG.info("%s = %s" % (key, value))
"""
if isinstance(value, SynergyObject):
result[key] = value.serialize()
elif isinstance(value, dict):
result[key] = {}
for k, v in value.items():
if isinstance(v, SynergyObject):
result[key][k] = v.serialize()
else:
result[key][k] = v
elif isinstance(value, list):
result[key] = []
class SynergySerializer(oslo_messaging.Serializer):
def __init__(self):
super(SynergySerializer, self).__init__()
def serialize_entity(self, context, entity):
if not entity:
return entity
if isinstance(entity, SynergyObject):
entity = entity.serialize()
elif isinstance(entity, dict):
result = {}
for key, value in entity.items():
result[key] = self.serialize_entity(context, value)
entity = result
return entity
def deserialize_entity(self, context, entity):
if isinstance(entity, dict):
if 'synergy_object.name' in entity:
entity = SynergyObject.deserialize(context, entity)
for item in value:
if isinstance(item, SynergyObject):
result[key].append(item.serialize())
else:
result[key].append(item)
elif isinstance(value, datetime.datetime):
result[key] = value.isoformat()
else:
result = {}
result[key] = value
for key, value in entity.items():
result[key] = self.deserialize_entity(context, value)
entity = result
return entity
def serialize_context(self, context):
return context.toDict()
def deserialize_context(self, context):
return ctx.RequestContext.fromDict(context)
return result
class RequestContextSerializer(oslo_messaging.Serializer):
def __init__(self):
pass
def serialize_entity(self, context, entity):
return entity
def deserialize_entity(self, context, entity):
return entity
def serialize_context(self, context):
return context.toDict()
def deserialize_context(self, context):
return ctx.RequestContext.fromDict(context)
class SynergyEncoder(JSONEncoder):
def default(self, obj):
if isinstance(obj, SynergyObject):
return obj.serialize()
else:
return JSONEncoder.default(self, obj)

View File

@ -15,8 +15,11 @@ except ImportError:
from oslo.config import cfg
from synergy.common import config
from synergy.common import service
from synergy.common import wsgi
from synergy.common.manager import Manager
from synergy.common.serializer import SynergyEncoder
from synergy.common.service import Service
from synergy.common.wsgi import Server
__author__ = "Lisa Zangrando"
__email__ = "lisa.zangrando[AT]pd.infn.it"
@ -76,7 +79,7 @@ def setLogger(name):
logger.addHandler(handler)
class Synergy(service.Service):
class Synergy(Service):
"""Service object for binaries running on hosts.
A service takes a manager and enables rpc by listening to queues based
@ -98,8 +101,7 @@ class Synergy(service.Service):
manager_class = entry.load()
manager_obj = manager_class(*args, **kwargs)
LOG.info("manager instance %r created!", entry.name)
manager_obj.setName(entry.name)
manager_obj.setAutoStart(CONF.get(entry.name).autostart)
manager_obj.setRate(CONF.get(entry.name).rate)
@ -137,14 +139,18 @@ class Synergy(service.Service):
result = []
for name, manager in self.managers.items():
result.append(name)
m = Manager(name)
m.setStatus(manager.getStatus())
m.setRate(manager.getRate())
result.append(m)
start_response("200 OK", [("Content-Type", "text/html")])
return ["%s" % json.dumps(result)]
return ["%s" % json.dumps(result, cls=SynergyEncoder)]
def getManagerStatus(self, environ, start_response):
manager_list = None
result = {}
result = []
query = environ.get("QUERY_STRING", None)
@ -165,14 +171,20 @@ class Synergy(service.Service):
manager_name = escape(manager_name)
if manager_name in self.managers:
result[manager_name] = self.managers[manager_name].getStatus()
manager = self.managers[manager_name]
m = Manager(manager_name)
m.setStatus(manager.getStatus())
m.setRate(manager.getRate())
result.append(m)
if len(manager_list) == 1 and len(result) == 0:
start_response("404 NOT FOUND", [("Content-Type", "text/plain")])
return ["manager %r not found!" % manager_list[0]]
start_response("200 OK", [("Content-Type", "text/html")])
return ["%s" % json.dumps(result)]
return ["%s" % json.dumps(result, cls=SynergyEncoder)]
def executeCommand(self, environ, start_response):
manager_name = None
@ -215,16 +227,8 @@ class Synergy(service.Service):
try:
result = manager.execute(command=command, **manager_args)
if not isinstance(result, dict):
try:
result = result.toDict()
except Exception:
result = result.__dict__
LOG.debug("execute command: result=%s" % result)
start_response("200 OK", [("Content-Type", "text/html")])
return ["%s" % json.dumps(result)]
return ["%s" % json.dumps(result, cls=SynergyEncoder)]
except Exception as ex:
LOG.debug("execute command: error=%s" % ex)
start_response("500 INTERNAL SERVER ERROR",
@ -233,7 +237,7 @@ class Synergy(service.Service):
def startManager(self, environ, start_response):
manager_list = None
result = {}
result = []
query = environ.get("QUERY_STRING", None)
@ -258,9 +262,11 @@ class Synergy(service.Service):
if manager_name not in self.managers:
continue
result[manager_name] = {}
manager = self.managers[manager_name]
m = Manager(manager_name)
m.setRate(manager.getRate())
result.append(m)
if manager.getStatus() == "ACTIVE":
LOG.info("starting the %r manager" % (manager_name))
@ -270,25 +276,25 @@ class Synergy(service.Service):
LOG.info("%r manager started! (rate=%s min)"
% (manager_name, manager.getRate()))
result[manager_name]["status"] = "RUNNING"
result[manager_name]["message"] = "started successfully"
m.setStatus("RUNNING")
m.set("message", "started successfully")
elif manager.getStatus() == "RUNNING":
result[manager_name]["status"] = "RUNNING"
result[manager_name]["message"] = "WARN: already started"
m.setStatus("RUNNING")
m.set("message", "WARN: already started")
elif manager.getStatus() == "ERROR":
result[manager_name]["status"] = "ERROR"
result[manager_name]["message"] = "wrong state"
m.setStatus("ERROR")
m.set("message", "wrong state")
if len(manager_list) == 1 and len(result) == 0:
start_response("404 NOT FOUND", [("Content-Type", "text/plain")])
return ["manager %r not found!" % manager_list[0]]
start_response("200 OK", [("Content-Type", "text/html")])
return ["%s" % json.dumps(result)]
return ["%s" % json.dumps(result, cls=SynergyEncoder)]
def stopManager(self, environ, start_response):
manager_list = None
result = {}
result = []
query = environ.get("QUERY_STRING", None)
@ -313,10 +319,13 @@ class Synergy(service.Service):
if manager_name not in self.managers:
continue
result[manager_name] = {}
manager = self.managers[manager_name]
m = Manager(manager_name)
m.setRate(manager.getRate())
result.append(m)
if manager.getStatus() == "RUNNING":
LOG.info("stopping the %r manager" % (manager_name))
@ -324,21 +333,21 @@ class Synergy(service.Service):
LOG.info("%r manager stopped!" % (manager_name))
result[manager_name]["status"] = "ACTIVE"
result[manager_name]["message"] = "stopped successfully"
m.setStatus("ACTIVE")
m.set("message", "stopped successfully")
elif manager.getStatus() == "ACTIVE":
result[manager_name]["status"] = "ACTIVE"
result[manager_name]["message"] = "WARN: already stopped"
m.setStatus("ACTIVE")
m.set("message", "WARN: already stopped")
elif manager.getStatus() == "ERROR":
result[manager_name]["status"] = "ERROR"
result[manager_name]["message"] = "wrong state"
m.setStatus("ERROR")
m.set("message", "wrong state")
if len(manager_list) == 1 and len(result) == 0:
start_response("404 NOT FOUND", [("Content-Type", "text/plain")])
return ["manager %r not found!" % manager_list[0]]
start_response("200 OK", [("Content-Type", "text/html")])
return ["%s" % json.dumps(result)]
return ["%s" % json.dumps(result, cls=SynergyEncoder)]
def start(self):
self.model_disconnected = False
@ -357,7 +366,7 @@ class Synergy(service.Service):
manager.setStatus("ERROR")
raise ex
self.wsgi_server = wsgi.Server(
self.wsgi_server = Server(
name="WSGI server",
host_name=CONF.WSGI.host,
host_port=CONF.WSGI.port,

View File

@ -23,6 +23,7 @@ import sys
import time
from mock import Mock
from synergy.common import utils
from synergy.service import Synergy
logging.basicConfig(level=logging.DEBUG)
@ -47,6 +48,21 @@ def getLogger(name):
return logger
def objectHookHandler(parsed_dict):
if "synergy_object" in parsed_dict:
synergy_object = parsed_dict["synergy_object"]
try:
objClass = utils.import_class(synergy_object["name"])
objInstance = objClass()
return objInstance.deserialize(parsed_dict)
except Exception as ex:
print(ex)
raise ex
else:
return parsed_dict
class SynergyTests(unittest.TestCase):
@mock.patch('synergy.service.LOG', LOG)
@ -66,53 +82,66 @@ class SynergyTests(unittest.TestCase):
start_response = Mock()
result = self.synergy.listManagers(environ={},
start_response=start_response)
result = json.loads(result[0])
self.assertEqual(result, ["TimerManager"])
result = json.loads(result[0], object_hook=objectHookHandler)
self.assertEqual(len(result), 1)
self.assertEqual(result[0].getName(), "TimerManager")
@mock.patch('synergy.service.LOG', LOG)
def test_getManagerStatus(self):
start_response = Mock()
result = self.synergy.getManagerStatus(environ={},
start_response=start_response)
result = json.loads(result[0])
self.assertEqual(result, {'TimerManager': 'ACTIVE'})
result = json.loads(result[0], object_hook=objectHookHandler)
self.assertEqual(result[0].getStatus(), 'ACTIVE')
@mock.patch('synergy.service.LOG', LOG)
def test_startManager(self):
environ = {'QUERY_STRING': 'manager=TimerManager'}
start_response = Mock()
environ = {'QUERY_STRING': 'manager=NONE'}
result = self.synergy.startManager(environ, start_response)
result = json.loads(result[0])
self.assertEqual(result, {'TimerManager': {
'message': 'started successfully', 'status': 'RUNNING'}})
self.assertEqual(result[0], "manager 'NONE' not found!")
environ = {'QUERY_STRING': 'manager=TimerManager'}
result = self.synergy.startManager(environ, start_response)
result = json.loads(result[0], object_hook=objectHookHandler)
self.assertEqual(result[0].getStatus(), 'RUNNING')
self.assertEqual(result[0].get("message"), 'started successfully')
time.sleep(0.5)
result = self.synergy.startManager(environ, start_response)
result = json.loads(result[0])
result = json.loads(result[0], object_hook=objectHookHandler)
self.assertEqual(result, {'TimerManager': {
'message': 'WARN: already started', 'status': 'RUNNING'}})
self.assertEqual(result[0].getStatus(), 'RUNNING')
self.assertEqual(result[0].get("message"), 'WARN: already started')
@mock.patch('synergy.service.LOG', LOG)
def test_stopManager(self):
environ = {'QUERY_STRING': 'manager=TimerManager'}
start_response = Mock()
stop_response = Mock()
environ = {'QUERY_STRING': 'manager=NONE'}
result = self.synergy.startManager(environ, start_response)
result = self.synergy.startManager(environ, stop_response)
self.assertEqual(result[0], "manager 'NONE' not found!")
environ = {'QUERY_STRING': 'manager=TimerManager'}
result = self.synergy.startManager(environ, stop_response)
result = json.loads(result[0], object_hook=objectHookHandler)
time.sleep(0.5)
result = self.synergy.stopManager(environ, start_response)
result = self.synergy.stopManager(environ, stop_response)
result = json.loads(result[0], object_hook=objectHookHandler)
result = json.loads(result[0])
self.assertEqual(result, {'TimerManager': {
'message': 'stopped successfully', 'status': 'ACTIVE'}})
self.assertEqual(result[0].getStatus(), 'ACTIVE')
@mock.patch('synergy.service.LOG', LOG)
def test_executeCommand(self):

View File

@ -27,6 +27,7 @@ class TestManager(base.TestCase):
def setUp(self):
super(TestManager, self).setUp()
self.manager = Manager(name="dummy_manager")
self.manager.setAutoStart(False)
def test_get_name(self):
self.assertEqual("dummy_manager", self.manager.getName())

View File

@ -13,3 +13,5 @@ testrepository>=0.0.18
testscenarios>=0.4
testtools>=1.4.0
mock==2.0.0
tabulate>=0.7.2,<0.8.0