From 3db30feebbde2c9e74f27a656931fa0d6bcb6920 Mon Sep 17 00:00:00 2001 From: Edward MacGillivray Date: Fri, 13 Oct 2017 14:01:39 -0700 Subject: Relocate iniparser to yardstick.network_services.helpers Change-Id: I1f457c9c24f2ca84dde61b64f58edaff8952670a Signed-off-by: Edward MacGillivray --- yardstick/network_services/helpers/iniparser.py | 249 +++++++++++++++++++++ .../network_services/vnf_generic/vnf/iniparser.py | 249 --------------------- .../vnf_generic/vnf/prox_helpers.py | 11 +- 3 files changed, 254 insertions(+), 255 deletions(-) create mode 100644 yardstick/network_services/helpers/iniparser.py delete mode 100644 yardstick/network_services/vnf_generic/vnf/iniparser.py (limited to 'yardstick') diff --git a/yardstick/network_services/helpers/iniparser.py b/yardstick/network_services/helpers/iniparser.py new file mode 100644 index 000000000..98256e08a --- /dev/null +++ b/yardstick/network_services/helpers/iniparser.py @@ -0,0 +1,249 @@ +# Copyright 2012 OpenStack Foundation +# +# 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. + + +class ParseError(Exception): + + def __init__(self, message, line_no, line): + self.msg = message + self.line = line + self.line_no = line_no + + def __str__(self): + return 'at line %d, %s: %r' % (self.line_no, self.msg, self.line) + + +class SectionParseError(ParseError): + + pass + + +class LineParser(object): + + PARSE_EXC = ParseError + + @staticmethod + def strip_key_value(key, value): + key = key.strip() + value = value.strip() + if value and value[0] == value[-1] and value.startswith(('"', "'")): + value = value[1:-1] + return key, [value] + + def __init__(self, line, line_no): + super(LineParser, self).__init__() + self.line = line + self.line_no = line_no + self.continuation = line != line.lstrip() + semi_active, _, semi_comment = line.partition(';') + pound_active, _, pound_comment = line.partition('#') + if not semi_comment and not pound_comment: + self.active = line.strip() + self.comment = '' + elif len(semi_comment) > len(pound_comment): + self.active = semi_active.strip() + self.comment = semi_comment.strip() + else: + self.active = pound_active.strip() + self.comment = pound_comment.strip() + self._section_name = None + + def __repr__(self): + template = "line %d: active '%s' comment '%s'\n%s" + return template % (self.line_no, self.active, self.comment, self.line) + + @property + def section_name(self): + if self._section_name is None: + if not self.active.startswith('['): + raise self.error_no_section_start_bracket() + if not self.active.endswith(']'): + raise self.error_no_section_end_bracket() + self._section_name = '' + if self.active: + self._section_name = self.active[1:-1] + if not self._section_name: + raise self.error_no_section_name() + return self._section_name + + def is_active_line(self): + return bool(self.active) + + def is_continuation(self): + return self.continuation + + def split_key_value(self): + for sep in ['=', ':']: + words = self.active.split(sep, 1) + try: + return self.strip_key_value(*words) + except TypeError: + pass + + return self.active.rstrip(), '@' + + def error_invalid_assignment(self): + return self.PARSE_EXC("No ':' or '=' found in assignment", self.line_no, self.line) + + def error_empty_key(self): + return self.PARSE_EXC('Key cannot be empty', self.line_no, self.line) + + def error_unexpected_continuation(self): + return self.PARSE_EXC('Unexpected continuation line', self.line_no, self.line) + + def error_no_section_start_bracket(self): + return SectionParseError('Invalid section (must start with [)', self.line_no, self.line) + + def error_no_section_end_bracket(self): + return self.PARSE_EXC('Invalid section (must end with ])', self.line_no, self.line) + + def error_no_section_name(self): + return self.PARSE_EXC('Empty section name', self.line_no, self.line) + + +class BaseParser(object): + + def parse(self, data=None): + if data is not None: + return self._parse(data.splitlines()) + + def _next_key_value(self, line_parser, key, value): + self.comment(line_parser) + + if not line_parser.is_active_line(): + # Blank line, ends multi-line values + if key: + key, value = self.assignment(key, value, line_parser) + return key, value + + if line_parser.is_continuation(): + # Continuation of previous assignment + if key is None: + raise line_parser.error_unexpected_continuation() + + value.append(line_parser.active.lstrip()) + return key, value + + if key: + # Flush previous assignment, if any + key, value = self.assignment(key, value, line_parser) + + try: + # Section start + self.new_section(line_parser) + except SectionParseError: + pass + else: + return key, value + + key, value = line_parser.split_key_value() + if not key: + raise line_parser.error_empty_key() + return key, value + + def _parse(self, line_iter): + key = None + value = [] + + parse_iter = (LineParser(line, line_no) for line_no, line in enumerate(line_iter)) + for line_parser in parse_iter: + key, value = self._next_key_value(line_parser, key, value) + + if key: + # Flush previous assignment, if any + self.assignment(key, value, LineParser('EOF', -1)) + + def _assignment(self, key, value, line_parser): + """Called when a full assignment is parsed.""" + raise NotImplementedError() + + def assignment(self, key, value, line_parser): + self._assignment(key, value, line_parser) + return None, [] + + def new_section(self, line_parser): + """Called when a new section is started.""" + raise NotImplementedError() + + def comment(self, line_parser): + """Called when a comment is parsed.""" + raise NotImplementedError() + + +class ConfigParser(BaseParser): + """Parses a single config file, populating 'sections' to look like: + + [ + [ + 'section1', + [ + ['key1', 'value1\nvalue2'], + ['key2', 'value3\nvalue4'], + ], + ], + [ + 'section2', + [ + ['key3', 'value5\nvalue6'], + ], + ], + ] + """ + + def __init__(self, filename, sections=None): + super(ConfigParser, self).__init__() + self.filename = filename + if sections is not None: + self.sections = sections + else: + self.sections = [] + self.section_name = None + self.section = None + + def parse(self, data=None): + if not data: + data = self.filename + with open(data) as f: + return self._parse(f) + + def __iter__(self): + return iter(self.sections) + + def find_section_index(self, section_name): + return next((i for i, (name, value) in enumerate(self) if name == section_name), -1) + + def find_section(self, section_name): + return next((value for name, value in self.sections if name == section_name), None) + + def new_section(self, line_parser): + section_name = line_parser.section_name + index = self.find_section_index(section_name) + self.section_name = section_name + if index == -1: + self.section = [section_name, []] + self.sections.append(self.section) + else: + self.section = self.sections[index] + + def _assignment(self, key, value, line_parser): + if not self.section_name: + raise line_parser.error_no_section_name() + + value = '\n'.join(value) + entry = [key, value] + self.section[1].append(entry) + + def comment(self, line_parser): + """Called when a comment is parsed.""" + pass diff --git a/yardstick/network_services/vnf_generic/vnf/iniparser.py b/yardstick/network_services/vnf_generic/vnf/iniparser.py deleted file mode 100644 index 98256e08a..000000000 --- a/yardstick/network_services/vnf_generic/vnf/iniparser.py +++ /dev/null @@ -1,249 +0,0 @@ -# Copyright 2012 OpenStack Foundation -# -# 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. - - -class ParseError(Exception): - - def __init__(self, message, line_no, line): - self.msg = message - self.line = line - self.line_no = line_no - - def __str__(self): - return 'at line %d, %s: %r' % (self.line_no, self.msg, self.line) - - -class SectionParseError(ParseError): - - pass - - -class LineParser(object): - - PARSE_EXC = ParseError - - @staticmethod - def strip_key_value(key, value): - key = key.strip() - value = value.strip() - if value and value[0] == value[-1] and value.startswith(('"', "'")): - value = value[1:-1] - return key, [value] - - def __init__(self, line, line_no): - super(LineParser, self).__init__() - self.line = line - self.line_no = line_no - self.continuation = line != line.lstrip() - semi_active, _, semi_comment = line.partition(';') - pound_active, _, pound_comment = line.partition('#') - if not semi_comment and not pound_comment: - self.active = line.strip() - self.comment = '' - elif len(semi_comment) > len(pound_comment): - self.active = semi_active.strip() - self.comment = semi_comment.strip() - else: - self.active = pound_active.strip() - self.comment = pound_comment.strip() - self._section_name = None - - def __repr__(self): - template = "line %d: active '%s' comment '%s'\n%s" - return template % (self.line_no, self.active, self.comment, self.line) - - @property - def section_name(self): - if self._section_name is None: - if not self.active.startswith('['): - raise self.error_no_section_start_bracket() - if not self.active.endswith(']'): - raise self.error_no_section_end_bracket() - self._section_name = '' - if self.active: - self._section_name = self.active[1:-1] - if not self._section_name: - raise self.error_no_section_name() - return self._section_name - - def is_active_line(self): - return bool(self.active) - - def is_continuation(self): - return self.continuation - - def split_key_value(self): - for sep in ['=', ':']: - words = self.active.split(sep, 1) - try: - return self.strip_key_value(*words) - except TypeError: - pass - - return self.active.rstrip(), '@' - - def error_invalid_assignment(self): - return self.PARSE_EXC("No ':' or '=' found in assignment", self.line_no, self.line) - - def error_empty_key(self): - return self.PARSE_EXC('Key cannot be empty', self.line_no, self.line) - - def error_unexpected_continuation(self): - return self.PARSE_EXC('Unexpected continuation line', self.line_no, self.line) - - def error_no_section_start_bracket(self): - return SectionParseError('Invalid section (must start with [)', self.line_no, self.line) - - def error_no_section_end_bracket(self): - return self.PARSE_EXC('Invalid section (must end with ])', self.line_no, self.line) - - def error_no_section_name(self): - return self.PARSE_EXC('Empty section name', self.line_no, self.line) - - -class BaseParser(object): - - def parse(self, data=None): - if data is not None: - return self._parse(data.splitlines()) - - def _next_key_value(self, line_parser, key, value): - self.comment(line_parser) - - if not line_parser.is_active_line(): - # Blank line, ends multi-line values - if key: - key, value = self.assignment(key, value, line_parser) - return key, value - - if line_parser.is_continuation(): - # Continuation of previous assignment - if key is None: - raise line_parser.error_unexpected_continuation() - - value.append(line_parser.active.lstrip()) - return key, value - - if key: - # Flush previous assignment, if any - key, value = self.assignment(key, value, line_parser) - - try: - # Section start - self.new_section(line_parser) - except SectionParseError: - pass - else: - return key, value - - key, value = line_parser.split_key_value() - if not key: - raise line_parser.error_empty_key() - return key, value - - def _parse(self, line_iter): - key = None - value = [] - - parse_iter = (LineParser(line, line_no) for line_no, line in enumerate(line_iter)) - for line_parser in parse_iter: - key, value = self._next_key_value(line_parser, key, value) - - if key: - # Flush previous assignment, if any - self.assignment(key, value, LineParser('EOF', -1)) - - def _assignment(self, key, value, line_parser): - """Called when a full assignment is parsed.""" - raise NotImplementedError() - - def assignment(self, key, value, line_parser): - self._assignment(key, value, line_parser) - return None, [] - - def new_section(self, line_parser): - """Called when a new section is started.""" - raise NotImplementedError() - - def comment(self, line_parser): - """Called when a comment is parsed.""" - raise NotImplementedError() - - -class ConfigParser(BaseParser): - """Parses a single config file, populating 'sections' to look like: - - [ - [ - 'section1', - [ - ['key1', 'value1\nvalue2'], - ['key2', 'value3\nvalue4'], - ], - ], - [ - 'section2', - [ - ['key3', 'value5\nvalue6'], - ], - ], - ] - """ - - def __init__(self, filename, sections=None): - super(ConfigParser, self).__init__() - self.filename = filename - if sections is not None: - self.sections = sections - else: - self.sections = [] - self.section_name = None - self.section = None - - def parse(self, data=None): - if not data: - data = self.filename - with open(data) as f: - return self._parse(f) - - def __iter__(self): - return iter(self.sections) - - def find_section_index(self, section_name): - return next((i for i, (name, value) in enumerate(self) if name == section_name), -1) - - def find_section(self, section_name): - return next((value for name, value in self.sections if name == section_name), None) - - def new_section(self, line_parser): - section_name = line_parser.section_name - index = self.find_section_index(section_name) - self.section_name = section_name - if index == -1: - self.section = [section_name, []] - self.sections.append(self.section) - else: - self.section = self.sections[index] - - def _assignment(self, key, value, line_parser): - if not self.section_name: - raise line_parser.error_no_section_name() - - value = '\n'.join(value) - entry = [key, value] - self.section[1].append(entry) - - def comment(self, line_parser): - """Called when a comment is parsed.""" - pass diff --git a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py index 992b6d06e..ac5abfbcb 100644 --- a/yardstick/network_services/vnf_generic/vnf/prox_helpers.py +++ b/yardstick/network_services/vnf_generic/vnf/prox_helpers.py @@ -14,28 +14,27 @@ from __future__ import absolute_import import array -import operator -import logging import io +import logging +import operator import os import re import select import socket - -from collections import OrderedDict, namedtuple import time +from collections import OrderedDict, namedtuple from contextlib import contextmanager from itertools import repeat, chain from multiprocessing import Queue import six -from six.moves import zip, StringIO from six.moves import cStringIO +from six.moves import zip, StringIO from yardstick.benchmark.scenarios.networking.vnf_generic import find_relative_file from yardstick.common import utils from yardstick.common.utils import SocketTopology, join_non_strings, try_int -from yardstick.network_services.vnf_generic.vnf.iniparser import ConfigParser +from yardstick.network_services.helpers.iniparser import ConfigParser from yardstick.network_services.vnf_generic.vnf.sample_vnf import ClientResourceHelper from yardstick.network_services.vnf_generic.vnf.sample_vnf import DpdkVnfSetupEnvHelper -- cgit 1.2.3-korg