diff options
author | treyad <treyad@viosoft.com> | 2018-10-24 22:02:42 -0700 |
---|---|---|
committer | treyad <treyad@viosoft.com> | 2019-04-05 03:02:13 -0700 |
commit | 9b043a1529a52c5269f6a67f951a5df1b12f2786 (patch) | |
tree | ff4e8895d5ea75bb08f97d4d7cfae3695539c517 /yardstick/network_services | |
parent | 62c06a9435fe0f42eeb1fde5e86fb273941e39c8 (diff) |
Add sipp trafficgen based SampleVNFTrafficGen
This patch defines:
- Generic VNF APIs to test Network service:
--> instantiate: prepare the arguments for run sipp
--> run_traffic: run sipp test and handle the result file
--> collect_kpi: collect results and push to queue
--> terminate
JIRA: YARDSTICK-1446
Change-Id: I7f6b7dd253164bb5c359ac866cb8cae81f504d65
Signed-off-by: treyad <treyad@viosoft.com>
Diffstat (limited to 'yardstick/network_services')
3 files changed, 176 insertions, 0 deletions
diff --git a/yardstick/network_services/traffic_profile/__init__.py b/yardstick/network_services/traffic_profile/__init__.py index c5d8eff0b..85b3d54a0 100644 --- a/yardstick/network_services/traffic_profile/__init__.py +++ b/yardstick/network_services/traffic_profile/__init__.py @@ -31,6 +31,7 @@ def register_modules(): 'yardstick.network_services.traffic_profile.pktgen', 'yardstick.network_services.traffic_profile.landslide_profile', 'yardstick.network_services.traffic_profile.vpp_rfc2544', + 'yardstick.network_services.traffic_profile.sip', ] for module in modules: diff --git a/yardstick/network_services/traffic_profile/sip.py b/yardstick/network_services/traffic_profile/sip.py new file mode 100644 index 000000000..d18574090 --- /dev/null +++ b/yardstick/network_services/traffic_profile/sip.py @@ -0,0 +1,32 @@ +# Copyright (c) 2019 Viosoft Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from yardstick.network_services.traffic_profile import base + + +class SipProfile(base.TrafficProfile): + """ Sipp Traffic profile """ + + def __init__(self, yaml_data): + super(SipProfile, self).__init__(yaml_data) + self.generator = None + + def execute_traffic(self, traffic_generator=None): + if traffic_generator is not None and self.generator is None: + self.generator = traffic_generator + + def is_ended(self): + if self.generator is not None: + return self.generator.is_ended() + return False diff --git a/yardstick/network_services/vnf_generic/vnf/tg_imsbench_sipp.py b/yardstick/network_services/vnf_generic/vnf/tg_imsbench_sipp.py new file mode 100644 index 000000000..70557b848 --- /dev/null +++ b/yardstick/network_services/vnf_generic/vnf/tg_imsbench_sipp.py @@ -0,0 +1,143 @@ +# Copyright (c) 2019 Viosoft Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import logging +from collections import deque + +from yardstick.network_services.vnf_generic.vnf import sample_vnf + +LOG = logging.getLogger(__name__) + + +class SippSetupEnvHelper(sample_vnf.SetupEnvHelper): + APP_NAME = "ImsbenchSipp" + + +class SippResourceHelper(sample_vnf.ClientResourceHelper): + pass + + +class SippVnf(sample_vnf.SampleVNFTrafficGen): + """ + This class calls the test script from TG machine, then gets the result file + from IMS machine. After that, the result file is handled line by line, and + is updated to database. + """ + + APP_NAME = "ImsbenchSipp" + APP_WORD = "ImsbenchSipp" + VNF_TYPE = "ImsbenchSipp" + HW_OFFLOADING_NFVI_TYPES = {'baremetal', 'sriov'} + RESULT = "/tmp/final_result.dat" + SIPP_RESULT = "/tmp/sipp_dat_files/final_result.dat" + LOCAL_PATH = "/tmp" + CMD = "./SIPp_benchmark.bash {} {} {} '{}'" + + def __init__(self, name, vnfd, setup_env_helper_type=None, + resource_helper_type=None): + if resource_helper_type is None: + resource_helper_type = SippResourceHelper + if setup_env_helper_type is None: + setup_env_helper_type = SippSetupEnvHelper + super(SippVnf, self).__init__( + name, vnfd, setup_env_helper_type, resource_helper_type) + self.params = "" + self.pcscf_ip = self.vnfd_helper.interfaces[0]["virtual-interface"]\ + ["peer_intf"]["local_ip"] + self.sipp_ip = self.vnfd_helper.interfaces[0]["virtual-interface"]\ + ["local_ip"] + self.media_ip = self.vnfd_helper.interfaces[1]["virtual-interface"]\ + ["local_ip"] + self.queue = "" + self.count = 0 + + def instantiate(self, scenario_cfg, context_cfg): + super(SippVnf, self).instantiate(scenario_cfg, context_cfg) + scenario_cfg = {} + _params = [("port", 5060), ("start_user", 1), ("end_user", 10000), + ("init_reg_cps", 50), ("init_reg_max", 5000), ("reg_cps", 50), + ("reg_step", 10), ("rereg_cps", 10), ("rereg_step", 5), + ("dereg_cps", 10), ("dereg_step", 5), ("msgc_cps", 10), + ("msgc_step", 2), ("run_mode", "rtp"), ("call_cps", 10), + ("hold_time", 15), ("call_step", 5)] + + self.params = ';'.join([str(scenario_cfg.get("options", {}).get(k, v)) + for k, v in dict(_params).items()]) + + def wait_for_instantiate(self): + pass + + def get_result_files(self): + self.ssh_helper.get(self.SIPP_RESULT, self.LOCAL_PATH, True) + + # Example of result file: + # cat /tmp/final_result.dat + # timestamp:1000 reg:100 reg_saps:0 + # timestamp:2000 reg:100 reg_saps:50 + # timestamp:3000 reg:100 reg_saps:50 + # timestamp:4000 reg:100 reg_saps:50 + # ... + # reg_Requested_prereg:50 + # reg_Effective_prereg:49.49 + # reg_DOC:0 + # ... + @staticmethod + def handle_result_files(filename): + with open(filename, 'r') as f: + content = f.readlines() + result = [{k: round(float(v), 2) for k, v in [i.split(":", 1) for i in x.split()]} + for x in content if x] + return deque(result) + + def run_traffic(self, traffic_profile): + traffic_profile.execute_traffic(self) + cmd = self.CMD.format(self.sipp_ip, self.media_ip, + self.pcscf_ip, self.params) + self.ssh_helper.execute(cmd, None, 3600, False) + self.get_result_files() + self.queue = self.handle_result_files(self.RESULT) + + def collect_kpi(self): + result = {} + try: + result = self.queue.popleft() + except IndexError: + pass + return result + + @staticmethod + def count_line_num(fname): + try: + with open(fname, 'r') as f: + return sum(1 for line in f) + except IOError: + return 0 + + def is_ended(self): + """ + The test will end when the results are pushed into database. + It does not depend on the "duration" value, so this value will be set + enough big to make sure that the test will end before duration. + """ + num_lines = self.count_line_num(self.RESULT) + if self.count == num_lines: + LOG.debug('TG IS ENDED.....................') + self.count = 0 + return True + self.count += 1 + return False + + def terminate(self): + LOG.debug('TERMINATE:.....................') + self.resource_helper.terminate() |