blob: 45bd9fb02760a59299ed2e90d0e68d17df8f44aa [file] [log] [blame]
Oleksii Zhurba020fab42017-11-01 20:13:28 +00001import json
2import requests
Oleksii Zhurba84ce7fe2018-01-16 21:34:01 +00003import datetime
Oleksii Zhurba9848e212018-09-05 10:53:51 -05004import pytest
Oleksii Zhurba020fab42017-11-01 20:13:28 +00005
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -05006@pytest.mark.sl_dup
7#ElasticsearchClusterHealthStatusMajor or stacklight-pytest
8@pytest.mark.full
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +03009@pytest.mark.usefixtures('check_kibana')
Oleksii Zhurba020fab42017-11-01 20:13:28 +000010def test_elasticsearch_cluster(local_salt_client):
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050011 salt_output = local_salt_client.pillar_get(
12 tgt='kibana:server',
13 param='_param:haproxy_elasticsearch_bind_host')
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -050014 ssl = local_salt_client.pillar_get(
15 tgt='elasticsearch:server',
16 param='haproxy:proxy:listen:elasticsearch:binds:ssl:enabled')
17 proto = "https" if ssl else "http"
Oleksii Zhurba9848e212018-09-05 10:53:51 -050018
Oleksii Zhurbae592ed12018-06-21 18:01:09 -050019 proxies = {"http": None, "https": None}
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050020 IP = salt_output
Dmitriy Kruglova34a3042019-08-20 11:45:35 +020021 response = requests.get(
22 '{0}://{1}:9200/'.format(proto, IP),
23 proxies=proxies,
24 verify=False)
25 assert response.status_code == 200, (
26 "Issues with accessing elasticsearch on {}.".format(IP))
27 response = requests.get(
28 '{0}://{1}:9200/_cat/health'.format(proto, IP),
29 proxies=proxies,
30 verify=False).content
31 msg = "elasticsearch is not healthy:\n{}".format(
32 json.dumps(response, indent=4))
33 assert response.split()[3] == 'green',msg
34 assert response.split()[4] == '3', msg
35 assert response.split()[5] == '3', msg
36 assert response.split()[10] == '0', msg
37 assert response.split()[13] == '100.0%', msg
Oleksii Zhurba020fab42017-11-01 20:13:28 +000038
39
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -050040@pytest.mark.sl_dup
41#stacklight-pytest
42@pytest.mark.full
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +030043@pytest.mark.usefixtures('check_kibana')
Ievgeniia Zadorozhna511f0ce2018-11-08 17:43:10 +030044def test_kibana_status(local_salt_client):
45 proxies = {"http": None, "https": None}
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050046 IP = local_salt_client.pillar_get(param='_param:stacklight_log_address')
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -050047 ssl = local_salt_client.pillar_get(
48 tgt='kibana:server',
49 param='haproxy:proxy:listen:kibana:binds:ssl:enabled')
50 proto = "https" if ssl else "http"
51
Dmitriy Kruglova34a3042019-08-20 11:45:35 +020052 response = requests.get(
53 '{0}://{1}:5601/api/status'.format(proto, IP),
54 proxies=proxies,
55 verify=False).content
56 body = json.loads(response)
57 assert body['status']['overall']['state'] == "green", (
58 "Kibana overall status is not 'green':\n{}".format(
59 body['status']['overall'])
60 )
Ievgeniia Zadorozhna511f0ce2018-11-08 17:43:10 +030061 for i in body['status']['statuses']:
Dmitriy Kruglova34a3042019-08-20 11:45:35 +020062 assert i['state'] == "green", (
63 "Kibana statuses are unexpected:\n{}".format(i))
Ievgeniia Zadorozhna511f0ce2018-11-08 17:43:10 +030064
65
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -050066@pytest.mark.smoke
67#TODO: recheck
Ievgeniia Zadorozhna511f0ce2018-11-08 17:43:10 +030068@pytest.mark.usefixtures('check_kibana')
Oleksii Zhurba84ce7fe2018-01-16 21:34:01 +000069def test_elasticsearch_node_count(local_salt_client):
70 now = datetime.datetime.now()
71 today = now.strftime("%Y.%m.%d")
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050072 salt_output = local_salt_client.pillar_get(
73 tgt='kibana:server',
74 param='_param:haproxy_elasticsearch_bind_host')
Oleksii Zhurba9848e212018-09-05 10:53:51 -050075
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050076 IP = salt_output
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -050077 ssl = local_salt_client.pillar_get(
78 tgt='elasticsearch:server',
79 param='haproxy:proxy:listen:elasticsearch:binds:ssl:enabled')
80 proto = "https" if ssl else "http"
81
Tatyana Leontovich30bd90c2019-01-11 16:26:32 +020082 headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
Oleksii Zhurbae592ed12018-06-21 18:01:09 -050083 proxies = {"http": None, "https": None}
Tatyana Leontovich30bd90c2019-01-11 16:26:32 +020084 data = ('{"size": 0, "aggs": '
85 '{"uniq_hostname": '
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -050086 '{"terms": {"size": 500, '
Tatyana Leontovich30bd90c2019-01-11 16:26:32 +020087 '"field": "Hostname.keyword"}}}}')
88 response = requests.post(
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -050089 '{0}://{1}:9200/log-{2}/_search?pretty'.format(proto, IP, today),
Tatyana Leontovich30bd90c2019-01-11 16:26:32 +020090 proxies=proxies,
91 headers=headers,
Dmitriy Kruglova34a3042019-08-20 11:45:35 +020092 verify=False,
Tatyana Leontovich30bd90c2019-01-11 16:26:32 +020093 data=data)
Dmitriy Kruglova34a3042019-08-20 11:45:35 +020094 assert response.status_code == 200, (
95 'Issues with accessing elasticsearch on {}:\n{}'.format(
96 IP, response.text)
97 )
Tatyana Leontovich30bd90c2019-01-11 16:26:32 +020098 resp = json.loads(response.text)
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050099 cluster_domain = local_salt_client.pillar_get(param='_param:cluster_domain')
Oleksii Zhurbad2847dc2018-02-16 15:13:09 -0600100 monitored_nodes = []
Oleksii Zhurba7f463412018-03-21 16:32:44 -0500101 for item_ in resp['aggregations']['uniq_hostname']['buckets']:
Oleksii Zhurbad2847dc2018-02-16 15:13:09 -0600102 node_name = item_['key']
103 monitored_nodes.append(node_name + '.' + cluster_domain)
104 missing_nodes = []
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500105 all_nodes = local_salt_client.test_ping(tgt='*').keys()
106 for node in all_nodes:
Oleksii Zhurbad2847dc2018-02-16 15:13:09 -0600107 if node not in monitored_nodes:
108 missing_nodes.append(node)
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200109 assert len(missing_nodes) == 0, (
110 "Not all nodes are in Elasticsearch. Expected {}, but found {} keys.\n"
111 "Missing nodes:\n{}".format(
112 len(monitored_nodes), len(all_nodes), missing_nodes)
113 )
Oleksii Zhurba84ce7fe2018-01-16 21:34:01 +0000114
115
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500116@pytest.mark.sl_dup
117#DockerServiceMonitoring*
118@pytest.mark.full
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000119def test_stacklight_services_replicas(local_salt_client):
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300120 # TODO
121 # change to docker:swarm:role:master ?
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000122 salt_output = local_salt_client.cmd(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500123 tgt='I@docker:client:stack:monitoring and I@prometheus:server',
124 param='docker service ls',
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300125 expr_form='compound')
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500126
127 if not salt_output:
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300128 pytest.skip("docker:client:stack:monitoring or \
129 prometheus:server pillars are not found on this environment.")
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500130
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000131 wrong_items = []
132 for line in salt_output[salt_output.keys()[0]].split('\n'):
133 if line[line.find('/') - 1] != line[line.find('/') + 1] \
134 and 'replicated' in line:
135 wrong_items.append(line)
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200136 assert len(wrong_items) == 0, (
137 "Some monitoring services don't have the expected number of "
138 "replicas:\n{}".format(json.dumps(wrong_items, indent=4))
139 )
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000140
141
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500142@pytest.mark.smoke
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300143@pytest.mark.usefixtures('check_prometheus')
Oleksii Zhurba25215d92019-01-31 16:35:57 -0600144def test_prometheus_alert_count(local_salt_client, ctl_nodes_pillar):
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500145 IP = local_salt_client.pillar_get(param='_param:cluster_public_host')
Sergey Galkinea5a9ae2019-11-18 15:15:07 +0400146 prometheus_password_old = local_salt_client.pillar_get(
147 param='_param:keepalived_prometheus_vip_password_generated')
Hanna Arhipovafae5b5b2019-12-09 15:57:55 +0200148 prometheus_password_generated = local_salt_client.pillar_get(
Sergey Galkinea5a9ae2019-11-18 15:15:07 +0400149 param='_param:prometheus_server_proxy_password_generated')
Hanna Arhipovafae5b5b2019-12-09 15:57:55 +0200150 # New password in 2019.2.7
151 prometheus_password_from_nginx = local_salt_client.pillar_get(
152 tgt="nginx:server",
153 param='_param:nginx_proxy_prometheus_server_password')
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -0500154 proto = local_salt_client.pillar_get(
155 param='_param:cluster_public_protocol')
Sergey Galkinea5a9ae2019-11-18 15:15:07 +0400156 proxies = {"http": None, "https": None}
Oleksii Zhurba468e6c72018-01-16 17:43:15 +0000157 # keystone:server can return 3 nodes instead of 1
158 # this will be fixed later
159 # TODO
Hanna Arhipovafae5b5b2019-12-09 15:57:55 +0200160 if prometheus_password_from_nginx:
161 prometheus_password = prometheus_password_from_nginx
162 elif prometheus_password_generated:
163 prometheus_password = prometheus_password_generated
164 else:
Sergey Galkinea5a9ae2019-11-18 15:15:07 +0400165 prometheus_password = prometheus_password_old
Hanna Arhipovafae5b5b2019-12-09 15:57:55 +0200166
Sergey Galkinea5a9ae2019-11-18 15:15:07 +0400167 response = requests.get(
168 '{0}://{1}:15010/api/v1/alerts'.format(proto, IP),
169 proxies=proxies,
170 auth=('prometheus', prometheus_password))
171 assert response.status_code == 200, (
172 'Issues with accessing prometheus alerts on {}:\n{}'.format(
173 IP, response.text)
174 )
175 alerts = json.loads(response.content)
176 short_alerts = ''
177 for i in alerts['data']['alerts']:
178 short_alerts = '{}* {}\n'.format(short_alerts, i['annotations']['description'])
179 assert alerts['data']['alerts'] == [], 'AlertManager page has some alerts!\n{}'.format(
180 short_alerts)
Oleksii Zhurba468e6c72018-01-16 17:43:15 +0000181
182
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500183@pytest.mark.sl_dup
184#DockerServiceMonitoring* ??
185@pytest.mark.full
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000186def test_stacklight_containers_status(local_salt_client):
187 salt_output = local_salt_client.cmd(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500188 tgt='I@docker:swarm:role:master and I@prometheus:server',
189 param='docker service ps $(docker stack services -q monitoring)',
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300190 expr_form='compound')
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500191
192 if not salt_output:
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200193 pytest.skip("docker:swarm:role:master or prometheus:server pillars "
194 "are not found on this environment.")
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500195
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000196 result = {}
Oleksii Zhurba468e6c72018-01-16 17:43:15 +0000197 # for old reclass models, docker:swarm:role:master can return
198 # 2 nodes instead of one. Here is temporary fix.
199 # TODO
200 if len(salt_output.keys()) > 1:
201 if 'CURRENT STATE' not in salt_output[salt_output.keys()[0]]:
202 del salt_output[salt_output.keys()[0]]
Oleksii Zhurbaf2af6372017-11-01 22:53:03 +0000203 for line in salt_output[salt_output.keys()[0]].split('\n')[1:]:
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000204 shift = 0
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000205 if line.split()[1] == '\\_':
206 shift = 1
207 if line.split()[1 + shift] not in result.keys():
208 result[line.split()[1]] = 'NOT OK'
209 if line.split()[4 + shift] == 'Running' \
210 or line.split()[4 + shift] == 'Ready':
211 result[line.split()[1 + shift]] = 'OK'
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200212 assert 'NOT OK' not in result.values(), (
213 "Some containers have incorrect state:\n{}".format(
214 json.dumps(result, indent=4))
215 )
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500216
217
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500218@pytest.mark.sl_dup
219#PrometheusTargetDown
220@pytest.mark.full
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500221def test_running_telegraf_services(local_salt_client):
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500222 salt_output = local_salt_client.cmd(tgt='telegraf:agent',
223 fun='service.status',
224 param='telegraf',
225 expr_form='pillar',)
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500226
227 if not salt_output:
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200228 pytest.skip("Telegraf or telegraf:agent pillars are not found on "
229 "this environment.")
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500230
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500231 result = [{node: status} for node, status
232 in salt_output.items()
233 if status is False]
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200234 assert result == [], (
235 "Telegraf service is not running on the following nodes:\n{}".format(
236 result)
237 )
Ievgeniia Zadorozhna6775eb72018-11-09 19:50:04 +0300238
239
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500240@pytest.mark.sl_dup
241#PrometheusTargetDown
242@pytest.mark.full
Ievgeniia Zadorozhna6775eb72018-11-09 19:50:04 +0300243def test_running_fluentd_services(local_salt_client):
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500244 salt_output = local_salt_client.cmd(tgt='fluentd:agent',
245 fun='service.status',
246 param='td-agent',
Ievgeniia Zadorozhna6775eb72018-11-09 19:50:04 +0300247 expr_form='pillar')
248 result = [{node: status} for node, status
249 in salt_output.items()
250 if status is False]
Dmitriy Kruglova34a3042019-08-20 11:45:35 +0200251 assert result == [], (
252 "Fluentd check failed - td-agent service is not running on the "
253 "following nodes:\n{}".format(result)
254 )