Change in osmo-gsm-tester[master]: Split Scenario class to its own file

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.org
Mon May 11 13:16:40 UTC 2020


pespin 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>


More information about the gerrit-log mailing list