Bottlenecks testpmd scale-up testcase.
[bottlenecks.git] / utils / parser.py
1 #!/usr/bin/env python
2 ##############################################################################
3 # Copyright (c) 2017 Huawei Technologies Co.,Ltd and others.
4 #
5 # All rights reserved. This program and the accompanying materials
6 # are made available under the terms of the Apache License, Version 2.0
7 # which accompanies this distribution, and is available at
8 # http://www.apache.org/licenses/LICENSE-2.0
9 ##############################################################################
10 '''This file realize the function of how to parser a config file.
11 This contain Two part:
12 Frist is Init some variables the will be used.
13 Second is reading config file.'''
14
15 import os
16 import yaml
17 import json
18 import time
19 from pyroute2 import IPDB
20 import utils.infra_setup.runner.docker_env as docker_env
21
22
23 class Parser():
24
25     bottlenecks_config = {}
26     bottlenecks_test = {}
27
28     @classmethod
29     def config_init(cls):
30         cls.code_dir = os.path.dirname(os.path.abspath(__file__))
31         cls.root_dir = os.path.dirname(cls.code_dir)
32         cls.test_dir = os.path.join(cls.root_dir, 'testsuites')
33         config_dir = os.path.join(
34             cls.root_dir,
35             'config',
36             'config.yaml')
37
38         with open(config_dir) as file:
39             config_info = yaml.load(file)
40             common_config = config_info['common_config']
41             cls.bottlenecks_config["releng_dir"] = common_config["releng_dir"]
42             cls.bottlenecks_config["fetch_os"] = common_config["fetch_os_file"]
43             cls.bottlenecks_config["log_dir"] = common_config['log_dir']
44             cls.bottlenecks_config["rc_dir"] = common_config['rc_dir']
45             cls.bottlenecks_config["pod_info"] = common_config['pod_info']
46             cls.bottlenecks_config["yardstick_rc_dir"] = \
47                 common_config['yardstick_rc_dir']
48             cls.config_dir_check(cls.bottlenecks_config["log_dir"])
49
50     @classmethod
51     def story_read(cls, testcase, story_name):
52         story_dir = os.path.join(
53             cls.test_dir,
54             testcase,
55             'testsuite_story',
56             story_name + '.yaml')
57         with open(story_dir) as file:
58             story_parser = yaml.load(file)
59         for case_name in story_parser['testcase']:
60             Parser.testcase_read(testcase, case_name)
61
62         return cls.bottlenecks_test
63
64     @classmethod
65     def testcase_read(cls, testcase, testcase_name):
66
67         testcase_dir = os.path.join(
68             cls.test_dir,
69             testcase,
70             'testcase_cfg',
71             testcase_name)
72         testcase_local = testcase_dir + ".yaml"
73         with open(testcase_local) as f:
74             cls.bottlenecks_test[testcase_name] = yaml.load(f)
75
76         return cls.bottlenecks_test
77
78     @classmethod
79     def config_dir_check(cls, dirname):
80         if dirname is None:
81             dirname = '/tmp/'
82         if not os.path.exists(dirname):
83             os.makedirs(dirname)
84
85     @classmethod
86     def testcase_out_dir(cls, testcase):
87         file_name = os.getenv("OUTPUT_FILE")
88         if file_name is None:
89             file_suffix = time.strftime('%H_%M', time.localtime(time.time()))
90             suffix_name = "_" + str(file_suffix)
91             out_name = cls.bottlenecks_config["log_dir"] + testcase
92             outfile_name = out_name + suffix_name + ".out"
93         else:
94             out_name = str(file_name)
95             outfile_name = cls.bottlenecks_config["log_dir"] + out_name
96         return outfile_name
97
98     @staticmethod
99     def config_parser(testcase_cfg, parameters):
100         test_cfg = testcase_cfg['test_config']
101         stack_cfg = testcase_cfg['stack_config']
102         # TO-DO add cli parameters to stack_config.
103         return test_cfg, stack_cfg
104
105     @staticmethod
106     def convert_docker_env(config, ip_type):
107         if ip_type is "dashboard":
108             config["contexts"]["dashboard_ip"] = \
109                 docker_env.ELK_info["ip"] + ":9200"
110         elif ip_type is "yardstick":
111             config["contexts"]["yardstick_ip"] = \
112                 docker_env.yardstick_info["ip"] + ":8888"
113
114     @staticmethod
115     def ip_parser(ip_type):
116         with IPDB() as ip:
117             GATEWAY_IP = ip.routes['default'].gateway
118         if ip_type is "dashboard":
119             TEST_IP = GATEWAY_IP + ":9200"
120         elif ip_type is "yardstick_test_ip":
121             TEST_IP = GATEWAY_IP + ":8888"
122         return TEST_IP
123
124     @staticmethod
125     def result_to_file(data, file_name):
126         with open(file_name, "a") as f:
127             f.write(json.dumps(data, f))
128             f.write("\n")
129
130     @staticmethod
131     def str_to_list(str_org):
132         try:
133             data = str_org.split(',')
134         except AttributeError:
135             data = []
136             data.append(str_org)
137         return data
138
139
140 class HeatTemplate_Parser():
141     """parser a Heat template and a method to deploy template to a stack"""
142
143     def __init__(self):
144         self.heat_date = {}
145         self.heat_date["resources"] = {}
146         self.heat_date["outputs"] = {}
147         self.heat_date["heat_template_version"] = "2013-05-23"
148         self.heat_date["description"] = {"Stack built by the bottlenecks"
149                                          " framework for root."}
150
151     def add_security_group(self, name):
152         """add to the template a Neutron SecurityGroup"""
153         security_name = name + "-security_group"
154         self.heat_date["resources"][security_name] = {
155             "type": "OS::Neutron::SecurityGroup",
156             "properties": {
157                 "name": security_name,
158                 "description": "Group allowing icmp and upd/tcp on all ports",
159                 "rules": [
160                     {"remote_ip_prefix": "0.0.0.0/0",
161                      "protocol": "tcp",
162                      "port_range_min": "1",
163                      "port_range_max": "65535"},
164                     {"remote_ip_prefix": "0.0.0.0/0",
165                      "protocol": "udp",
166                      "port_range_min": "1",
167                      "port_range_max": "65535"},
168                     {"remote_ip_prefix": "0.0.0.0/0",
169                      "protocol": "icmp"}
170                 ]
171             }
172         }
173
174         self.heat_date["outputs"][security_name] = {
175             "description": "ID of Security Group",
176             "value": {"get_resource": security_name}
177         }
178
179     def add_keypair(self, name):
180         """add to the template a Nova KeyPair"""
181         key_name = name + "key"
182         with open(Parser.root_dir +
183                   "utils/infra_setup/"
184                   "bottlenecks_key/bottlenecks_key.pub") as f:
185             key_content = f.read()
186             self.heat_date["resources"][key_name] = {
187                 "type": "OS::Nova::KeyPair",
188                 "properties": {
189                     "name": key_name,
190                     "public_key": key_content
191                 }
192             }
193
194     def add_network(self, name):
195         """add to the template a Neutron Net"""
196         network_name = name + "-net"
197         self.heat_date["resources"][network_name] = {
198             "type": "OS::Neutron::Net",
199             "properties": {"name": network_name}
200         }
201
202     def add_subnet(self, name, cidr):
203         """add to the template a Neutron Subnet"""
204         network_name = name + "-net"
205         subnet_name = name + "-subnet"
206         self.heat_date["resources"][subnet_name] = {
207             "type": "OS::Neutron::Subnet",
208             "depends_on": network_name,
209             "properties": {
210                 "name": subnet_name,
211                 "cidr": cidr,
212                 "network_id": {"get_resource": network_name}
213             }
214         }
215
216         self.heat_date["outputs"][subnet_name] = {
217             "description": "subnet %s ID" % subnet_name,
218             "value": {"get_resource": subnet_name}
219         }
220
221     def add_router(self, name, ext_gw_net):
222         """add to the template a Neutron Router and interface"""
223         router_name = name + "-route"
224         subnet_name = name + "-subnet"
225
226         self.heat_date["resources"][router_name] = {
227             "type": "OS::Neutron::Router",
228             "depends_on": [subnet_name],
229             "properties": {
230                 "name": router_name,
231                 "external_gateway_info": {
232                     "network": ext_gw_net
233                 }
234             }
235         }
236
237     def add_router_interface(self, name):
238         """add to the template a Neutron RouterInterface and interface"""
239         router_name = name + "-route"
240         subnet_name = name + "-subnet"
241         router_if_name = name + "-interface"
242
243         self.heat_date["resources"][router_if_name] = {
244             "type": "OS::Neutron::RouterInterface",
245             "depends_on": [router_name, subnet_name],
246             "properties": {
247                 "router_id": {"get_resource": router_name},
248                 "subnet_id": {"get_resource": subnet_name}
249             }
250         }
251
252     def add_server(self, name, image, flavor, user, ports=None):
253         """add to the template a Nova Server"""
254
255         key_name = "bottlenecks-poscakey"
256         port_name = name + "-port"
257         self.heat_date["resources"][name] = {
258             "type": "OS::Nova::Server",
259             "properties": {
260                 "name": name,
261                 "flavor": flavor,
262                 "image": image,
263                 "key_name": {"get_resource": key_name},
264                 "admin_user": user,
265                 "networks": [{
266                     "port": {"get_resource": port_name}
267                 }]
268             }
269         }
270
271         self.heat_date["outputs"][name] = {
272             "description": "VM UUID",
273             "value": {"get_resource": name}
274         }
275
276     def add_port(self, name, stack_name=None):
277         """add to the template a named Neutron Port"""
278         network_name = stack_name + "-net"
279         subnet_name = stack_name + "-subnet"
280         port_name = name + "-port"
281         security_name = stack_name + "-security_group"
282
283         self.heat_date["resources"][port_name] = {
284             "type": "OS::Neutron::Port",
285             "depends_on": [subnet_name],
286             "properties": {
287                 "name": port_name,
288                 "fixed_ips": [{"subnet": {"get_resource": subnet_name}}],
289                 "network_id": {"get_resource": network_name},
290                 "replacement_policy": "AUTO",
291                 "security_groups": [{"get_resource": security_name}]
292             }
293         }
294
295         self.heat_date["outputs"][port_name] = {
296             "description": "Address for interface %s" % port_name,
297             "value": {"get_attr": [port_name, "fixed_ips", 0, "ip_address"]}
298         }
299
300     def add_floating_ip(self, name, stack_name, network_ext):
301         """add to the template a Nova FloatingIP resource
302         see: https://bugs.launchpad.net/heat/+bug/1299259
303         """
304         port_name = name + "-port"
305         floating_ip_name = name + "-floating"
306         router_if_name = stack_name + "-interface"
307
308         self.heat_date["resources"][floating_ip_name] = {
309             "depends_on": [router_if_name, port_name],
310             "type": "OS::Nova::FloatingIP",
311             "properties": {
312                 "pool": network_ext,
313             }
314         }
315         self.heat_date['outputs'][floating_ip_name] = {
316             'description': 'floating ip %s' % name,
317             'value': {'get_attr': [name, 'ip']}
318         }
319
320     def add_floating_ip_ass(self, name):
321         """add to the template a Nova FloatingIP resource
322         see: https://bugs.launchpad.net/heat/+bug/1299259
323         """
324         port_name = name + "-port"
325         floating_ip_name = name + "-floating"
326         floating_ass = name + "-floating_ass"
327
328         self.heat_date["resources"][floating_ass] = {
329             "type": 'OS::Neutron::FloatingIPAssociation',
330             "depends_on": [port_name, floating_ip_name],
331             "properties": {
332                 "floatingip_id": {'get_resource': floating_ip_name},
333                 "port_id": {"get_resource": port_name}
334             }
335         }
336
337     def get_template_date(self):
338         return self.heat_date