Merge "Fix IxLoad traffic generator issue around running the traffic."
[yardstick.git] / yardstick / network_services / vnf_generic / vnf / tg_ixload.py
1 #  Copyright (c) 2016-2017 Intel Corporation
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain 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,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 from __future__ import absolute_import
16 import csv
17 import glob
18 import logging
19 import os
20 import shutil
21
22 from collections import OrderedDict
23 from subprocess import call
24
25 import six
26
27 from yardstick.common.utils import makedirs
28 from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen
29 from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
30
31 LOG = logging.getLogger(__name__)
32
33 VNF_PATH = os.path.dirname(os.path.realpath(__file__))
34
35 MOUNT_CMD = """\
36 mount.cifs //{0[ip]}/Results {1.RESULTS_MOUNT} \
37 -o username={0[user]},password={0[password]}\
38 """
39
40 IXLOAD_CONFIG_TEMPLATE = '''\
41 {
42     "ixia_chassis": "%s",
43     "IXIA": {
44         "ports": %s,
45         "card": %s
46     },
47     "remote_server": "%s",
48     "result_dir": "%s",
49     "ixload_cfg": "C:/Results/%s"
50 }'''
51
52 IXLOAD_CMD = "{ixloadpy} {http_ixload} {args}"
53
54
55 class ResourceDataHelper(list):
56
57     def get_aggregates(self):
58         return {
59             "min": min(self),
60             "max": max(self),
61             "avg": sum(self) / len(self),
62         }
63
64
65 class IxLoadResourceHelper(ClientResourceHelper):
66
67     RESULTS_MOUNT = "/mnt/Results"
68
69     KPI_LIST = OrderedDict((
70         ('http_throughput', 'HTTP Total Throughput (Kbps)'),
71         ('simulated_users', 'HTTP Simulated Users'),
72         ('concurrent_connections', 'HTTP Concurrent Connections'),
73         ('connection_rate', 'HTTP Connection Rate'),
74         ('transaction_rate', 'HTTP Transaction Rate'),
75     ))
76
77     def __init__(self, setup_helper):
78         super(IxLoadResourceHelper, self).__init__(setup_helper)
79         self.result = OrderedDict((key, ResourceDataHelper()) for key in self.KPI_LIST)
80         self.resource_file_name = ''
81
82     def parse_csv_read(self, reader):
83         for row in reader:
84             try:
85                 new_data = {key_left: int(row[key_right])
86                             for key_left, key_right in self.KPI_LIST.items()}
87             except (TypeError, ValueError):
88                 continue
89             else:
90                 for key, value in new_data.items():
91                     self.result[key].append(value)
92
93     def setup(self):
94         # TODO: fixupt scenario_helper to hanlde ixia
95         self.resource_file_name = str(self.scenario_helper.scenario_cfg['ixia_profile'])
96         makedirs(self.RESULTS_MOUNT)
97         cmd = MOUNT_CMD.format(self.vnfd_helper.mgmt_interface, self)
98         LOG.debug(cmd)
99
100         if not os.path.ismount(self.RESULTS_MOUNT):
101             call(cmd, shell=True)
102
103         shutil.rmtree(self.RESULTS_MOUNT, ignore_errors=True)
104         makedirs(self.RESULTS_MOUNT)
105         shutil.copy(self.resource_file_name, self.RESULTS_MOUNT)
106
107     def make_aggregates(self):
108         return {key_right: self.result[key_left].get_aggregates()
109                 for key_left, key_right in self.KPI_LIST.items()}
110
111     def log(self):
112         for key in self.KPI_LIST:
113             LOG.debug(self.result[key])
114
115
116 class IxLoadTrafficGen(SampleVNFTrafficGen):
117
118     def __init__(self, name, vnfd, setup_env_helper_type=None, resource_helper_type=None):
119         if resource_helper_type is None:
120             resource_helper_type = IxLoadResourceHelper
121
122         super(IxLoadTrafficGen, self).__init__(name, vnfd, setup_env_helper_type,
123                                                resource_helper_type)
124         self._result = {}
125         self.data = None
126
127     def run_traffic(self, traffic_profile):
128         ports = []
129         card = None
130         for interface in self.vnfd_helper.interfaces:
131             vpci_list = interface['virtual-interface']["vpci"].split(":")
132             card = vpci_list[0]
133             ports.append(str(vpci_list[1]))
134
135         for csv_file in glob.iglob(self.ssh_helper.join_bin_path('*.csv')):
136             os.unlink(csv_file)
137
138         ixia_config = self.vnfd_helper.mgmt_interface["tg-config"]
139         ixload_config = IXLOAD_CONFIG_TEMPLATE % (
140             ixia_config["ixchassis"], ports, card,
141             self.vnfd_helper.mgmt_interface["ip"], self.ssh_helper.bin_path,
142             os.path.basename(self.resource_helper.resource_file_name))
143
144         http_ixload_path = os.path.join(VNF_PATH, "../../traffic_profile")
145
146         cmd = IXLOAD_CMD.format(
147             ixloadpy=os.path.join(ixia_config["py_bin_path"], "ixloadpython"),
148             http_ixload=os.path.join(http_ixload_path, "http_ixload.py"),
149             args="'%s'" % ixload_config)
150
151         LOG.debug(cmd)
152         call(cmd, shell=True)
153
154         with open(self.ssh_helper.join_bin_path("ixLoad_HTTP_Client.csv")) as csv_file:
155             lines = csv_file.readlines()[10:]
156
157         with open(self.ssh_helper.join_bin_path("http_result.csv"), 'wb+') as result_file:
158             result_file.writelines(six.text_type(lines[:-1]))
159             result_file.flush()
160             result_file.seek(0)
161             reader = csv.DictReader(result_file)
162             self.resource_helper.parse_csv_read(reader)
163
164         self.resource_helper.log()
165         self.data = self.resource_helper.make_aggregates()
166
167     def listen_traffic(self, traffic_profile):
168         pass
169
170     def instantiate(self, scenario_cfg, context_cfg):
171         super(IxLoadTrafficGen, self).instantiate(scenario_cfg, context_cfg)
172
173     def wait_for_instantiate(self):
174         # not needed for Ixload
175         pass
176
177     def terminate(self):
178         call(["pkill", "-9", "http_ixload.py"])
179         super(IxLoadTrafficGen, self).terminate()