Merge "Add git installation to docker guide"
[barometer.git] / baro_tests / tests.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright 2017 OPNFV
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
8 #
9 #      http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
15 # under the License.
16
17 """Function for testing collectd plug-ins with different oup plug-ins"""
18
19 import time
20 import math
21
22
23 def test_snmp_sends_data(
24         compute, interval, logger, client, mib_file=None,
25         mib_strings=None, in_command=None, conf=None):
26     """Check that SNMP deta are updated"""
27     logger.debug('Interval: {}'.format(interval))
28     if mib_file is not None:
29         logger.info(
30             'Getting SNMP metrics of MIB file {} and '.format(mib_file)
31             + 'following MIB strings: {}...'.format(', '.join(mib_strings)))
32     snmp_metrics = client.get_snmp_metrics(compute, mib_file, mib_strings)
33     if mib_file is None:
34         return len(snmp_metrics) > 1
35     if in_command is not None and conf is not None:
36         conf.execute_command(in_command, compute.get_ip())
37
38     attempt = 1
39     is_passed = False
40     while (attempt <= 10) and not is_passed:
41         is_passed = True
42         # wait Interval time + 2 sec for db update
43         sleep_time = interval + 2
44         if attempt > 1:
45             logger.info('Starting attempt {}'.format(attempt))
46         logger.info(
47             'Sleeping for {} seconds to get updated entries'.format(sleep_time)
48             + ' (interval is {} sec)...'.format(interval))
49         time.sleep(sleep_time)
50
51         logger.info(
52             'Getting SNMP metrics of MIB file {} and '.format(mib_file)
53             + 'following MIB strings: {}...'.format(', '.join(mib_strings)))
54         snmp_metrics2 = client.get_snmp_metrics(compute, mib_file, mib_strings)
55         unchanged_snmp_metrics = [
56             snmp_metric for snmp_metric in snmp_metrics
57             if snmp_metrics[snmp_metric] == snmp_metrics2[snmp_metric]]
58         if len(unchanged_snmp_metrics) > 0:
59             logger.error("Following SNMP metrics didn't change: {}".format(
60                 ', '.join(unchanged_snmp_metrics)))
61             is_passed = False
62         attempt += 1
63         if not is_passed:
64             logger.warning('After sleep new entries were not found.')
65     if not is_passed:
66         logger.error('This was the last attempt.')
67         return False
68     logger.info('All SNMP metrics are changed.')
69     return True
70
71
72 def test_ceilometer_node_sends_data(
73         node_id, interval, logger, client, criteria_list=[],
74         resource_id_substrings=['']):
75     """ Test that data reported by Ceilometer are updated in the given interval.
76
77     Keyword arguments:
78     node_id -- node ID
79     interval -- interval to check
80     logger -- logger instance
81     client -- CeilometerClient instance
82     criteria_list -- list of criteria used in ceilometer calls
83     resource_id_substrings -- list of substrings to search for in resource ID
84
85     Return boolean value indicating success or failure.
86     """
87
88     def _search_meterlist_latest_entry(meterlist, node_str, substr=''):
89         """Search for latest entry in meter list
90
91         Keyword arguments:
92         meterlist -- list of metrics
93         node_str -- name of node, which will be found in meter list
94         substr -- substring which will be found in meter list
95
96         Return latest entry from meter list which contains given node string
97         and (if defined) subsrting.
98         """
99         res = [
100             entry for entry in meterlist if node_str in entry['resource_id']
101             and substr in entry['resource_id']]
102         if res:
103             return res[0]
104         else:
105             return []
106
107     client.auth_token()
108     timestamps = {}
109     node_str = 'node-{}'.format(node_id) if node_id else ''
110
111     logger.info(
112         'Searching for timestamps of latest entries{0}{1}{2}...'.format(
113             '' if node_str == '' else ' for {}'.format(node_str),
114             '' if len(criteria_list) == 0 else (
115                 ' for criteria ' + ', '.join(criteria_list)),
116             '' if resource_id_substrings == [''] else
117             ' and resource ID substrings "{}"'.format(
118                 '", "'.join(resource_id_substrings))))
119     for criterion in criteria_list if len(criteria_list) > 0 else [None]:
120         meter_list = client.get_gnocchi_metrics(criterion)
121         for resource_id_substring in resource_id_substrings:
122             last_entry = _search_meterlist_latest_entry(
123                 meter_list, node_str, resource_id_substring)
124             if len(last_entry) == 0:
125                 logger.error('Entry{0}{1}{2} not found'.format(
126                     '' if node_str == '' else ' for {}'.format(node_str),
127                     '' if criterion is None else 'for criterion {}'.format(
128                         criterion),
129                     '' if resource_id_substring == '' else 'and resource '
130                     + 'ID substring "{}"'.format(resource_id_substring)))
131                 return False
132             timestamp = last_entry['timestamp']
133             logger.debug('Last entry found: {0} {1}'.format(
134                 timestamp, last_entry['resource_id']))
135             timestamps[(criterion, resource_id_substring)] = timestamp
136
137     attempt = 1
138     is_passed = False
139     while (attempt <= 10) and not is_passed:
140         is_passed = True
141         # wait Interval time + 2 sec for db update
142         sleep_time = interval + 2
143         if attempt > 1:
144             logger.info('Starting attempt {}'.format(attempt))
145         logger.info(
146             'Sleeping for {} seconds to get updated entries '.format(sleep_time)
147             + '(interval is {} sec)...'.format(interval))
148         time.sleep(sleep_time)
149
150         logger.info(
151             'Searching for timestamps of latest entries{}{}{}...' .format(
152                 '' if node_str == '' else ' for {}'.format(node_str),
153                 '' if len(criteria_list) == 0 else (
154                     ' for criteria ' + ', ' .join(criteria_list)),
155                 '' if resource_id_substrings == ['']
156                 else ' and resource ID substrings "{}"' .format(
157                     '", "'.join(resource_id_substrings))))
158         for criterion in criteria_list if len(criteria_list) > 0 else [None]:
159             meter_list = client.get_ceil_metrics(criterion)
160             for resource_id_substring in resource_id_substrings:
161                 last_entry = _search_meterlist_latest_entry(
162                     meter_list, node_str, resource_id_substring)
163                 if len(last_entry) == 0:
164                     logger.error('Entry{0}{1}{2} not found'.format(
165                         '' if node_str == '' else ' for {}'.format(node_str),
166                         '' if criterion is None else 'for criterion {}'.format(
167                             criterion),
168                         '' if resource_id_substring == '' else ' and resource'
169                         + 'ID substring "{}"'.format(resource_id_substring)))
170                     return False
171                 timestamp = last_entry['timestamp']
172                 logger.debug('Last entry found: {} {}'.format(
173                     timestamp, last_entry['resource_id']))
174                 if timestamp == timestamps[(criterion, resource_id_substring)]:
175                     logger.warning(
176                         'Last entry{0}{1}{2} has the same timestamp as '
177                         + 'before the sleep'.format(
178                             '' if node_str == '' else ' for {}'.format(
179                                 node_str),
180                             '' if resource_id_substring == ''
181                             else ', substring "{}"'.format(
182                                 resource_id_substring),
183                             '' if criterion is None else
184                             ' for criterion {}'.format(criterion)))
185                     is_passed = False
186         attempt += 1
187         if not is_passed:
188             logger.warning('After sleep new entries were not found.')
189     if not is_passed:
190         logger.error('This was the last attempt.')
191         return False
192     logger.info('All latest entries found.')
193     return True
194
195
196 def test_csv_handles_plugin_data(
197         compute, interval, plugin, plugin_subdirs, meter_categories,
198         logger, client):
199     """Check that CSV data are updated by the plugin.
200
201     Keyword arguments:
202     compute -- object compute node
203     interval -- interval to check
204     plugin -- plugin which will be tested
205     plugin_subdirs -- list subdirectories in csv folder
206     meter_categories -- list of meter categories which will be tested
207     logger -- logger instance
208     client -- CSVClient instance
209
210     Return boolean value indicating success or failure.
211     """
212     logger.info(
213         'Getting CSV metrics of plugin {} on compute node {}...' .format(
214             plugin, compute.get_id()))
215     logger.debug('Interval: {}'.format(interval))
216     logger.debug('Plugin subdirs: {}'.format(plugin_subdirs))
217     logger.debug('Plugin meter categories: {}'.format(meter_categories))
218     plugin_metrics = client.get_csv_metrics(
219         compute, plugin_subdirs, meter_categories)
220     if len(plugin_metrics) < len(plugin_subdirs) * len(meter_categories):
221         logger.error('Some plugin metrics not found')
222         return False
223
224     logger.info(
225         'Checking that last two entries in metrics are corresponding'
226         + 'to interval...')
227     for metric in plugin_metrics:
228         logger.debug('{0} {1} {2} ... '.format(metric[0], metric[1], metric[2]))
229         # When there's a small interval or many metrics, there may be a slight
230         # delay in writing the metrics. e.g. a gap of 1.* is okay for an interval of 1
231         if math.floor(metric[3] - metric[2]) > interval + 1:
232             logger.error(
233                 'Time of last two entries differ by '
234                 + '{}, but interval is {}'.format(
235                     metric[3] - metric[2], interval))
236             return False
237         else:
238             logger.debug('OK')
239     logger.info('OK')
240
241     # wait Interval time + 2 sec
242     sleep_time = interval + 2
243     logger.info(
244         'Sleeping for {} seconds to get updated entries '.format(sleep_time)
245         + '(interval is {} sec)...'.format(interval))
246     time.sleep(sleep_time)
247
248     logger.info('Getting new metrics of compute node {}...'.format(
249         compute.get_name()))
250     plugin_metrics2 = client.get_csv_metrics(
251         compute, plugin_subdirs, meter_categories)
252     if len(plugin_metrics2) < len(plugin_subdirs) * len(meter_categories):
253         logger.error('Some plugin metrics not found')
254         return False
255
256     logger.info('Comparing old and new metrics...')
257     logger.debug(plugin_metrics)
258     logger.debug(plugin_metrics2)
259     if len(plugin_metrics) != len(plugin_metrics2):
260         logger.error('Plugin metrics length before and after sleep differ')
261         return False
262     for i in range(len(plugin_metrics2)):
263         logger.debug('{0} {1} {2}  - {3} {4} {5} ... '.format(
264             plugin_metrics[i][0], plugin_metrics[i][1],
265             plugin_metrics[i][2], plugin_metrics2[i][0],
266             plugin_metrics2[i][1], plugin_metrics2[i][2]))
267         if plugin_metrics[i] == plugin_metrics2[i]:
268             logger.error('FAIL')
269             return False
270         else:
271             logger.debug('OK')
272     logger.info('OK')
273
274     return True
275
276
277 def test_localagent_server_set_collectd(compute, file, logger, client):
278     with open(file, mode='w') as f:
279         f.write('# dummy conf\n')
280     res = client.set(file)
281     if res:
282         logger.info('set collectd PASS')
283     else:
284         logger.error('set collectd FAIL')
285
286     return res