X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=resources%2Ftools%2Fwrk%2Fwrk_traffic_profile_parser.py;h=f5534657055a1b49afee05aec5bd8db270b2c1bf;hb=HEAD;hp=e1f8365345754bd1f551714e36a95f47011e7ce8;hpb=a95c54b7821596402e0aa7136cd7d1de71a5b187;p=csit.git diff --git a/resources/tools/wrk/wrk_traffic_profile_parser.py b/resources/tools/wrk/wrk_traffic_profile_parser.py deleted file mode 100644 index e1f8365345..0000000000 --- a/resources/tools/wrk/wrk_traffic_profile_parser.py +++ /dev/null @@ -1,286 +0,0 @@ -# Copyright (c) 2018 Cisco and / or its affiliates. -# 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. - -"""wrk traffic profile parser. - -See LLD for the structure of a wrk traffic profile. -""" - - -from os.path import isfile -from pprint import pformat - -from yaml import load, YAMLError -from robot.api import logger - -from resources.tools.wrk.wrk_errors import WrkError - - -class WrkTrafficProfile(object): - """The wrk traffic profile. - """ - - MANDATORY_PARAMS = ("urls", - "first-cpu", - "cpus", - "duration", - "nr-of-threads", - "nr-of-connections") - - def __init__(self, profile_name): - """Read the traffic profile from the yaml file. - - :param profile_name: Path to the yaml file with the profile. - :type profile_name: str - :raises: WrkError if it is not possible to parse the profile. - """ - - self._profile_name = None - self._traffic_profile = None - - self.profile_name = profile_name - - try: - with open(self.profile_name, 'r') as profile_file: - self.traffic_profile = load(profile_file) - except IOError as err: - raise WrkError(msg="An error occurred while opening the file '{0}'." - .format(self.profile_name), - details=str(err)) - except YAMLError as err: - raise WrkError(msg="An error occurred while parsing the traffic " - "profile '{0}'.".format(self.profile_name), - details=str(err)) - - self._validate_traffic_profile() - - if self.traffic_profile: - logger.debug("\nThe wrk traffic profile '{0}' is valid.\n". - format(self.profile_name)) - logger.debug("wrk traffic profile '{0}':".format(self.profile_name)) - logger.debug(pformat(self.traffic_profile)) - else: - logger.debug("\nThe wrk traffic profile '{0}' is invalid.\n". - format(self.profile_name)) - raise WrkError("\nThe wrk traffic profile '{0}' is invalid.\n". - format(self.profile_name)) - - def __repr__(self): - return pformat(self.traffic_profile) - - def __str__(self): - return pformat(self.traffic_profile) - - def _validate_traffic_profile(self): - """Validate the traffic profile. - - The specification, the structure and the rules are described in - doc/wrk_lld.rst - """ - - logger.debug("\nValidating the wrk traffic profile '{0}'...\n". - format(self.profile_name)) - - # Level 1: Check if the profile is a dictionary: - if not isinstance(self.traffic_profile, dict): - logger.error("The wrk traffic profile must be a dictionary.") - self.traffic_profile = None - return - - # Level 2: Check if all mandatory parameters are present: - is_valid = True - for param in self.MANDATORY_PARAMS: - if self.traffic_profile.get(param, None) is None: - logger.error("The parameter '{0}' in mandatory.".format(param)) - is_valid = False - if not is_valid: - self.traffic_profile = None - return - - # Level 3: Mandatory params: Check if urls is a list: - is_valid = True - if not isinstance(self.traffic_profile["urls"], list): - logger.error("The parameter 'urls' must be a list.") - is_valid = False - - # Level 3: Mandatory params: Check if cpus is a valid integer: - try: - cpus = int(self.traffic_profile["cpus"]) - if cpus < 1: - raise ValueError - self.traffic_profile["cpus"] = cpus - except ValueError: - logger.error("The parameter 'cpus' must be an integer greater than " - "1.") - is_valid = False - - # Level 3: Mandatory params: Check if first-cpu is a valid integer: - try: - first_cpu = int(self.traffic_profile["first-cpu"]) - if first_cpu < 0: - raise ValueError - self.traffic_profile["first-cpu"] = first_cpu - except ValueError: - logger.error("The parameter 'first-cpu' must be an integer greater " - "than 1.") - is_valid = False - - # Level 3: Mandatory params: Check if duration is a valid integer: - try: - duration = int(self.traffic_profile["duration"]) - if duration < 1: - raise ValueError - self.traffic_profile["duration"] = duration - except ValueError: - logger.error("The parameter 'duration' must be an integer " - "greater than 1.") - is_valid = False - - # Level 3: Mandatory params: Check if nr-of-threads is a valid integer: - try: - nr_of_threads = int(self.traffic_profile["nr-of-threads"]) - if nr_of_threads < 1: - raise ValueError - self.traffic_profile["nr-of-threads"] = nr_of_threads - except ValueError: - logger.error("The parameter 'nr-of-threads' must be an integer " - "greater than 1.") - is_valid = False - - # Level 3: Mandatory params: Check if nr-of-connections is a valid - # integer: - try: - nr_of_connections = int(self.traffic_profile["nr-of-connections"]) - if nr_of_connections < 1: - raise ValueError - self.traffic_profile["nr-of-connections"] = nr_of_connections - except ValueError: - logger.error("The parameter 'nr-of-connections' must be an integer " - "greater than 1.") - is_valid = False - - # Level 4: Optional params: Check if script is present: - script = self.traffic_profile.get("script", None) - if script is not None: - if not isinstance(script, str): - logger.error("The path to LuaJIT script in invalid") - is_valid = False - else: - if not isfile(script): - logger.error("The file '{0}' in not present.". - format(script)) - is_valid = False - else: - self.traffic_profile["script"] = None - logger.debug("The optional parameter 'LuaJIT script' is not " - "defined. No problem.") - - # Level 4: Optional params: Check if header is present: - header = self.traffic_profile.get("header", None) - if header: - if not (isinstance(header, dict) or isinstance(header, str)): - logger.error("The parameter 'header' is not valid.") - is_valid = False - else: - if isinstance(header, dict): - header_lst = list() - for key, val in header.items(): - header_lst.append("{0}: {1}".format(key, val)) - if header_lst: - self.traffic_profile["header"] = ", ".join(header_lst) - else: - logger.error("The parameter 'header' is defined but " - "empty.") - is_valid = False - else: - self.traffic_profile["header"] = None - logger.debug("The optional parameter 'header' is not defined. " - "No problem.") - - # Level 4: Optional params: Check if latency is present: - latency = self.traffic_profile.get("latency", None) - if latency is not None: - try: - latency = bool(latency) - self.traffic_profile["latency"] = latency - except ValueError: - logger.error("The parameter 'latency' must be boolean.") - is_valid = False - else: - self.traffic_profile["latency"] = False - logger.debug("The optional parameter 'latency' is not defined. " - "No problem.") - - # Level 4: Optional params: Check if timeout is present: - timeout = self.traffic_profile.get("timeout", None) - if timeout: - try: - timeout = int(timeout) - if timeout < 1: - raise ValueError - self.traffic_profile["timeout"] = timeout - except ValueError: - logger.error("The parameter 'timeout' must be integer greater " - "than 1.") - is_valid = False - else: - self.traffic_profile["timeout"] = None - logger.debug("The optional parameter 'timeout' is not defined. " - "No problem.") - - if not is_valid: - self.traffic_profile = None - return - - # Level 5: Check dependencies between parameters: - # Level 5: Check urls and cpus: - if self.traffic_profile["cpus"] % len(self.traffic_profile["urls"]): - logger.error("The number of CPUs must be a multiplication of the " - "number of URLs.") - self.traffic_profile = None - - @property - def profile_name(self): - """Getter - Profile name. - - :returns: The traffic profile file path - :rtype: str - """ - return self._profile_name - - @profile_name.setter - def profile_name(self, profile_name): - """ - - :param profile_name: - :type profile_name: str - """ - self._profile_name = profile_name - - @property - def traffic_profile(self): - """Getter: Traffic profile. - - :returns: The traffic profile. - :rtype: dict - """ - return self._traffic_profile - - @traffic_profile.setter - def traffic_profile(self, profile): - """Setter - Traffic profile. - - :param profile: The new traffic profile. - :type profile: dict - """ - self._traffic_profile = profile