Add send socket commands function
[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 from yardstick.common import utils
26 from yardstick.network_services.vnf_generic.vnf.sample_vnf import SampleVNFTrafficGen
27 from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper
28
29
30 LOG = logging.getLogger(__name__)
31
32 VNF_PATH = os.path.dirname(os.path.realpath(__file__))
33
34 MOUNT_CMD = """\
35 mount.cifs //{0[ip]}/Results {1.RESULTS_MOUNT} \
36 -o username={0[user]},password={0[password]}\
37 """
38
39 IXLOAD_CONFIG_TEMPLATE = '''\
40 {
41     "ixia_chassis": "%s",
42     "IXIA": {
43         "ports": %s,
44         "card": %s
45     },
46     "remote_server": "%s",
47     "result_dir": "%s",
48     "ixload_cfg": "C:/Results/%s"
49 }'''
50
51 IXLOAD_CMD = "{ixloadpy} {http_ixload} {args}"
52
53
54 class ResourceDataHelper(list):
55
56     def get_aggregates(self):
57         return {
58             "min": min(self),
59             "max": max(self),
60             "avg": sum(self) / len(self),
61         }
62
63
64 class IxLoadResourceHelper(ClientResourceHelper):
65
66     RESULTS_MOUNT = "/mnt/Results"
67
68     KPI_LIST = OrderedDict((
69         ('http_throughput', 'HTTP Total Throughput (Kbps)'),
70         ('simulated_users', 'HTTP Simulated Users'),
71         ('concurrent_connections', 'HTTP Concurrent Connections'),
72         ('connection_rate', 'HTTP Connection Rate'),
73         ('transaction_rate', 'HTTP Transaction Rate'),
74     ))
75
76     def __init__(self, setup_helper):
77         super(IxLoadResourceHelper, self).__init__(setup_helper)
78         self.result = OrderedDict((key, ResourceDataHelper()) for key in self.KPI_LIST)
79         self.resource_file_name = ''
80         self.data = None
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         # NOTE: fixup scenario_helper to hanlde ixia
95         self.resource_file_name = \
96             utils.find_relative_file(
97                 self.scenario_helper.scenario_cfg['ixia_profile'],
98                 self.scenario_helper.scenario_cfg["task_path"])
99         utils.makedirs(self.RESULTS_MOUNT)
100         cmd = MOUNT_CMD.format(self.vnfd_helper.mgmt_interface, self)
101         LOG.debug(cmd)
102
103         if not os.path.ismount(self.RESULTS_MOUNT):
104             call(cmd, shell=True)
105
106         shutil.rmtree(self.RESULTS_MOUNT, ignore_errors=True)
107         utils.makedirs(self.RESULTS_MOUNT)
108         shutil.copy(self.resource_file_name, self.RESULTS_MOUNT)
109
110     def make_aggregates(self):
111         return {key_right: self.result[key_left].get_aggregates()
112                 for key_left, key_right in self.KPI_LIST.items()}
113
114     def collect_kpi(self):
115         if self.data:
116             self._result.update(self.data)
117         LOG.info("Collect %s KPIs %s", self.RESOURCE_WORD, self._result)
118         return self._result
119
120     def log(self):
121         for key in self.KPI_LIST:
122             LOG.debug(self.result[key])
123
124
125 class IxLoadTrafficGen(SampleVNFTrafficGen):
126
127     def __init__(self, name, vnfd, setup_env_helper_type=None, resource_helper_type=None):
128         if resource_helper_type is None:
129             resource_helper_type = IxLoadResourceHelper
130
131         super(IxLoadTrafficGen, self).__init__(name, vnfd, setup_env_helper_type,
132                                                resource_helper_type)
133         self._result = {}
134
135     def run_traffic(self, traffic_profile):
136         ports = []
137         card = None
138         for interface in self.vnfd_helper.interfaces:
139             vpci_list = interface['virtual-interface']["vpci"].split(":")
140             card = vpci_list[0]
141             ports.append(str(vpci_list[1]))
142
143         for csv_file in glob.iglob(self.ssh_helper.join_bin_path('*.csv')):
144             os.unlink(csv_file)
145
146         ixia_config = self.vnfd_helper.mgmt_interface["tg-config"]
147         ixload_config = IXLOAD_CONFIG_TEMPLATE % (
148             ixia_config["ixchassis"], ports, card,
149             self.vnfd_helper.mgmt_interface["ip"], self.ssh_helper.bin_path,
150             os.path.basename(self.resource_helper.resource_file_name))
151
152         http_ixload_path = os.path.join(VNF_PATH, "../../traffic_profile")
153
154         cmd = IXLOAD_CMD.format(
155             ixloadpy=os.path.join(ixia_config["py_bin_path"], "ixloadpython"),
156             http_ixload=os.path.join(http_ixload_path, "http_ixload.py"),
157             args="'%s'" % ixload_config)
158
159         LOG.debug(cmd)
160         call(cmd, shell=True)
161
162         with open(self.ssh_helper.join_bin_path("ixLoad_HTTP_Client.csv")) as csv_file:
163             lines = csv_file.readlines()[10:]
164         with open(self.ssh_helper.join_bin_path("http_result.csv"), 'wb+') as result_file:
165             result_file.writelines(lines[:-1])
166             result_file.flush()
167             result_file.seek(0)
168             reader = csv.DictReader(result_file)
169             self.resource_helper.parse_csv_read(reader)
170
171         self.resource_helper.log()
172         self.resource_helper.data = self.resource_helper.make_aggregates()
173
174     def terminate(self):
175         call(["pkill", "-9", "http_ixload.py"])
176         super(IxLoadTrafficGen, self).terminate()