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