blob: 73409518f8750331d3f0b3b021275d84c6f7fc24 [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
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -050021 assert requests.get('{0}://{1}:9200/'.format(proto, IP),
22 proxies=proxies, verify=False).status_code == 200, \
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050023 'Cannot check elasticsearch url on {}.'.format(IP)
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -050024 resp = requests.get('{0}://{1}:9200/_cat/health'.format(proto, IP),
25 proxies=proxies, verify=False).content
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050026 assert resp.split()[3] == 'green', \
27 'elasticsearch status is not good {}'.format(
28 json.dumps(resp, indent=4))
29 assert resp.split()[4] == '3', \
30 'elasticsearch status is not good {}'.format(
31 json.dumps(resp, indent=4))
32 assert resp.split()[5] == '3', \
33 'elasticsearch status is not good {}'.format(
34 json.dumps(resp, indent=4))
35 assert resp.split()[10] == '0', \
36 'elasticsearch status is not good {}'.format(
37 json.dumps(resp, indent=4))
38 assert resp.split()[13] == '100.0%', \
39 'elasticsearch status is not good {}'.format(
40 json.dumps(resp, indent=4))
Oleksii Zhurba020fab42017-11-01 20:13:28 +000041
42
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -050043@pytest.mark.sl_dup
44#stacklight-pytest
45@pytest.mark.full
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +030046@pytest.mark.usefixtures('check_kibana')
Ievgeniia Zadorozhna511f0ce2018-11-08 17:43:10 +030047def test_kibana_status(local_salt_client):
48 proxies = {"http": None, "https": None}
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050049 IP = local_salt_client.pillar_get(param='_param:stacklight_log_address')
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -050050 ssl = local_salt_client.pillar_get(
51 tgt='kibana:server',
52 param='haproxy:proxy:listen:kibana:binds:ssl:enabled')
53 proto = "https" if ssl else "http"
54
55 resp = requests.get('{0}://{1}:5601/api/status'.format(proto, IP),
56 proxies=proxies, verify=False).content
Ievgeniia Zadorozhna511f0ce2018-11-08 17:43:10 +030057 body = json.loads(resp)
58 assert body['status']['overall']['state'] == "green", \
59 "Kibana status is not expected: {}".format(
60 body['status']['overall'])
61 for i in body['status']['statuses']:
62 assert i['state'] == "green", \
63 "Kibana statuses are unexpected: {}".format(i)
64
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,
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -050092 verify = False,
Tatyana Leontovich30bd90c2019-01-11 16:26:32 +020093 data=data)
94 assert 200 == response.status_code, 'Unexpected code {}'.format(
95 response.text)
96 resp = json.loads(response.text)
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -050097 cluster_domain = local_salt_client.pillar_get(param='_param:cluster_domain')
Oleksii Zhurbad2847dc2018-02-16 15:13:09 -060098 monitored_nodes = []
Oleksii Zhurba7f463412018-03-21 16:32:44 -050099 for item_ in resp['aggregations']['uniq_hostname']['buckets']:
Oleksii Zhurbad2847dc2018-02-16 15:13:09 -0600100 node_name = item_['key']
101 monitored_nodes.append(node_name + '.' + cluster_domain)
102 missing_nodes = []
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500103 all_nodes = local_salt_client.test_ping(tgt='*').keys()
104 for node in all_nodes:
Oleksii Zhurbad2847dc2018-02-16 15:13:09 -0600105 if node not in monitored_nodes:
106 missing_nodes.append(node)
107 assert len(missing_nodes) == 0, \
Oleksii Zhurba84ce7fe2018-01-16 21:34:01 +0000108 'Not all nodes are in Elasticsearch. Found {0} keys, ' \
Oleksii Zhurbad2847dc2018-02-16 15:13:09 -0600109 'expected {1}. Missing nodes: \n{2}'. \
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500110 format(len(monitored_nodes), len(all_nodes), missing_nodes)
Oleksii Zhurba84ce7fe2018-01-16 21:34:01 +0000111
112
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500113@pytest.mark.sl_dup
114#DockerServiceMonitoring*
115@pytest.mark.full
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000116def test_stacklight_services_replicas(local_salt_client):
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300117 # TODO
118 # change to docker:swarm:role:master ?
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000119 salt_output = local_salt_client.cmd(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500120 tgt='I@docker:client:stack:monitoring and I@prometheus:server',
121 param='docker service ls',
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300122 expr_form='compound')
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500123
124 if not salt_output:
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300125 pytest.skip("docker:client:stack:monitoring or \
126 prometheus:server pillars are not found on this environment.")
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500127
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000128 wrong_items = []
129 for line in salt_output[salt_output.keys()[0]].split('\n'):
130 if line[line.find('/') - 1] != line[line.find('/') + 1] \
131 and 'replicated' in line:
132 wrong_items.append(line)
133 assert len(wrong_items) == 0, \
134 '''Some monitoring services doesn't have expected number of replicas:
135 {}'''.format(json.dumps(wrong_items, indent=4))
136
137
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500138@pytest.mark.smoke
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300139@pytest.mark.usefixtures('check_prometheus')
Oleksii Zhurba25215d92019-01-31 16:35:57 -0600140def test_prometheus_alert_count(local_salt_client, ctl_nodes_pillar):
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500141 IP = local_salt_client.pillar_get(param='_param:cluster_public_host')
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -0500142 proto = local_salt_client.pillar_get(
143 param='_param:cluster_public_protocol')
Oleksii Zhurba468e6c72018-01-16 17:43:15 +0000144 # keystone:server can return 3 nodes instead of 1
145 # this will be fixed later
146 # TODO
Oleksii Zhurba0c039ee2018-01-16 19:44:53 +0000147 nodes_info = local_salt_client.cmd(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500148 tgt=ctl_nodes_pillar,
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -0500149 param='curl -k -s {0}://{1}:15010/alerts | grep icon-chevron-down | '
150 'grep -v "0 active"'.format(proto, IP),
Oleksii Zhurba468e6c72018-01-16 17:43:15 +0000151 expr_form='pillar')
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500152
Oleksii Zhurba0c039ee2018-01-16 19:44:53 +0000153 result = nodes_info[nodes_info.keys()[0]].replace('</td>', '').replace(
154 '<td><i class="icon-chevron-down"></i> <b>', '').replace('</b>', '')
155 assert result == '', 'AlertManager page has some alerts! {}'.format(
156 json.dumps(result), indent=4)
Oleksii Zhurba468e6c72018-01-16 17:43:15 +0000157
158
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500159@pytest.mark.sl_dup
160#DockerServiceMonitoring* ??
161@pytest.mark.full
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000162def test_stacklight_containers_status(local_salt_client):
163 salt_output = local_salt_client.cmd(
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500164 tgt='I@docker:swarm:role:master and I@prometheus:server',
165 param='docker service ps $(docker stack services -q monitoring)',
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300166 expr_form='compound')
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500167
168 if not salt_output:
Oleksii Zhurba8ce9fcf2018-10-05 18:38:22 +0300169 pytest.skip("docker:swarm:role:master or prometheus:server \
170 pillars are not found on this environment.")
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500171
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000172 result = {}
Oleksii Zhurba468e6c72018-01-16 17:43:15 +0000173 # for old reclass models, docker:swarm:role:master can return
174 # 2 nodes instead of one. Here is temporary fix.
175 # TODO
176 if len(salt_output.keys()) > 1:
177 if 'CURRENT STATE' not in salt_output[salt_output.keys()[0]]:
178 del salt_output[salt_output.keys()[0]]
Oleksii Zhurbaf2af6372017-11-01 22:53:03 +0000179 for line in salt_output[salt_output.keys()[0]].split('\n')[1:]:
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000180 shift = 0
Oleksii Zhurba020fab42017-11-01 20:13:28 +0000181 if line.split()[1] == '\\_':
182 shift = 1
183 if line.split()[1 + shift] not in result.keys():
184 result[line.split()[1]] = 'NOT OK'
185 if line.split()[4 + shift] == 'Running' \
186 or line.split()[4 + shift] == 'Ready':
187 result[line.split()[1 + shift]] = 'OK'
188 assert 'NOT OK' not in result.values(), \
189 '''Some containers are in incorrect state:
190 {}'''.format(json.dumps(result, indent=4))
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500191
192
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500193@pytest.mark.sl_dup
194#PrometheusTargetDown
195@pytest.mark.full
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500196def test_running_telegraf_services(local_salt_client):
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500197 salt_output = local_salt_client.cmd(tgt='telegraf:agent',
198 fun='service.status',
199 param='telegraf',
200 expr_form='pillar',)
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500201
202 if not salt_output:
203 pytest.skip("Telegraf or telegraf:agent \
204 pillar are not found on this environment.")
205
Oleksii Zhurbae592ed12018-06-21 18:01:09 -0500206 result = [{node: status} for node, status
207 in salt_output.items()
208 if status is False]
209 assert result == [], 'Telegraf service is not running ' \
Oleksii Zhurba9848e212018-09-05 10:53:51 -0500210 'on following nodes: {}'.format(result)
Ievgeniia Zadorozhna6775eb72018-11-09 19:50:04 +0300211
212
Oleksii Zhurba5b15b9b2019-05-09 18:53:40 -0500213@pytest.mark.sl_dup
214#PrometheusTargetDown
215@pytest.mark.full
Ievgeniia Zadorozhna6775eb72018-11-09 19:50:04 +0300216def test_running_fluentd_services(local_salt_client):
Oleksii Zhurba4bfd2ee2019-04-10 21:56:58 -0500217 salt_output = local_salt_client.cmd(tgt='fluentd:agent',
218 fun='service.status',
219 param='td-agent',
Ievgeniia Zadorozhna6775eb72018-11-09 19:50:04 +0300220 expr_form='pillar')
221 result = [{node: status} for node, status
222 in salt_output.items()
223 if status is False]
224 assert result == [], 'Fluentd check failed: td-agent service is not ' \
Oleksii Zhurba85f55fe2019-06-10 17:30:53 -0500225 'running on following nodes:'.format(result)