]> git.proxmox.com Git - ceph.git/blobdiff - ceph/qa/tasks/mgr/mgr_test_case.py
import quincy beta 17.1.0
[ceph.git] / ceph / qa / tasks / mgr / mgr_test_case.py
index 70791af7d7e1b1639e4d6aedd4a7b13dd3cacfd4..5fe5e0759856cb269f309e50a4f271a2b5a4d8cb 100644 (file)
@@ -1,8 +1,8 @@
-
-from unittest import case
 import json
 import logging
 
+from unittest import SkipTest
+
 from teuthology import misc
 from tasks.ceph_test_case import CephTestCase
 
@@ -36,10 +36,8 @@ class MgrCluster(CephCluster):
         self.mgr_daemons[mgr_id].restart()
 
     def get_mgr_map(self):
-        status = json.loads(
-            self.mon_manager.raw_cluster_cmd("status", "--format=json-pretty"))
-
-        return status["mgrmap"]
+        return json.loads(
+            self.mon_manager.raw_cluster_cmd("mgr", "dump", "--format=json-pretty"))
 
     def get_active_id(self):
         return self.get_mgr_map()["active_name"]
@@ -48,97 +46,142 @@ class MgrCluster(CephCluster):
         return [s['name'] for s in self.get_mgr_map()["standbys"]]
 
     def set_module_conf(self, module, key, val):
