Fix small things for integration of ApexLake with Yardstick
[yardstick.git] / yardstick / vTC / apexlake / experimental_framework / benchmarks / instantiation_validation_benchmark.py
1 # Copyright (c) 2015 Intel Research and Development Ireland Ltd.
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 import os
16 import commands
17 import signal
18 import time
19 from experimental_framework.benchmarks import benchmark_base_class as base
20 from experimental_framework.constants import framework_parameters as fp
21 from experimental_framework.constants import conf_file_sections as cfs
22 from experimental_framework.packet_generators import dpdk_packet_generator \
23     as dpdk
24 import experimental_framework.common as common
25
26
27 THROUGHPUT = 'throughput'
28 VLAN_SENDER = 'vlan_sender'
29 VLAN_RECEIVER = 'vlan_receiver'
30 PACKETS_FILE_NAME = 'packets.res'
31 PACKET_CHECKER_PROGRAM_NAME = 'test_sniff'
32 MULTICAST_GROUP = '224.192.16.1'
33
34
35 class InstantiationValidationBenchmark(base.BenchmarkBaseClass):
36
37     def __init__(self, name, params):
38         base.BenchmarkBaseClass.__init__(self, name, params)
39         self.base_dir = "{}{}{}".format(
40             common.get_base_dir(), fp.EXPERIMENTAL_FRAMEWORK_DIR,
41             fp.DPDK_PKTGEN_DIR)
42         self.results_file = self.base_dir + PACKETS_FILE_NAME
43         self.lua_file = self.base_dir + 'constant_traffic.lua'
44         self.res_dir = ''
45         self.interface_name = ''
46
47         # Set the packet checker command
48         self.pkt_checker_command = common.get_base_dir()
49         self.pkt_checker_command += 'experimental_framework/libraries/'
50         self.pkt_checker_command += 'packet_checker/'
51         self.pkt_checker_command += PACKET_CHECKER_PROGRAM_NAME + ' '
52
53     def init(self):
54         """
55         Initialize the benchmark
56         :return: None
57         """
58         pass
59
60     def finalize(self):
61         """
62         Finalizes the benchmark
63         :return: None
64         """
65         pass
66
67     def get_features(self):
68         features = dict()
69         features['description'] = 'Instantiation Validation Benchmark'
70         features['parameters'] = [THROUGHPUT, VLAN_SENDER, VLAN_RECEIVER]
71         features['allowed_values'] = dict()
72         features['allowed_values'][THROUGHPUT] = map(str, range(0, 100))
73         features['allowed_values'][VLAN_SENDER] = map(str, range(-1, 4096))
74         features['allowed_values'][VLAN_RECEIVER] = map(str, range(-1, 4096))
75         features['default_values'] = dict()
76         features['default_values'][THROUGHPUT] = '1'
77         features['default_values'][VLAN_SENDER] = '-1'
78         features['default_values'][VLAN_RECEIVER] = '-1'
79         return features
80
81     def run(self):
82         # Setup packet generator
83         traffic_time = '10'
84         packet_size = '512'
85         traffic_rate_percentage = self.params[THROUGHPUT]
86
87         dpdk_pktgen_vars = common.get_dpdk_pktgen_vars()
88         # bus_address = dpdk_pktgen_vars[cfs.CFSP_DPDK_BUS_SLOT_NIC_2]
89         self.interface_name = dpdk_pktgen_vars[cfs.CFSP_DPDK_NAME_IF_2]
90         packetgen = dpdk.DpdkPacketGenerator()
91         self._configure_lua_file(traffic_rate_percentage, traffic_time)
92         packetgen.init_dpdk_pktgen(dpdk_interfaces=1,
93                                    pcap_file_0='packet_' + packet_size +
94                                                '.pcap',
95                                    pcap_file_1='igmp.pcap',
96                                    lua_script='constant_traffic.lua',
97                                    vlan_0=self.params[VLAN_SENDER],
98                                    vlan_1=self.params[VLAN_RECEIVER])
99
100         self._init_packet_checker()
101         # Send constant traffic at a specified rate
102         common.LOG.debug('Start the packet generator')
103         packetgen.send_traffic()
104         common.LOG.debug('Stop the packet generator')
105         time.sleep(5)
106         self._finalize_packet_checker()
107         self._reset_lua_file(traffic_rate_percentage, traffic_time)
108         return self._get_results()
109
110     def _configure_lua_file(self, traffic_rate_percentage, traffic_time):
111         """
112         Configure the packet gen to write the results into the right file
113         :return: None
114         """
115         common.replace_in_file(self.lua_file, 'local out_file = ""',
116                                'local out_file = "' +
117                                self.results_file + '"')
118         common.replace_in_file(self.lua_file, 'local traffic_rate = 0',
119                                'local traffic_rate = ' +
120                                traffic_rate_percentage)
121         common.replace_in_file(self.lua_file, 'local traffic_delay = 0',
122                                'local traffic_delay = ' + traffic_time)
123
124     def _reset_lua_file(self, traffic_rate_percentage, traffic_time):
125         """
126         Configure the packet gen to write the results into the right file
127         :param traffic_rate_percentage:
128         :param traffic_time:
129         :return: None
130         """
131
132         common.replace_in_file(self.lua_file, 'local out_file = "' +
133                                self.results_file + '"',
134                                'local out_file = ""')
135         common.replace_in_file(self.lua_file, 'local traffic_rate = ' +
136                                traffic_rate_percentage,
137                                'local traffic_rate = 0')
138         common.replace_in_file(self.lua_file, 'local traffic_delay = ' +
139                                traffic_time, 'local traffic_delay = 0')
140
141     def _get_results(self):
142         ret_val = dict()
143         packet_checker_res = 0
144         if self.res_dir:
145             packet_checker_res = \
146                 int(common.get_file_first_line(self.res_dir +
147                                                'packet_checker.res'))
148         pkt_gen_res = int(common.get_file_first_line(self.results_file))
149         if pkt_gen_res <= packet_checker_res or \
150            (float(pkt_gen_res - packet_checker_res) / pkt_gen_res) <= 0.1:
151             ret_val['failure'] = '0'
152         else:
153             ret_val['failure'] = '1'
154         return ret_val
155
156     def _init_packet_checker(self):
157         """
158         Sets up the multicast and starts the packet checker
159         :return:
160         """
161         # Kill any other process running from previous failed execution
162         self.res_dir = common.get_result_dir()
163         pids = self._get_pids()
164         for pid in pids:
165             os.kill(pid, signal.SIGTERM)
166
167         # initialization of the VLAN interface
168         command = "ip link add link "
169         command += self.interface_name
170         command += " name "
171         command += self.interface_name + '.' + self.params[VLAN_RECEIVER]
172         command += " type vlan id " + self.params[VLAN_RECEIVER]
173         common.run_command(command)
174
175         # set up the new
176         command = 'ifconfig ' + self.interface_name + '.' + \
177                   self.params[VLAN_RECEIVER]
178         # An IP address is required for the interface to receive a multicast
179         # flow. The specific address is not important
180         command += ' 10.254.254.254 up'
181         common.run_command(command)
182
183         # configure smcroute
184         command = "echo 'mgroup from "
185         command += self.interface_name + '.' + self.params[VLAN_RECEIVER]
186         command += " group "
187         command += MULTICAST_GROUP
188         command += "' > /etc/smcroute.conf"
189         common.run_command(command)
190
191         # run smcroute on the interface
192         command = 'smcroute -d'
193         common.run_command(command)
194
195         # Start the packet checker
196         # TODO: Compile "make" the packet sniffer
197         command = "chmod +x {}".format(self.pkt_checker_command)
198         common.run_command(command)
199         command = self.pkt_checker_command
200         command += self.interface_name + '.' + self.params[VLAN_RECEIVER]
201         command += ' 128'
202         command += ' &'
203         common.run_command(command)
204
205     def _finalize_packet_checker(self):
206         """
207         Obtains the PID of the packet checker and sends an alarm to
208         terminate it
209         :return: None
210         """
211         pids = self._get_pids()
212         for pid in pids:
213             os.kill(pid, signal.SIGTERM)
214
215         # stop smcroute on the interface
216         command = 'smcroute -k'
217         common.run_command(command)
218
219         # finalization of the VLAN interface
220         command = "ip link delete "
221         command += self.interface_name + '.' + self.params[VLAN_RECEIVER]
222         common.run_command(command)
223
224     def _get_pids(self):
225         """
226         Returns a list of integers containing the pid or the pids of the
227         processes currently running on the host
228         :return: type: list of int
229         """
230         output = commands.getoutput("ps -ef |pgrep " +
231                                     PACKET_CHECKER_PROGRAM_NAME)
232         if not output:
233             pids = []
234         else:
235             pids = map(int, output.split('\n'))
236         return pids