Creating a generic monitor 85/15985/3
authorlihuan <lihuansse@tongji.edu.cn>
Sat, 25 Jun 2016 03:22:57 +0000 (11:22 +0800)
committerlihuan <lihuansse@tongji.edu.cn>
Thu, 30 Jun 2016 08:17:50 +0000 (16:17 +0800)
JIRA: YARDSTICK-274

Change-Id: Iac8c525b36b2778767177b17e6107866cc514e40
Signed-off-by: lihuan <lihuansse@tongji.edu.cn>
tests/unit/benchmark/scenarios/availability/test_basemonitor.py
tests/unit/benchmark/scenarios/availability/test_monitor_general.py [new file with mode: 0644]
yardstick/benchmark/scenarios/availability/monitor/basemonitor.py
yardstick/benchmark/scenarios/availability/monitor/monitor_general.py [new file with mode: 0644]
yardstick/benchmark/scenarios/availability/monitor_conf.yaml [new file with mode: 0644]

index 1329527..1408410 100644 (file)
@@ -23,6 +23,7 @@ class MonitorMgrTestCase(unittest.TestCase):
     def setUp(self):
         config = {
             'monitor_type': 'openstack-api',
+            'key' : 'service_status'
         }
 
         self.monitor_configs = []
@@ -36,6 +37,11 @@ class MonitorMgrTestCase(unittest.TestCase):
 
         ret = instance.verify_SLA()
 
+    def test_MonitorMgr_getitem(self, mock_monitor):
+        monitorMgr = basemonitor.MonitorMgr()
+        monitorMgr.init_monitors(self.monitor_configs, None)
+        monitorIns = monitorMgr['service_status']
+
 class BaseMonitorTestCase(unittest.TestCase):
 
     class MonitorSimple(basemonitor.BaseMonitor):
diff --git a/tests/unit/benchmark/scenarios/availability/test_monitor_general.py b/tests/unit/benchmark/scenarios/availability/test_monitor_general.py
new file mode 100644 (file)
index 0000000..85487a5
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+##############################################################################
+# Copyright (c) 2016 Huan Li and others
+# lihuansse@tongji.edu.cn
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+
+# Unittest for yardstick.benchmark.scenarios.availability.monitor
+# .monitor_general
+
+import mock
+import unittest
+from yardstick.benchmark.scenarios.availability.monitor import monitor_general
+
+
+@mock.patch('yardstick.benchmark.scenarios.availability.monitor.'
+            'monitor_general.ssh')
+@mock.patch('yardstick.benchmark.scenarios.availability.monitor.'
+            'monitor_general.open')
+class GeneralMonitorServiceTestCase(unittest.TestCase):
+    def setUp(self):
+        host = {
+            "ip": "10.20.0.5",
+            "user": "root",
+            "key_filename": "/root/.ssh/id_rsa"
+        }
+        self.context = {"node1": host}
+        self.monitor_cfg = {
+            'monitor_type': 'general-monitor',
+            'key': 'service_status',
+            'host': 'node1',
+            'monitor_time': 3,
+            'parameter': {'serviceName': 'haproxy'},
+            'sla': {'max_recover_time': 1}
+        }
+        self.monitor_cfg_noparam = {
+            'monitor_type': 'general-monitor',
+            'key': 'service_status',
+            'host': 'node1',
+            'monitor_time': 3,
+            'sla': {'max_recover_time': 1}
+        }
+
+    def test__monitor_general_all_successful(self, mock_open, mock_ssh):
+        ins = monitor_general.GeneralMonitor(self.monitor_cfg, self.context)
+
+        ins.setup()
+        mock_ssh.SSH().execute.return_value = (0, "running", '')
+        ins.monitor_func()
+        ins._result = {'outage_time' : 0}
+        ins.verify_SLA()
+
+    def test__monitor_general_all_successful_noparam(self, mock_open, mock_ssh):
+        ins = monitor_general.GeneralMonitor(self.monitor_cfg_noparam, self.context)
+
+        ins.setup()
+        mock_ssh.SSH().execute.return_value = (0, "running", '')
+        ins.monitor_func()
+        ins._result = {'outage_time' : 0}
+        ins.verify_SLA()
+
+    def test__monitor_general_failure(self, mock_open, mock_ssh):
+        ins = monitor_general.GeneralMonitor(self.monitor_cfg_noparam, self.context)
+
+        ins.setup()
+        mock_ssh.SSH().execute.return_value = (1, "error", 'error')
+        ins.monitor_func()
+        ins._result = {'outage_time' : 2}
+        ins.verify_SLA()
index 983c3a3..d26c99c 100644 (file)
@@ -12,6 +12,7 @@ import multiprocessing
 import time
 import os
 import yardstick.common.utils as utils
