Merge "Added Functest testcases for Barometer project"
[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
19
20 def test_gnocchi_node_sends_data(
21         node_id, interval, logger, client, criteria_list=[],
22         resource_id_substrings=['']):
23     logger.info("Gnocchi test cases will be coming soon!!")
24     return False
25
26
27 def test_ceilometer_node_sends_data(
28         node_id, interval, logger, client, criteria_list=[],
29         resource_id_substrings=['']):
30     """ Test that data reported by Ceilometer are updated in the given interval.
31
32     Keyword arguments:
33     node_id -- node ID
34     interval -- interval to check
35     logger -- logger instance
36     client -- CeilometerClient instance
37     criteria_list -- list of criteria used in ceilometer calls
38     resource_id_substrings -- list of substrings to search for in resource ID
39
40     Return boolean value indicating success or failure.
41     """
42
43     def _search_meterlist_latest_entry(meterlist, node_str, substr=''):
44         """Search for latest entry in meter list
45
46         Keyword arguments:
47         meterlist -- list of metrics
48         node_str -- name of node, which will be found in meter list
49         substr -- substring which will be found in meter list
50
51         Return latest entry from meter list which contains given node string
52         and (if defined) subsrting.
53         """
54         res = [
55             entry for entry in meterlist if node_str in entry['resource_id']
56             and substr in entry['resource_id']]
57         if res:
58             return res[0]
59         else:
60             return []
61
62     client.auth_token()
63     timestamps = {}
64     node_str = 'node-{}'.format(node_id) if node_id else ''
65
66     logger.info(
67         'Searching for timestamps of latest entries{0}{1}{2}...'.format(
68             '' if node_str == '' else ' for {}'.format(node_str),
69             '' if len(criteria_list) == 0 else (
70                 ' for criteria ' + ', '.join(criteria_list)),
71             '' if resource_id_substrings == [''] else
72             ' and resource ID substrings "{}"'.format(
73                 '", "'.join(resource_id_substrings))))
74     for criterion in criteria_list if len(criteria_list) > 0 else [None]:
75         meter_list = client.get_gnocchi_metrics(criterion)
76         for resource_id_substring in resource_id_substrings:
77             last_entry = _search_meterlist_latest_entry(
78                 meter_list, node_str, resource_id_substring)
79             if len(last_entry) == 0:
80                 logger.error('Entry{0}{1}{2} not found'.format(
81                     '' if node_str == '' else ' for {}'.format(node_str),
82                     '' if criterion is None else 'for criterion {}'.format(
83                         criterion),
84                     '' if resource_id_substring == '' else 'and resource '
85                     + 'ID substring "{}"'.format(resource_id_substring)))
86                 return False
87             timestamp = last_entry['timestamp']
88             logger.debug('Last entry found: {0} {1}'.format(
89                 timestamp, last_entry['resource_id']))
90             timestamps[(criterion, resource_id_substring)] = timestamp
91
92     attempt = 1
93     is_passed = False
94     while (attempt <= 10) and not is_passed:
95         is_passed = True
96         # wait Interval time + 2 sec for db update
97         sleep_time = interval + 2
98         if attempt > 1:
99             logger.info('Starting attempt {}'.format(attempt))
100         logger.info(
101             'Sleeping for {} seconds to get updated entries '.format(sleep_time)
102             + '(interval is {} sec)...'.format(interval))
103         time.sleep(sleep_time)
104
105         logger.info(
106             'Searching for timestamps of latest entries{}{}{}...' .format(
107                 '' if node_str == '' else ' for {}'.format(node_str),
108                 '' if len(criteria_list) == 0 else (
109                     ' for criteria ' + ', ' .join(criteria_list)),
110                 '' if resource_id_substrings == ['']
111                 else ' and resource ID substrings "{}"' .format(
112                     '", "'.join(resource_id_substrings))))
113         for criterion in criteria_list if len(criteria_list) > 0 else [None]:
114             meter_list = client.get_ceil_metrics(criterion)
115             for resource_id_substring in resource_id_substrings:
116                 last_entry = _search_meterlist_latest_entry(
117                     meter_list, node_str, resource_id_substring)
118                 if len(last_entry) == 0:
119                     logger.error('Entry{0}{1}{2} not found'.format(
120                         '' if node_str == '' else ' for {}'.format(node_str),
121                         '' if criterion is None else 'for criterion {}'.format(
122                             criterion),
123                         '' if resource_id_substring == '' else ' and resource'
124                         + 'ID substring "{}"'.format(resource_id_substring)))
125                     return False
126                 timestamp = last_entry['timestamp']
127                 logger.debug('Last entry found: {} {}'.format(
128                     timestamp, last_entry['resource_id']))
129                 if timestamp == timestamps[(criterion, resource_id_substring)]:
130                     logger.warning(
131                         'Last entry{0}{1}{2} has the same timestamp as '
132                         + 'before the sleep'.format(
133                             '' if node_str == '' else ' for {}'.format(
134                                 node_str),
135                             '' if resource_id_substring == ''
136                             else ', substring "{}"'.format(
137                                 resource_id_substring),
138                             '' if criterion is None else
139                             ' for criterion {}'.format(criterion)))
140                     is_passed = False
141         attempt += 1
142         if not is_passed:
143             logger.warning('After sleep new entries were not found.')
144     if not is_passed:
145         logger.error('This was the last attempt.')
146         return False
147     logger.info('All latest entries found.')
148     return True
149
150
151 def test_csv_handles_plugin_data(
152         compute, interval, plugin, plugin_subdirs, meter_categories,
153         logger, client):
154     """Check that CSV data are updated by the plugin.
155
156     Keyword arguments:
157     compute -- object compute node
158     interval -- interval to check
159     plugin -- plugin which will be tested
160     plugin_subdirs -- list subdirectories in csv folder
161     meter_categories -- list of meter categories which will be tested
162     logger -- logger instance
163     client -- CSVClient instance
164
165     Return boolean value indicating success or failure.
166     """
167     logger.info(
168         'Getting CSV metrics of plugin {} on compute node {}...' .format(
169             plugin, compute.get_id()))
170     logger.debug('Interval: {}'.format(interval))
171     logger.debug('Plugin subdirs: {}'.format(plugin_subdirs))
172     logger.debug('Plugin meter categories: {}'.format(meter_categories))
173     plugin_metrics = client.get_csv_metrics(
174         compute, plugin_subdirs, meter_categories)
175     if len(plugin_metrics) < len(plugin_subdirs) * len(meter_categories):
176         logger.error('Some plugin metrics not found')
177         return False
178
179     logger.info(
180         'Checking that last two entries in metrics are corresponding'
181         + 'to interval...')
182     for metric in plugin_metrics:
183         logger.debug('{0} {1} {2} ... '.format(metric[0], metric[1], metric[2]))
184         if metric[3] - metric[2] != interval:
185             logger.error(
186                 'Time of last two entries differ by '
187                 + '{}, but interval is {}'.format(
188                     metric[3] - metric[2], interval))
189             return False
190         else:
191             logger.debug('OK')
192     logger.info('OK')
193
194     # wait Interval time + 2 sec
195     sleep_time = interval + 2
196     logger.info(
197         'Sleeping for {} seconds to get updated entries '.format(sleep_time)
198         + '(interval is {} sec)...'.format(interval))
199     time.sleep(sleep_time)
200
201     logger.info('Getting new metrics of compute node {}...'.format(
202         compute.get_name()))
203     plugin_metrics2 = client.get_csv_metrics(
204         compute, plugin_subdirs, meter_categories)
205     if len(plugin_metrics2) < len(plugin_subdirs) * len(meter_categories):
206         logger.error('Some plugin metrics not found')
207         return False
208
209     logger.info('Comparing old and new metrics...')
210     logger.debug(plugin_metrics)
211     logger.debug(plugin_metrics2)
212     if len(plugin_metrics) != len(plugin_metrics2):
213         logger.error('Plugin metrics length before and after sleep differ')
214         return False
215     for i in range(len(plugin_metrics2)):
216         logger.debug('{0} {1} {2}  - {3} {4} {5} ... '.format(
217             plugin_metrics[i][0], plugin_metrics[i][1],
218             plugin_metrics[i][2], plugin_metrics2[i][0],
219             plugin_metrics2[i][1], plugin_metrics2[i][2]))
220         if plugin_metrics[i] == plugin_metrics2[i]:
221             logger.error('FAIL')
222             return False
223         else:
224             logger.debug('OK')
225     logger.info('OK')
226
227     return True