-        self.mon_manager.raw_cluster_cmd("config-key", "set",
+        self.mon_manager.raw_cluster_cmd("config", "set", "mgr",
                                          "mgr/{0}/{1}".format(
                                              module, key
                                          ), val)
 
-    def set_module_localized_conf(self, module, mgr_id, key, val):
-        self.mon_manager.raw_cluster_cmd("config-key", "set",
-                                         "mgr/{0}/{1}/{2}".format(
-                                             module, mgr_id, key
-                                         ), val)
+    def set_module_localized_conf(self, module, mgr_id, key, val, force):
+        cmd = ["config", "set", "mgr",
+               "/".join(["mgr", module, mgr_id, key]),
+               val]
+        if force:
+            cmd.append("--force")
+        self.mon_manager.raw_cluster_cmd(*cmd)
 
 
 class MgrTestCase(CephTestCase):
     MGRS_REQUIRED = 1
 
-    def setUp(self):
-        super(MgrTestCase, self).setUp()
-
-        # The test runner should have populated this
-        assert self.mgr_cluster is not None
+    @classmethod
+    def setup_mgrs(cls):
+        # Stop all the daemons
+        for daemon in cls.mgr_cluster.mgr_daemons.values():
+            daemon.stop()
 
-        if len(self.mgr_cluster.mgr_ids) < self.MGRS_REQUIRED:
-            raise case.SkipTest("Only have {0} manager daemons, "
-                                "{1} are required".format(
-                len(self.mgr_cluster.mgr_ids), self.MGRS_REQUIRED))
+        for mgr_id in cls.mgr_cluster.mgr_ids:
+            cls.mgr_cluster.mgr_fail(mgr_id)
 
-        # Restart all the daemons
-        for daemon in self.mgr_cluster.mgr_daemons.values():
-            daemon.stop()
+        # Unload all non-default plugins
+        loaded = json.loads(cls.mgr_cluster.mon_manager.raw_cluster_cmd(
+                   "mgr", "module", "ls", "--format=json-pretty"))['enabled_modules']
+        unload_modules = set(loaded) - {"cephadm", "restful"}
 
-        for mgr_id in self.mgr_cluster.mgr_ids:
-            self.mgr_cluster.mgr_fail(mgr_id)
+        for m in unload_modules:
+            cls.mgr_cluster.mon_manager.raw_cluster_cmd(
+                "mgr", "module", "disable", m)
 
-        for daemon in self.mgr_cluster.mgr_daemons.values():
+        # Start all the daemons
+        for daemon in cls.mgr_cluster.mgr_daemons.values():
             daemon.restart()
 
         # Wait for an active to come up
-        self.wait_until_true(lambda: self.mgr_cluster.get_active_id() != "",
+        cls.wait_until_true(lambda: cls.mgr_cluster.get_active_id() != "",
                              timeout=20)
 
-        expect_standbys = set(self.mgr_cluster.mgr_ids) \
-                          - {self.mgr_cluster.get_active_id()}
-        self.wait_until_true(
-            lambda: set(self.mgr_cluster.get_standby_ids()) == expect_standbys,
+        expect_standbys = set(cls.mgr_cluster.mgr_ids) \
+                          - {cls.mgr_cluster.get_active_id()}
+        cls.wait_until_true(
+            lambda: set(cls.mgr_cluster.get_standby_ids()) == expect_standbys,
             timeout=20)
 
-    def _load_module(self, module_name):
-        loaded = json.loads(self.mgr_cluster.mon_manager.raw_cluster_cmd(
-                   "mgr", "module", "ls"))['enabled_modules']
+    @classmethod
+    def setUpClass(cls):
+        # The test runner should have populated this
+        assert cls.mgr_cluster is not None
+
+        if len(cls.mgr_cluster.mgr_ids) < cls.MGRS_REQUIRED:
+            raise SkipTest(
+                "Only have {0} manager daemons, {1} are required".format(
+                    len(cls.mgr_cluster.mgr_ids), cls.MGRS_REQUIRED))
+
+        cls.setup_mgrs()
+
+    @classmethod
+    def _unload_module(cls, module_name):
+        def is_disabled():
+            enabled_modules = json.loads(cls.mgr_cluster.mon_manager.raw_cluster_cmd(
+                'mgr', 'module', 'ls', "--format=json-pretty"))['enabled_modules']
+            return module_name not in enabled_modules
+
+        if is_disabled():
+            return
+
+        log.debug("Unloading Mgr module %s ...", module_name)
+        cls.mgr_cluster.mon_manager.raw_cluster_cmd('mgr', 'module', 'disable', module_name)
+        cls.wait_until_true(is_disabled, timeout=30)
+
+    @classmethod
+    def _load_module(cls, module_name):
+        loaded = json.loads(cls.mgr_cluster.mon_manager.raw_cluster_cmd(
+            "mgr", "module", "ls", "--format=json-pretty"))['enabled_modules']
         if module_name in loaded:
             # The enable command is idempotent, but our wait for a restart
             # isn't, so let's return now if it's already loaded
             return
 
-        initial_gid = self.mgr_cluster.get_mgr_map()['active_gid']
-        self.mgr_cluster.mon_manager.raw_cluster_cmd("mgr", "module", "enable",
-                                         module_name)
+        initial_mgr_map = cls.mgr_cluster.get_mgr_map()
+
+        # check if the the module is configured as an always on module
+        mgr_daemons = json.loads(cls.mgr_cluster.mon_manager.raw_cluster_cmd(
+            "mgr", "metadata"))
+
+        for daemon in mgr_daemons:
+            if daemon["name"] == initial_mgr_map["active_name"]:
+                ceph_version = daemon["ceph_release"]
+                always_on = initial_mgr_map["always_on_modules"].get(ceph_version, [])
+                if module_name in always_on:
+                    return
+
+        log.debug("Loading Mgr module %s ...", module_name)
+        initial_gid = initial_mgr_map['active_gid']
+        cls.mgr_cluster.mon_manager.raw_cluster_cmd(
+            "mgr", "module", "enable", module_name, "--force")
 
         # Wait for the module to load
         def has_restarted():
-            mgr_map = self.mgr_cluster.get_mgr_map()
+            mgr_map = cls.mgr_cluster.get_mgr_map()
             done = mgr_map['active_gid'] != initial_gid and mgr_map['available']
             if done:
-                log.info("Restarted after module load (new active {0}/{1})".format(
-                    mgr_map['active_name'] , mgr_map['active_gid']))
+                log.debug("Restarted after module load (new active {0}/{1})".format(
+                    mgr_map['active_name'], mgr_map['active_gid']))
             return done
-        self.wait_until_true(has_restarted, timeout=30)
+        cls.wait_until_true(has_restarted, timeout=30)
 
 
-    def _get_uri(self, service_name):
+    @classmethod
+    def _get_uri(cls, service_name):
         # Little dict hack so that I can assign into this from
         # the get_or_none function
         mgr_map = {'x': None}
 
         def _get_or_none():
-            mgr_map['x'] = self.mgr_cluster.get_mgr_map()
+            mgr_map['x'] = cls.mgr_cluster.get_mgr_map()
             result = mgr_map['x']['services'].get(service_name, None)
             return result
 
-        self.wait_until_true(lambda: _get_or_none() is not None, 30)
+        cls.wait_until_true(lambda: _get_or_none() is not None, 30)
 
         uri = mgr_map['x']['services'][service_name]
 
-        log.info("Found {0} at {1} (daemon {2}/{3})".format(
+        log.debug("Found {0} at {1} (daemon {2}/{3})".format(
             service_name, uri, mgr_map['x']['active_name'],
             mgr_map['x']['active_gid']))
 
         return uri
 
-
-    def _assign_ports(self, module_name, config_name, min_port=7789):
+    @classmethod
+    def _assign_ports(cls, module_name, config_name, min_port=7789):
         """
         To avoid the need to run lots of hosts in teuthology tests to
         get different URLs per mgr, we will hand out different ports
@@ -150,27 +193,28 @@ class MgrTestCase(CephTestCase):
         # Start handing out ports well above Ceph's range.
         assign_port = min_port
 
-        for mgr_id in self.mgr_cluster.mgr_ids:
-            self.mgr_cluster.mgr_stop(mgr_id)
-            self.mgr_cluster.mgr_fail(mgr_id)
+        for mgr_id in cls.mgr_cluster.mgr_ids:
+            cls.mgr_cluster.mgr_stop(mgr_id)
+            cls.mgr_cluster.mgr_fail(mgr_id)
 
-        for mgr_id in self.mgr_cluster.mgr_ids:
-            log.info("Using port {0} for {1} on mgr.{2}".format(
+        for mgr_id in cls.mgr_cluster.mgr_ids:
+            log.debug("Using port {0} for {1} on mgr.{2}".format(
                 assign_port, module_name, mgr_id
             ))
-            self.mgr_cluster.set_module_localized_conf(module_name, mgr_id,
-                                                       config_name,
-                                                       str(assign_port))
+            cls.mgr_cluster.set_module_localized_conf(module_name, mgr_id,
+                                                      config_name,
+                                                      str(assign_port),
+                                                      force=True)
             assign_port += 1
 
-        for mgr_id in self.mgr_cluster.mgr_ids:
-            self.mgr_cluster.mgr_restart(mgr_id)
+        for mgr_id in cls.mgr_cluster.mgr_ids:
+            cls.mgr_cluster.mgr_restart(mgr_id)
 
         def is_available():
-            mgr_map = self.mgr_cluster.get_mgr_map()
+            mgr_map = cls.mgr_cluster.get_mgr_map()
             done = mgr_map['available']
             if done:
-                log.info("Available after assign ports (new active {0}/{1})".format(
-                    mgr_map['active_name'] , mgr_map['active_gid']))
+                log.debug("Available after assign ports (new active {0}/{1})".format(
+                    mgr_map['active_name'], mgr_map['active_gid']))
             return done
-        self.wait_until_true(is_available, timeout=30)
+        cls.wait_until_true(is_available, timeout=30)