This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
pespin gerrit-no-reply at lists.osmocom.orgpespin has uploaded this change for review. ( https://gerrit.osmocom.org/c/osmo-gsm-tester/+/18200 ) Change subject: Split Scenario class to its own file ...................................................................... Split Scenario class to its own file Change-Id: Ia029de7ecda4c8dc3d0b4c412e4c9c0a65cf0185 --- M selftest/suite_test/suite_test.py M src/osmo_gsm_tester/core/config.py A src/osmo_gsm_tester/core/scenario.py M src/osmo_gsm_tester/core/suite.py 4 files changed, 148 insertions(+), 112 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-gsm-tester refs/changes/00/18200/1 diff --git a/selftest/suite_test/suite_test.py b/selftest/suite_test/suite_test.py index fc5f9df..a096027 100755 --- a/selftest/suite_test/suite_test.py +++ b/selftest/suite_test/suite_test.py @@ -3,7 +3,11 @@ import sys import _prep import shutil -from osmo_gsm_tester.core import log, config, util, report +from osmo_gsm_tester.core import log +from osmo_gsm_tester.core import config +from osmo_gsm_tester.core import util +from osmo_gsm_tester.core import report +from osmo_gsm_tester.core import scenario from osmo_gsm_tester.core import suite from osmo_gsm_tester.core.schema import generate_schemas, get_all_schema @@ -66,26 +70,26 @@ print('- test with half empty scenario') trial = FakeTrial() -scenario = config.Scenario('foo', 'bar') -scenario['resources'] = { 'bts': [{'type': 'osmo-bts-trx'}] } -s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) +sc = scenario.Scenario('foo', 'bar') +sc['resources'] = { 'bts': [{'type': 'osmo-bts-trx'}] } +s = suite.SuiteRun(trial, 'test_suite', s_def, [sc]) results = s.run_tests('hello_world.py') print(report.suite_to_text(s)) print('- test with scenario') trial = FakeTrial() -scenario = config.Scenario('foo', 'bar') -scenario['resources'] = { 'bts': [{ 'times': '2', 'type': 'osmo-bts-trx', 'trx_list': [{'nominal_power': '10'}, {'nominal_power': '12'}]}, {'type': 'sysmo'}] } -s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) +sc = scenario.Scenario('foo', 'bar') +sc['resources'] = { 'bts': [{ 'times': '2', 'type': 'osmo-bts-trx', 'trx_list': [{'nominal_power': '10'}, {'nominal_power': '12'}]}, {'type': 'sysmo'}] } +s = suite.SuiteRun(trial, 'test_suite', s_def, [sc]) results = s.run_tests('hello_world.py') print(report.suite_to_text(s)) print('- test with scenario and modifiers') trial = FakeTrial() -scenario = config.Scenario('foo', 'bar') -scenario['resources'] = { 'bts': [{ 'times': '2', 'type': 'osmo-bts-trx', 'trx_list': [{'nominal_power': '10'}, {'nominal_power': '12'}]}, {'type': 'sysmo'}] } -scenario['modifiers'] = { 'bts': [{ 'times': '2', 'trx_list': [{'nominal_power': '20'}, {'nominal_power': '20'}]}, {'type': 'sysmo'}] } -s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) +sc = scenario.Scenario('foo', 'bar') +sc['resources'] = { 'bts': [{ 'times': '2', 'type': 'osmo-bts-trx', 'trx_list': [{'nominal_power': '10'}, {'nominal_power': '12'}]}, {'type': 'sysmo'}] } +sc['modifiers'] = { 'bts': [{ 'times': '2', 'trx_list': [{'nominal_power': '20'}, {'nominal_power': '20'}]}, {'type': 'sysmo'}] } +s = suite.SuiteRun(trial, 'test_suite', s_def, [sc]) s.reserve_resources() print(repr(s.reserved_resources)) results = s.run_tests('hello_world.py') @@ -93,9 +97,9 @@ print('- test with suite-specific config') trial = FakeTrial() -scenario = config.Scenario('foo', 'bar') -scenario['config'] = {'suite': {s.name(): { 'some_suite_global_param': 'heyho', 'test_suite_params': {'one_bool_parameter': 'true', 'second_list_parameter': ['23', '45']}}}} -s = suite.SuiteRun(trial, 'test_suite', s_def, [scenario]) +sc = scenario.Scenario('foo', 'bar') +sc['config'] = {'suite': {s.name(): { 'some_suite_global_param': 'heyho', 'test_suite_params': {'one_bool_parameter': 'true', 'second_list_parameter': ['23', '45']}}}} +s = suite.SuiteRun(trial, 'test_suite', s_def, [sc]) s.reserve_resources() print(repr(s.reserved_resources)) results = s.run_tests('test_suite_params.py') diff --git a/src/osmo_gsm_tester/core/config.py b/src/osmo_gsm_tester/core/config.py index 98d422f..88e522d 100644 --- a/src/osmo_gsm_tester/core/config.py +++ b/src/osmo_gsm_tester/core/config.py @@ -165,6 +165,13 @@ with open(path, 'w') as f: f.write(tostr(config)) +def fromstr(config_str, validation_schema=None): + config = yaml.safe_load(config_str) + config = _standardize(config) + if validation_schema is not None: + schema.validate(config, validation_schema) + return config + def tostr(config): return _tostr(_standardize(config)) @@ -188,99 +195,6 @@ defaults = read_config_file(DEFAULTS_CONF, if_missing_return={}) return defaults.get(for_kind, {}) -class Scenario(log.Origin, dict): - def __init__(self, name, path, param_list=[]): - super().__init__(log.C_TST, name) - self.path = path - self.param_list = param_list - - @classmethod - def count_cont_char_backward(cls, str, before_pos, c): - n = 0 - i = before_pos - 1 - while i >= 0: - if str[i] != c: - break - n += 1 - i -= 1 - return n - - @classmethod - def split_scenario_parameters(cls, str): - cur_pos = 0 - param_li = [] - saved = '' - # Split into a list, but we want to escape '\,' to avoid splitting parameters containing commas. - while True: - prev_pos = cur_pos - cur_pos = str.find(',', prev_pos) - if cur_pos == -1: - param_li.append(str[prev_pos:]) - break - if cur_pos == 0: - param_li.append('') - elif cur_pos != 0 and str[cur_pos - 1] == '\\' and cls.count_cont_char_backward(str, cur_pos, '\\') % 2 == 1: - saved += str[prev_pos:cur_pos - 1] + ',' - else: - param_li.append(saved + str[prev_pos:cur_pos]) - saved = '' - cur_pos += 1 - i = 0 - # Also escape '\\' -> '\' - while i < len(param_li): - param_li[i] = param_li[i].replace('\\\\', '\\') - i += 1 - return param_li - - @classmethod - def from_param_list_str(cls, name, path, param_list_str): - param_list = cls.split_scenario_parameters(param_list_str) - return cls(name, path, param_list) - - def read_from_file(self, validation_schema): - with open(self.path, 'r') as f: - config_str = f.read() - if len(self.param_list) != 0: - param_dict = {} - i = 1 - for param in self.param_list: - param_dict['param' + str(i)] = param - i += 1 - self.dbg(param_dict=param_dict) - config_str = template.render_strbuf_inline(config_str, param_dict) - config = yaml.safe_load(config_str) - config = _standardize(config) - if validation_schema: - schema.validate(config, validation_schema) - self.update(config) - -def get_scenario(name, validation_schema=None): - scenarios_dir = get_scenarios_dir() - if not name.endswith('.conf'): - name = name + '.conf' - is_parametrized_file = '@' in name - param_list = [] - path = scenarios_dir.child(name) - if not is_parametrized_file: - if not os.path.isfile(path): - raise RuntimeError('No such scenario file: %r' % path) - sc = Scenario(name, path) - else: # parametrized scenario: - # Allow first matching complete matching names (eg: scenario at param1,param2.conf), - # this allows setting specific content in different files for specific values. - if not os.path.isfile(path): - # get "scenario at .conf" from "scenario at param1,param2.conf": - prefix_name = name[:name.index("@")+1] + '.conf' - path = scenarios_dir.child(prefix_name) - if not os.path.isfile(path): - raise RuntimeError('No such scenario file: %r (nor %s)' % (path, name)) - # At this point, we have existing file path. Let's now scrap the parameter(s): - # get param1,param2 str from scenario at param1,param2.conf - param_list_str = name.split('@', 1)[1][:-len('.conf')] - sc = Scenario.from_param_list_str(name, path, param_list_str) - sc.read_from_file(validation_schema) - return sc - def overlay(dest, src): if is_dict(dest): if not is_dict(src): diff --git a/src/osmo_gsm_tester/core/scenario.py b/src/osmo_gsm_tester/core/scenario.py new file mode 100644 index 0000000..efa045b --- /dev/null +++ b/src/osmo_gsm_tester/core/scenario.py @@ -0,0 +1,117 @@ +# osmo_gsm_tester: Suite scenario +# +# Copyright (C) 2016-2020 by sysmocom - s.f.m.c. GmbH +# +# Author: Neels Hofmeyr <neels at hofmeyr.de> +# Author: Pau Espin Pedrol <pespin at sysmocom.de> +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +import os + +from . import log +from . import template +from . import config + +class Scenario(log.Origin, dict): + def __init__(self, name, path, param_list=[]): + super().__init__(log.C_TST, name) + self.path = path + self.param_list = param_list + + @classmethod + def count_cont_char_backward(cls, str, before_pos, c): + n = 0 + i = before_pos - 1 + while i >= 0: + if str[i] != c: + break + n += 1 + i -= 1 + return n + + @classmethod + def split_scenario_parameters(cls, str): + cur_pos = 0 + param_li = [] + saved = '' + # Split into a list, but we want to escape '\,' to avoid splitting parameters containing commas. + while True: + prev_pos = cur_pos + cur_pos = str.find(',', prev_pos) + if cur_pos == -1: + param_li.append(str[prev_pos:]) + break + if cur_pos == 0: + param_li.append('') + elif cur_pos != 0 and str[cur_pos - 1] == '\\' and cls.count_cont_char_backward(str, cur_pos, '\\') % 2 == 1: + saved += str[prev_pos:cur_pos - 1] + ',' + else: + param_li.append(saved + str[prev_pos:cur_pos]) + saved = '' + cur_pos += 1 + i = 0 + # Also escape '\\' -> '\' + while i < len(param_li): + param_li[i] = param_li[i].replace('\\\\', '\\') + i += 1 + return param_li + + @classmethod + def from_param_list_str(cls, name, path, param_list_str): + param_list = cls.split_scenario_parameters(param_list_str) + return cls(name, path, param_list) + + def read_from_file(self, validation_schema): + with open(self.path, 'r') as f: + config_str = f.read() + if len(self.param_list) != 0: + param_dict = {} + i = 1 + for param in self.param_list: + param_dict['param' + str(i)] = param + i += 1 + self.dbg(param_dict=param_dict) + config_str = template.render_strbuf_inline(config_str, param_dict) + conf = config.fromstr(config_str, validation_schema) + self.update(conf) + +def get_scenario(name, validation_schema=None): + scenarios_dir = config.get_scenarios_dir() + if not name.endswith('.conf'): + name = name + '.conf' + is_parametrized_file = '@' in name + param_list = [] + path = scenarios_dir.child(name) + if not is_parametrized_file: + if not os.path.isfile(path): + raise RuntimeError('No such scenario file: %r' % path) + sc = Scenario(name, path) + else: # parametrized scenario: + # Allow first matching complete matching names (eg: scenario at param1,param2.conf), + # this allows setting specific content in different files for specific values. + if not os.path.isfile(path): + # get "scenario at .conf" from "scenario at param1,param2.conf": + prefix_name = name[:name.index("@")+1] + '.conf' + path = scenarios_dir.child(prefix_name) + if not os.path.isfile(path): + raise RuntimeError('No such scenario file: %r (nor %s)' % (path, name)) + # At this point, we have existing file path. Let's now scrap the parameter(s): + # get param1,param2 str from scenario at param1,param2.conf + param_list_str = name.split('@', 1)[1][:-len('.conf')] + sc = Scenario.from_param_list_str(name, path, param_list_str) + sc.read_from_file(validation_schema) + return sc + +# vim: expandtab tabstop=4 shiftwidth=4 diff --git a/src/osmo_gsm_tester/core/suite.py b/src/osmo_gsm_tester/core/suite.py index 81aab3e..a6eaca2 100644 --- a/src/osmo_gsm_tester/core/suite.py +++ b/src/osmo_gsm_tester/core/suite.py @@ -26,6 +26,7 @@ from . import util from . import schema from . import resource +from . import scenario from . import test class SuiteDefinition(log.Origin): @@ -111,12 +112,12 @@ if replicate_times: combination = config.replicate_times(combination) log.dbg(definition_conf=combination) - for scenario in self.scenarios: - log.ctx(combining_scenarios=conf_name, scenario=scenario.name()) - c = scenario.get(conf_name, {}) + for sc in self.scenarios: + log.ctx(combining_scenarios=conf_name, scenario=sc.name()) + c = sc.get(conf_name, {}) if replicate_times: c = config.replicate_times(c) - log.dbg(scenario=scenario.name(), conf=c) + log.dbg(scenario=sc.name(), conf=c) if c is None: continue schema.combine(combination, c) @@ -258,7 +259,7 @@ def load_suite_scenario_str(suite_scenario_str): suite_name, scenario_names = parse_suite_scenario_str(suite_scenario_str) suite = load(suite_name) - scenarios = [config.get_scenario(scenario_name, schema.get_all_schema()) for scenario_name in scenario_names] + scenarios = [scenario.get_scenario(scenario_name, schema.get_all_schema()) for scenario_name in scenario_names] return (suite_scenario_str, suite, scenarios) # vim: expandtab tabstop=4 shiftwidth=4 -- To view, visit https://gerrit.osmocom.org/c/osmo-gsm-tester/+/18200 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-gsm-tester Gerrit-Branch: master Gerrit-Change-Id: Ia029de7ecda4c8dc3d0b4c412e4c9c0a65cf0185 Gerrit-Change-Number: 18200 Gerrit-PatchSet: 1 Gerrit-Owner: pespin <pespin at sysmocom.de> Gerrit-MessageType: newchange -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20200511/d2b275fa/attachment.htm>