Merge "utils: create TASK_LOG_DIR if it doesn't exist"
[yardstick.git] / yardstick / network_services / vnf_generic / vnf / tg_trex.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 """ Trex acts as traffic generation and vnf definitions based on IETS Spec """
15
16 from __future__ import absolute_import
17 from __future__ import print_function
18
19 import logging
20 import os
21
22 import yaml
23
24 from yardstick.common.utils import mac_address_to_hex_list
25 from yardstick.network_services.utils import get_nsb_option
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 LOG = logging.getLogger(__name__)
30
31
32 class TrexResourceHelper(ClientResourceHelper):
33
34     CONF_FILE = '/tmp/trex_cfg.yaml'
35     QUEUE_WAIT_TIME = 1
36     RESOURCE_WORD = 'trex'
37     RUN_DURATION = 0
38
39     SYNC_PORT = 4500
40     ASYNC_PORT = 4501
41
42     def generate_cfg(self):
43         ext_intf = self.vnfd_helper.interfaces
44         vpci_list = []
45         port_list = []
46         trex_cfg = {
47             'port_limit': 0,
48             'version': '2',
49             'interfaces': vpci_list,
50             'port_info': port_list,
51             "port_limit": len(ext_intf),
52             "version": '2',
53         }
54         cfg_file = [trex_cfg]
55
56         for interface in ext_intf:
57             virtual_interface = interface['virtual-interface']
58             vpci_list.append(virtual_interface["vpci"])
59             dst_mac = virtual_interface["dst_mac"]
60
61             if not dst_mac:
62                 continue
63
64             local_mac = virtual_interface["local_mac"]
65             port_list.append({
66                 "src_mac": mac_address_to_hex_list(local_mac),
67                 "dest_mac": mac_address_to_hex_list(dst_mac),
68             })
69
70         cfg_str = yaml.safe_dump(cfg_file, default_flow_style=False, explicit_start=True)
71         self.ssh_helper.upload_config_file(os.path.basename(self.CONF_FILE), cfg_str)
72         self._vpci_ascending = sorted(vpci_list)
73
74     def check_status(self):
75         status, _, _ = self.ssh_helper.execute("sudo lsof -i:%s" % self.SYNC_PORT)
76         return status
77
78     # temp disable
79     DISABLE_DEPLOY = True
80
81     def setup(self):
82         if self.DISABLE_DEPLOY:
83             return
84
85         trex_path = self.ssh_helper.join_bin_path('trex')
86
87         err = self.ssh_helper.execute("which {}".format(trex_path))[0]
88         if err == 0:
89             return
90
91         LOG.info("Copying %s to destination...", self.RESOURCE_WORD)
92         self.ssh_helper.run("sudo mkdir -p '{}'".format(os.path.dirname(trex_path)))
93         self.ssh_helper.put("~/.bash_profile", "~/.bash_profile")
94         self.ssh_helper.put(trex_path, trex_path, True)
95         ko_src = os.path.join(trex_path, "scripts/ko/src/")
96         self.ssh_helper.execute(self.MAKE_INSTALL.format(ko_src))
97
98     def start(self, ports=None, *args, **kwargs):
99         cmd = "sudo fuser -n tcp {0.SYNC_PORT} {0.ASYNC_PORT} -k > /dev/null 2>&1"
100         self.ssh_helper.execute(cmd.format(self))
101
102         self.ssh_helper.execute("sudo pkill -9 rex > /dev/null 2>&1")
103
104         trex_path = self.ssh_helper.join_bin_path("trex", "scripts")
105         path = get_nsb_option("trex_path", trex_path)
106
107         # cmd = "sudo ./t-rex-64 -i --cfg %s > /dev/null 2>&1" % self.CONF_FILE
108         cmd = "./t-rex-64 -i --cfg '{}'".format(self.CONF_FILE)
109
110         # if there are errors we want to see them
111         # we have to sudo cd because the path might be owned by root
112         trex_cmd = """sudo bash -c "cd '{}' ; {}" >/dev/null""".format(path, cmd)
113         self.ssh_helper.execute(trex_cmd)
114
115     def terminate(self):
116         super(TrexResourceHelper, self).terminate()
117         cmd = "sudo fuser -n tcp %s %s -k > /dev/null 2>&1"
118         self.ssh_helper.execute(cmd % (self.SYNC_PORT, self.ASYNC_PORT))
119
120
121 class TrexTrafficGen(SampleVNFTrafficGen):
122     """
123     This class handles mapping traffic profile and generating
124     traffic for given testcase
125     """
126
127     APP_NAME = 'TRex'
128
129     def __init__(self, name, vnfd, setup_env_helper_type=None, resource_helper_type=None):
130         if resource_helper_type is None:
131             resource_helper_type = TrexResourceHelper
132
133         super(TrexTrafficGen, self).__init__(name, vnfd, setup_env_helper_type,
134                                              resource_helper_type)
135
136     def _check_status(self):
137         return self.resource_helper.check_status()
138
139     def _start_server(self):
140         super(TrexTrafficGen, self)._start_server()
141         self.resource_helper.start()
142
143     def scale(self, flavor=""):
144         pass
145
146     def listen_traffic(self, traffic_profile):
147         pass
148
149     def terminate(self):
150         self.resource_helper.terminate()