]> git.proxmox.com Git - ceph.git/blame - ceph/qa/tasks/mgr/test_module_selftest.py
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / qa / tasks / mgr / test_module_selftest.py
CommitLineData
3efd9988
FG
1
2import time
3import requests
11fdf7f2
TL
4import errno
5import logging
f67539c2
TL
6import sys
7
11fdf7f2 8from teuthology.exceptions import CommandFailedError
3efd9988 9
f67539c2
TL
10from .mgr_test_case import MgrTestCase
11
3efd9988 12
11fdf7f2
TL
13log = logging.getLogger(__name__)
14
3efd9988
FG
15
16class TestModuleSelftest(MgrTestCase):
17 """
18 That modules with a self-test command can be loaded and execute it
19 without errors.
20
21 This is not a substitute for really testing the modules, but it
22 is quick and is designed to catch regressions that could occur
23 if data structures change in a way that breaks how the modules
24 touch them.
25 """
26 MGRS_REQUIRED = 1
27
11fdf7f2 28 def setUp(self):
9f95a23c 29 super(TestModuleSelftest, self).setUp()
11fdf7f2
TL
30 self.setup_mgrs()
31
3efd9988 32 def _selftest_plugin(self, module_name):
11fdf7f2 33 self._load_module("selftest")
3efd9988
FG
34 self._load_module(module_name)
35
11fdf7f2
TL
36 # Execute the module's self_test() method
37 self.mgr_cluster.mon_manager.raw_cluster_cmd(
38 "mgr", "self-test", "module", module_name)
3efd9988
FG
39
40 def test_zabbix(self):
b32b8144
FG
41 # Set these mandatory config fields so that the zabbix module
42 # won't trigger health/log errors on load/serve.
43 self.mgr_cluster.set_module_conf("zabbix", "zabbix_host", "localhost")
44 self.mgr_cluster.set_module_conf("zabbix", "identifier", "foo")
3efd9988
FG
45 self._selftest_plugin("zabbix")
46
47 def test_prometheus(self):
94b18763 48 self._assign_ports("prometheus", "server_port", min_port=8100)
3efd9988
FG
49 self._selftest_plugin("prometheus")
50
51 def test_influx(self):
52 self._selftest_plugin("influx")
53
11fdf7f2 54 def test_diskprediction_local(self):
f67539c2
TL
55 if sys.version_info >= (3, 8):
56 # https://tracker.ceph.com/issues/45147
57 python_version = f'python {sys.version_info.major}.{sys.version_info.minor}'
58 self.skipTest(f'{python_version} not compatible with diskprediction_local')
11fdf7f2
TL
59 self._selftest_plugin("diskprediction_local")
60
11fdf7f2
TL
61 def test_telegraf(self):
62 self._selftest_plugin("telegraf")
63
64 def test_iostat(self):
65 self._selftest_plugin("iostat")
66
67 def test_devicehealth(self):
68 self._selftest_plugin("devicehealth")
69 # Clean up the pool that the module creates, because otherwise
70 # it's low PG count causes test failures.
71 pool_name = "device_health_metrics"
72 self.mgr_cluster.mon_manager.raw_cluster_cmd(
73 "osd", "pool", "delete", pool_name, pool_name,
74 "--yes-i-really-really-mean-it")
75
3efd9988
FG
76 def test_selftest_run(self):
77 self._load_module("selftest")
78 self.mgr_cluster.mon_manager.raw_cluster_cmd("mgr", "self-test", "run")
79
11fdf7f2
TL
80 def test_telemetry(self):
81 self._selftest_plugin("telemetry")
82
83 def test_crash(self):
84 self._selftest_plugin("crash")
85
9f95a23c
TL
86 def test_orchestrator(self):
87 self._selftest_plugin("orchestrator")
eafe8130
TL
88
89
11fdf7f2
TL
90 def test_selftest_config_update(self):
91 """
92 That configuration updates are seen by running mgr modules
93 """
94 self._load_module("selftest")
95
96 def get_value():
97 return self.mgr_cluster.mon_manager.raw_cluster_cmd(
98 "mgr", "self-test", "config", "get", "testkey").strip()
99
100 self.assertEqual(get_value(), "None")
101 self.mgr_cluster.mon_manager.raw_cluster_cmd(
102 "config", "set", "mgr", "mgr/selftest/testkey", "foo")
103 self.wait_until_equal(get_value, "foo", timeout=10)
104
105 def get_localized_value():
106 return self.mgr_cluster.mon_manager.raw_cluster_cmd(
107 "mgr", "self-test", "config", "get_localized", "testkey").strip()
108
109 self.assertEqual(get_localized_value(), "foo")
110 self.mgr_cluster.mon_manager.raw_cluster_cmd(
111 "config", "set", "mgr", "mgr/selftest/{}/testkey".format(
112 self.mgr_cluster.get_active_id()),
113 "bar")
114 self.wait_until_equal(get_localized_value, "bar", timeout=10)
115
11fdf7f2 116
3efd9988
FG
117 def test_selftest_command_spam(self):
118 # Use the selftest module to stress the mgr daemon
119 self._load_module("selftest")
120
121 # Use the dashboard to test that the mgr is still able to do its job
11fdf7f2 122 self._assign_ports("dashboard", "ssl_server_port")
3efd9988 123 self._load_module("dashboard")
11fdf7f2
TL
124 self.mgr_cluster.mon_manager.raw_cluster_cmd("dashboard",
125 "create-self-signed-cert")
3efd9988
FG
126
127 original_active = self.mgr_cluster.get_active_id()
128 original_standbys = self.mgr_cluster.get_standby_ids()
129
130 self.mgr_cluster.mon_manager.raw_cluster_cmd("mgr", "self-test",
131 "background", "start",
132 "command_spam")
133
134 dashboard_uri = self._get_uri("dashboard")
135
136 delay = 10
137 periods = 10
138 for i in range(0, periods):
139 t1 = time.time()
140 # Check that an HTTP module remains responsive
11fdf7f2 141 r = requests.get(dashboard_uri, verify=False)
3efd9988
FG
142 self.assertEqual(r.status_code, 200)
143
144 # Check that a native non-module command remains responsive
145 self.mgr_cluster.mon_manager.raw_cluster_cmd("osd", "df")
146
147 time.sleep(delay - (time.time() - t1))
148
149 self.mgr_cluster.mon_manager.raw_cluster_cmd("mgr", "self-test",
150 "background", "stop")
151
152 # Check that all mgr daemons are still running
153 self.assertEqual(original_active, self.mgr_cluster.get_active_id())
154 self.assertEqual(original_standbys, self.mgr_cluster.get_standby_ids())
11fdf7f2
TL
155
156 def test_module_commands(self):
157 """
158 That module-handled commands have appropriate behavior on
159 disabled/failed/recently-enabled modules.
160 """
161
162 # Calling a command on a disabled module should return the proper
163 # error code.
164 self._load_module("selftest")
165 self.mgr_cluster.mon_manager.raw_cluster_cmd(
166 "mgr", "module", "disable", "selftest")
167 with self.assertRaises(CommandFailedError) as exc_raised:
168 self.mgr_cluster.mon_manager.raw_cluster_cmd(
169 "mgr", "self-test", "run")
170
171 self.assertEqual(exc_raised.exception.exitstatus, errno.EOPNOTSUPP)
172
173 # Calling a command that really doesn't exist should give me EINVAL.
174 with self.assertRaises(CommandFailedError) as exc_raised:
175 self.mgr_cluster.mon_manager.raw_cluster_cmd(
176 "osd", "albatross")
177
178 self.assertEqual(exc_raised.exception.exitstatus, errno.EINVAL)
179
180 # Enabling a module and then immediately using ones of its commands
181 # should work (#21683)
182 self._load_module("selftest")
183 self.mgr_cluster.mon_manager.raw_cluster_cmd(
184 "mgr", "self-test", "config", "get", "testkey")
185
186 # Calling a command for a failed module should return the proper
187 # error code.
188 self.mgr_cluster.mon_manager.raw_cluster_cmd(
189 "mgr", "self-test", "background", "start", "throw_exception")
190 with self.assertRaises(CommandFailedError) as exc_raised:
191 self.mgr_cluster.mon_manager.raw_cluster_cmd(
192 "mgr", "self-test", "run"
193 )
194 self.assertEqual(exc_raised.exception.exitstatus, errno.EIO)
195
196 # A health alert should be raised for a module that has thrown
197 # an exception from its serve() method
198 self.wait_for_health(
199 "Module 'selftest' has failed: Synthetic exception in serve",
200 timeout=30)
201
202 self.mgr_cluster.mon_manager.raw_cluster_cmd(
203 "mgr", "module", "disable", "selftest")
204
205 self.wait_for_health_clear(timeout=30)
206
207 def test_module_remote(self):
208 """
209 Use the selftest module to exercise inter-module communication
210 """
211 self._load_module("selftest")
212 # The "self-test remote" operation just happens to call into
213 # influx.
214 self._load_module("influx")
215
216 self.mgr_cluster.mon_manager.raw_cluster_cmd(
217 "mgr", "self-test", "remote")
218
219 def test_selftest_cluster_log(self):
220 """
221 Use the selftest module to test the cluster/audit log interface.
222 """
223 priority_map = {
224 "info": "INF",
225 "security": "SEC",
226 "warning": "WRN",
227 "error": "ERR"
228 }
229 self._load_module("selftest")
230 for priority in priority_map.keys():
231 message = "foo bar {}".format(priority)
232 log_message = "[{}] {}".format(priority_map[priority], message)
233 # Check for cluster/audit logs:
234 # 2018-09-24 09:37:10.977858 mgr.x [INF] foo bar info
235 # 2018-09-24 09:37:10.977860 mgr.x [SEC] foo bar security
236 # 2018-09-24 09:37:10.977863 mgr.x [WRN] foo bar warning
237 # 2018-09-24 09:37:10.977866 mgr.x [ERR] foo bar error
238 with self.assert_cluster_log(log_message):
239 self.mgr_cluster.mon_manager.raw_cluster_cmd(
240 "mgr", "self-test", "cluster-log", "cluster",
241 priority, message)
242 with self.assert_cluster_log(log_message, watch_channel="audit"):
243 self.mgr_cluster.mon_manager.raw_cluster_cmd(
244 "mgr", "self-test", "cluster-log", "audit",
245 priority, message)
246
247 def test_selftest_cluster_log_unknown_channel(self):
248 """
249 Use the selftest module to test the cluster/audit log interface.
250 """
251 with self.assertRaises(CommandFailedError) as exc_raised:
252 self.mgr_cluster.mon_manager.raw_cluster_cmd(
253 "mgr", "self-test", "cluster-log", "xyz",
254 "ERR", "The channel does not exist")
255 self.assertEqual(exc_raised.exception.exitstatus, errno.EOPNOTSUPP)