Merge "WIP: Add role to auto install docker on hosts"
[barometer.git] / baro_tests / local_agent.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 # Patch on October 10 2017
15
16 """Executing test of LocalAgent"""
17
18 import os
19 import pika
20 import requests
21 import time
22
23 import tests
24
25 logger = None
26
27
28 class LocalAgentClient(object):
29     """Client to request LocalAgent"""
30     def __init__(self, host, port, user, passwd):
31         """
32         Keyword arguments:
33         host -- Host URL
34         port -- Host Port
35         user -- Username
36         passwd -- Password
37         """
38         self._host = host
39         self._port = port
40         self._user = user
41         self._passwd = passwd
42
43     def set(self, file):
44         logger.error('Do nothing to LocalAgent')
45
46     def __str__(self):
47         return ('host: {0}, port: {1}, user: {2}, pass: {3}'
48                 .format(self._host, self._port,
49                         self._user, (self._passwd and '<Filterd>')))
50
51
52 class RestLocalAgentClient(LocalAgentClient):
53     """Client to request LocalAgent using REST"""
54     def __init__(self, host, port, user, passwd):
55         super(self.__class__, self).__init__(host, port, user, passwd)
56
57     def set(self, file):
58         logger.debug('Send to localagent using REST -- {}'.format(str(self)))
59
60         if not os.path.isfile(file):
61             print '{} is not found'.format(file)
62             return False
63         filename = os.path.basename(file)
64
65         url = 'http://{0}:{1}/collectd/conf'.format(self._host, self._port)
66         config = {'file': (filename, open(file, 'r'))}
67         requests.post(url, files=config)
68
69         return True
70
71
72 class PubLocalAgentClient(LocalAgentClient):
73     """Client to request LocalAgent using AMQP Publish"""
74     def __init__(self, host, port, user, passwd):
75         super(self.__class__, self).__init__(host, port, user, passwd)
76
77     def set(self, file):
78         logger.debug('Send to localagent using AMQP Publish -- {}'
79                      .format(str(self)))
80
81         if not os.path.isfile(file):
82             print '{} is not found'.format(file)
83             return False
84         filename = os.path.basename(file)
85         filebody = open(file, 'r').read()
86         message = filename + '/' + filebody
87
88         credentials = pika.PlainCredentials(self._user, self._passwd)
89         connection = pika.BlockingConnection(pika.ConnectionParameters(
90                 host=self._host, port=int(self._port),
91                 credentials=credentials))
92         channel = connection.channel()
93         channel.exchange_declare(exchange='collectd-conf',
94                                  exchange_type='fanout')
95         channel.basic_publish(exchange='collectd-conf',
96                               routing_key='',
97                               body=message)
98
99         connection.close()
100         return True
101
102
103 def _process_localagent_result(compute_node, testfunc,
104                                result, results_list, node):
105     """Print LocalAgent test result and append it to results list.
106
107     Keyword arguments:
108     testfunc -- localagent function name
109     result -- boolean test result
110     results_list -- results list
111     """
112     if result:
113         logger.info(
114             'Test case for {0} with LocalAgent PASSED on {1}.'.format(
115                 node, testfunc))
116     else:
117         logger.error(
118             'Test case for {0} with LocalAgent FAILED on {1}.'.format(
119                 node, testfunc))
120     results_list.append((compute_node, "LocalAgent", testfunc, result))
121
122
123 def _print_result_of_localagent(compute_ids, results):
124     """Print results of LocalAgent.
125
126     Keyword arguments:
127     compute_ids -- list of compute node IDs
128     results -- results list
129     """
130     compute_node_names = ['Node-{}'.format(i) for i in range(
131         len((compute_ids)))]
132     all_computes_in_line = ''
133     for compute in compute_node_names:
134         all_computes_in_line += '| ' + compute + (' ' * (7 - len(compute)))
135     line_of_nodes = '| Test           ' + all_computes_in_line + '|'
136     logger.info('=' * 70)
137     logger.info('+' + ('-' * ((9 * len(compute_node_names))+16)) + '+')
138     logger.info(
139         '|' + ' ' * ((9*len(compute_node_names))/2)
140         + ' LOCALAGENT TEST'
141         + ' ' * (
142             9*len(compute_node_names) - (9*len(compute_node_names))/2)
143         + '|')
144     logger.info(
145         '+' + ('-' * 16) + '+' + (('-' * 8) + '+') * len(compute_node_names))
146     logger.info(line_of_nodes)
147     logger.info(
148         '+' + ('-' * 16) + '+' + (('-' * 8) + '+') * len(compute_node_names))
149
150     testname = "LocalAgent"
151     print_line = ''
152     for id in compute_ids:
153         all_result = \
154             'FAIL' if [
155                 testfunc for comp_id, testname, testfunc, res in results
156                 if comp_id == id and not res] else 'PASS'
157         print_line += '| ' + all_result + '   '
158     logger.info(
159         '| {}'.format(testname) + (' ' * (15 - len(testname)))
160         + print_line + '|')
161
162     for testfunc in ['Server', 'InfoFetch']:
163         print_line = ''
164         for id in compute_ids:
165             if (id, testname, testfunc, True) in results:
166                 print_line += ' PASS   |'
167             elif (id, testname, testfunc, False) in results:
168                 print_line += ' FAIL   |'
169             else:
170                 print_line += ' SKIP   |'
171         logger.info(
172             '|  {}'.format(testfunc) + (' ' * (14-len(testfunc)))
173             + '|' + print_line)
174
175     logger.info(
176         '+' + ('-' * 16) + '+'
177         + (('-' * 8) + '+') * len(compute_node_names))
178     logger.info('=' * 70)
179
180
181 def local_agent_main(bt_logger, conf, computes):
182     """Check LocalAgent of each compute node.
183
184     Keyword arguments:
185     bt_logger -- logger instance
186     computes -- compute node list
187     """
188     global logger
189     logger = bt_logger
190
191     compute_ids = []
192     agent_results = []
193     for compute_node in computes:
194         node_id = compute_node.get_id()
195         compute_ids.append(node_id)
196
197         agent_server_running = conf.is_localagent_server_running(compute_node)
198         agent_infofetch_running = (
199             conf.is_localagent_infofetch_running(compute_node) and
200             conf.is_redis_running(compute_node))
201
202         if agent_server_running:
203             test_name = 'barotest'
204             tmpfile = '/tmp/' + test_name + '.conf'
205
206             agent_config = conf.get_localagent_config(compute_node)
207             listen_ip = compute_node.get_ip()
208             listen_port = agent_config.get('server').get('listen_port')
209             amqp_host = agent_config.get('server').get('amqp_host')
210             amqp_port = agent_config.get('server').get('amqp_port')
211             amqp_user = agent_config.get('server').get('amqp_user')
212             amqp_passwd = agent_config.get('server').get('amqp_password')
213             rest_client = RestLocalAgentClient(
214                               listen_ip, listen_port, '', '')
215             pub_client = PubLocalAgentClient(
216                              amqp_host, amqp_port, amqp_user,
217                              amqp_passwd)
218
219             all_res = True
220             for client in [rest_client, pub_client]:
221                 tests.test_localagent_server_set_collectd(
222                     compute_node, tmpfile, logger, client)
223                 sleep_time = 1
224                 logger.info(
225                     'Sleeping for {} seconds'.format(sleep_time)
226                     + ' before localagent server test...')
227                 time.sleep(sleep_time)
228                 res = conf.check_localagent_dummy_included(
229                           compute_node, test_name)
230                 all_res = all_res and res
231
232             _process_localagent_result(
233                 compute_node.get_id(), 'Server',
234                 all_res, agent_results, compute_node.get_name())
235
236         if agent_infofetch_running:
237             test_name = 'barotest'
238             resources = conf.create_testvm(compute_node, test_name)
239             sleep_time = 5
240             logger.info(
241                 'Sleeping for {} seconds'.format(sleep_time)
242                 + ' before localagent infofetch test...')
243             time.sleep(sleep_time)
244             res = conf.test_localagent_infofetch_get_data(
245                       compute_node, test_name)
246             conf.delete_testvm(resources)
247
248             _process_localagent_result(
249                 compute_node.get_id(), 'InfoFetch',
250                 res, agent_results, compute_node.get_name())
251
252     _print_result_of_localagent(compute_ids, agent_results)
253
254     for res in agent_results:
255         if not res[3]:
256             logger.error('Some tests have failed or have not been executed')
257             logger.error('LocalAgent test is Fail')
258             return 1
259         else:
260             pass
261     return 0