+import yaml
 
 LOG = logging.getLogger(__name__)
 
@@ -32,9 +33,16 @@ class MonitorMgr(object):
             monitor_type = monitor_cfg["monitor_type"]
             monitor_cls = BaseMonitor.get_monitor_cls(monitor_type)
             monitor_ins = monitor_cls(monitor_cfg, context)
-
+            if "key" in monitor_cfg:
+                monitor_ins.key = monitor_cfg["key"]
             self._monitor_list.append(monitor_ins)
 
+    def __getitem__(self, item):
+        for obj in self._monitor_list:
+            if obj.key == item:
+                return obj
+        raise KeyError("No such monitor instance of key - %s" % item)
+
     def start_monitors(self):
         for _monotor_instace in self._monitor_list:
             _monotor_instace.start_monitor()
@@ -52,8 +60,12 @@ class MonitorMgr(object):
 
 class BaseMonitor(multiprocessing.Process):
     """docstring for BaseMonitor"""
+    monitor_cfgs = {}
 
     def __init__(self, config, context):
+        if not BaseMonitor.monitor_cfgs:
+            with open(monitor_conf_path) as stream:
+                BaseMonitor.monitor_cfgs = yaml.load(stream)
         multiprocessing.Process.__init__(self)
         self._config = config
         self._context = context
diff --git a/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py b/yardstick/benchmark/scenarios/availability/monitor/monitor_general.py
new file mode 100644 (file)
index 0000000..515514c
--- /dev/null
@@ -0,0 +1,70 @@
+##############################################################################
+# Copyright (c) 2016 Juan Qiu and others
+# juan_ qiu@tongji.edu.cn
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Apache License, Version 2.0
+# which accompanies this distribution, and is available at
+# http://www.apache.org/licenses/LICENSE-2.0
+##############################################################################
+import logging
+import yardstick.ssh as ssh
+
+import basemonitor as basemonitor
+from yardstick.benchmark.scenarios.availability.util import buildshellparams
+
+
+LOG = logging.getLogger(__name__)
+
+
+class GeneralMonitor(basemonitor.BaseMonitor):
+    """docstring for MonitorApi"""
+
+    __monitor_type__ = "general-monitor"
+
+    def setup(self):
+        host = self._context[self._config["host"]]
+        ip = host.get("ip", None)
+        user = host.get("user", "root")
+        key_filename = host.get("key_filename", "~/.ssh/id_rsa")
+        self.key = self._config["key"]
+        self.monitor_type = self._config["monitor_type"]
+
+        if "parameter" in self._config:
+            parameter = self._config['parameter']
+            str = buildshellparams(parameter)
+            l = list(item for item in parameter.values())
+            self.cmd_param = str.format(*l)
+
+        self.monitor_cfg = basemonitor.BaseMonitor.monitor_cfgs.get(self.key)
+        self.monitor_script = self.get_script_fullpath(
+            self.monitor_cfg['monitor_script'])
+        self.connection = ssh.SSH(user, ip, key_filename=key_filename)
+        self.connection.wait(timeout=600)
+        LOG.debug("ssh host success!")
+
+    def monitor_func(self):
+        if "parameter" in self._config:
+            exit_status, stdout, stderr = self.connection.execute(
+                self.cmd_param,
+                stdin=open(self.monitor_script, "r"))
+        else:
+            exit_status, stdout, stderr = self.connection.execute(
+                "/bin/bash -s ",
+                stdin=open(self.monitor_script, "r"))
+
+        if exit_status:
+            return False
+        return True
+
+    def verify_SLA(self):
+        LOG.debug("the _result:%s" % self._result)
+        outage_time = self._result.get('outage_time', None)
+        max_outage_time = self._config["sla"]["max_recover_time"]
+        if outage_time is None:
+            LOG.error("There is no outage_time in monitor result.")
+            return False
+        if outage_time > max_outage_time:
+            LOG.error("SLA failure: %f > %f" % (outage_time, max_outage_time))
+            return False
+        else:
+            return True
diff --git a/yardstick/benchmark/scenarios/availability/monitor_conf.yaml b/yardstick/benchmark/scenarios/availability/monitor_conf.yaml
new file mode 100644 (file)
index 0000000..9efceed
--- /dev/null
@@ -0,0 +1,11 @@
+---
+# sample config file for ha test
+#
+schema: "yardstick:task:0.1"
+
+process_status:
+  monitor_script: ha_tools/check_process_python.bash
+nova_image_list:
+  monitor_script: ha_tools/nova_image_list.bash
+service_status:
+  monitor_script: ha_tools/check_service.bash