config: suites_dir and scenarios_dir are now a list of paths
This allows inheriting suites or scenarios from eg. sysmocom/ dir, while still allowing to apply new suites and scenarios on top. Change-Id: Icecdae32d400a6b6da2ebf167c1c795f7a74ae96
This commit is contained in:
parent
3a0dea682e
commit
66ef9457cb
|
@ -1,6 +1,6 @@
|
|||
state_dir: '/var/tmp/osmo-gsm-tester/state'
|
||||
suites_dir: './suites'
|
||||
scenarios_dir: './scenarios'
|
||||
suites_dir: ['./suites']
|
||||
scenarios_dir: ['./scenarios']
|
||||
default_suites_conf_path: './default-suites.conf'
|
||||
defaults_conf_path: './defaults.conf'
|
||||
resource_conf_path: './resources.conf'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
state_dir: '/var/tmp/osmo-gsm-tester/state'
|
||||
suites_dir: './suites'
|
||||
scenarios_dir: './scenarios'
|
||||
suites_dir: ['./suites']
|
||||
scenarios_dir: ['./scenarios']
|
||||
default_suites_conf_path: './default-suites.conf'
|
||||
defaults_conf_path: './defaults.conf'
|
||||
resource_conf_path: './resources.conf'
|
||||
|
|
|
@ -26,13 +26,19 @@ then overrides the above locations.
|
|||
{app-name} expects to find the following configuration settings in 'main.conf':
|
||||
|
||||
- 'state_dir': Path to <<state_dir,state_dir>> directory
|
||||
- 'suites_dir': Path to <<suites_dir,suites_dir>> directory
|
||||
- 'trial_dir': Path to <<trials,trial>> directory to test against (overridden by cmdline argument)
|
||||
- 'scenarios_dir': Path to <<scenarios_dir,scenarios_dir>> directory (optional)
|
||||
- 'suites_dir': List of paths to <<suites_dir,suites_dir>> directories.
|
||||
- 'scenarios_dir': List of paths to <<scenarios_dir,scenarios_dir>> directories (optional)
|
||||
- 'default_suites_conf_path': Path to <<default_suites_conf,default-suites.conf>> file (optional)
|
||||
- 'defaults_conf_path': Path to <<defaults_conf,defaults.conf>> file (optional)
|
||||
- 'resource_conf_path': Path to <<resource_conf,resources.conf>> file (optional)
|
||||
|
||||
Configuration settings holding a list of paths, such as 'suites_dir' or
|
||||
'scenarios_dir', are used to look up for paths in regular list of order, meaning
|
||||
first paths in list take preference over last ones. As a result, if a suite
|
||||
named 'A' is found in several paths, the one on the first path in the list will
|
||||
be used.
|
||||
|
||||
These are described in detail in the following sections. If no value is provided
|
||||
for a given setting, sane default paths are used: For 'state_dir',
|
||||
'/var/tmp/osmo-gsm-tester/state/' is used. All other files and directories are
|
||||
|
@ -45,8 +51,8 @@ of the {app-name} process parsing it.
|
|||
.Sample main.conf file:
|
||||
----
|
||||
state_dir: '/var/tmp/osmo-gsm-tester/state'
|
||||
suites_dir: '/usr/local/src/osmo-gsm-tester/suites'
|
||||
scenarios_dir: './scenarios'
|
||||
suites_dir: [ '/usr/local/src/osmo-gsm-tester/suites' ]
|
||||
scenarios_dir: [ './scenarios' ]
|
||||
trial_dir: './trial'
|
||||
default_suites_conf_path: './default-suites.conf'
|
||||
defaults_conf_path: './defaults.conf'
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
state_dir: ./test_work/state_dir
|
||||
suites_dir: ./suite_test
|
||||
suites_dir: ['./suite_test']
|
||||
|
|
|
@ -14,9 +14,9 @@ cnf -: DBG: MAIN CONFIG:
|
|||
{'default_suites_conf_path': '[PATH]/selftest/resource_test/conf/default-suites.conf',
|
||||
'defaults_conf_path': '[PATH]/selftest/resource_test/conf/defaults.conf',
|
||||
'resource_conf_path': '[PATH]/selftest/resource_test/conf/resources.conf',
|
||||
'scenarios_dir': '[PATH]/selftest/resource_test/conf/scenarios',
|
||||
'scenarios_dir': ['[PATH]/selftest/resource_test/conf/scenarios'],
|
||||
'state_dir': '[PATH]/selftest/resource_test/conf/test_work/state_dir',
|
||||
'suites_dir': '[PATH]/selftest/resource_test/conf/suite_test',
|
||||
'suites_dir': ['[PATH]/selftest/resource_test/conf/suite_test'],
|
||||
'trial_dir': '[PATH]/selftest/resource_test/conf/trial'}
|
||||
*** all resources:
|
||||
{'arfcn': [{'_hash': 'e620569450f8259b3f0212ec19c285dd07df063c',
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
state_dir: ./test_work/state_dir
|
||||
suites_dir: .
|
||||
scenarios_dir: .
|
||||
suites_dir: ['.']
|
||||
scenarios_dir: ['.']
|
||||
|
|
|
@ -3,9 +3,9 @@ cnf -: DBG: MAIN CONFIG:
|
|||
{'default_suites_conf_path': '[PATH]/selftest/scenario_test/default-suites.conf',
|
||||
'defaults_conf_path': '[PATH]/selftest/scenario_test/defaults.conf',
|
||||
'resource_conf_path': '[PATH]/selftest/scenario_test/resources.conf',
|
||||
'scenarios_dir': '[PATH]/selftest/scenario_test',
|
||||
'scenarios_dir': ['[PATH]/selftest/scenario_test'],
|
||||
'state_dir': '[PATH]/selftest/scenario_test/test_work/state_dir',
|
||||
'suites_dir': '[PATH]/selftest/scenario_test',
|
||||
'suites_dir': ['[PATH]/selftest/scenario_test'],
|
||||
'trial_dir': '[PATH]/selftest/scenario_test/trial'}
|
||||
scenario_case_01.conf
|
||||
{'anotherlist': ['4', '0'],
|
||||
|
@ -19,11 +19,11 @@ scenario_case_01.conf
|
|||
'somelist': [{'somelistitem': 'firststring'},
|
||||
{'somelistitem': 'secondstring'},
|
||||
{'somelistitem': 'thirdstring'}]}
|
||||
OK: expected RuntimeError: No such scenario file: '[PATH]/selftest/scenario_test/scenario_case_01@.conf' (nor scenario_case_01@.conf)
|
||||
OK: expected RuntimeError: No such scenario file 'scenario_case_01@.conf' (nor scenario_case_01@.conf) in [[PATH]/selftest/scenario_test]
|
||||
OK: expected ValueError
|
||||
OK: expected ValueError
|
||||
OK: expected RuntimeError: No such scenario file: '[PATH]/selftest/scenario_test/scenario_case_03.conf'
|
||||
OK: expected RuntimeError: No such scenario file: '[PATH]/selftest/scenario_test/scenario_case_03.conf'
|
||||
OK: expected RuntimeError: No such scenario file scenario_case_03.conf in [[PATH]/selftest/scenario_test]
|
||||
OK: expected RuntimeError: No such scenario file scenario_case_03.conf in [[PATH]/selftest/scenario_test]
|
||||
tst scenario_case_03@heyho,1,yes.conf: DBG: {param_dict={param1='heyho', param2='1', param3='yes'}}
|
||||
scenario_case_03@heyho,1,yes.conf
|
||||
{'anotherlist': ['1', '0'],
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
state_dir: ./test_work/state_dir
|
||||
suites_dir: .
|
||||
suites_dir: ['suitedirA', 'suitedirB']
|
||||
|
|
|
@ -4,14 +4,15 @@ cnf -: DBG: MAIN CONFIG:
|
|||
{'default_suites_conf_path': '[PATH]/selftest/suite_test/default-suites.conf',
|
||||
'defaults_conf_path': '[PATH]/selftest/suite_test/defaults.conf',
|
||||
'resource_conf_path': '[PATH]/selftest/suite_test/resources.conf',
|
||||
'scenarios_dir': '[PATH]/selftest/suite_test/scenarios',
|
||||
'scenarios_dir': ['[PATH]/selftest/suite_test/scenarios'],
|
||||
'state_dir': '[PATH]/selftest/suite_test/test_work/state_dir',
|
||||
'suites_dir': '[PATH]/selftest/suite_test',
|
||||
'suites_dir': ['[PATH]/selftest/suite_test/suitedirA',
|
||||
'[PATH]/selftest/suite_test/suitedirB'],
|
||||
'trial_dir': '[PATH]/selftest/suite_test/trial'}
|
||||
--- -: ERR: RuntimeError: Suite not found: 'does_not_exist' in [PATH]/selftest/suite_test
|
||||
--- -: ERR: RuntimeError: Suite not found: 'does_not_exist' in [[PATH]/selftest/suite_test/suitedirA, [PATH]/selftest/suite_test/suitedirB]
|
||||
- no suite.conf
|
||||
cnf empty_dir: DBG: reading suite.conf
|
||||
cnf [PATH]/selftest/suite_test/empty_dir/suite.conf: ERR: FileNotFoundError: [Errno 2] No such file or directory: '[PATH]/selftest/suite_test/empty_dir/suite.conf' [empty_dir↪[PATH]/selftest/suite_test/empty_dir/suite.conf]
|
||||
cnf [PATH]/selftest/suite_test/suitedirA/empty_dir/suite.conf: ERR: FileNotFoundError: [Errno 2] No such file or directory: '[PATH]/selftest/suite_test/suitedirA/empty_dir/suite.conf' [empty_dir↪[PATH]/selftest/suite_test/suitedirA/empty_dir/suite.conf]
|
||||
- valid suite dir
|
||||
cnf test_suite: DBG: reading suite.conf
|
||||
defaults:
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
resources:
|
||||
|
||||
defaults:
|
||||
timeout: 60s
|
|
@ -0,0 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
from osmo_gsm_tester.testenv import *
|
||||
|
||||
print('I am %r / %r' % (tenv.suite().name(), test.name()))
|
||||
|
|
@ -71,8 +71,8 @@ CFG_DEFAULTS_CONF = 'defaults_conf_path'
|
|||
CFG_RESOURCES_CONF = 'resource_conf_path'
|
||||
MAIN_CONFIG_SCHEMA = {
|
||||
CFG_STATE_DIR: schema.STR,
|
||||
CFG_SUITES_DIR: schema.STR,
|
||||
CFG_SCENARIOS_DIR: schema.STR,
|
||||
CFG_SUITES_DIR + '[]': schema.STR,
|
||||
CFG_SCENARIOS_DIR + '[]': schema.STR,
|
||||
CFG_TRIAL_DIR: schema.STR,
|
||||
CFG_DEFAULT_SUITES_CONF: schema.STR,
|
||||
CFG_DEFAULTS_CONF: schema.STR,
|
||||
|
@ -80,8 +80,8 @@ MAIN_CONFIG_SCHEMA = {
|
|||
}
|
||||
|
||||
DF_CFG_STATE_DIR = '/var/tmp/osmo-gsm-tester/state/'
|
||||
DF_CFG_SUITES_DIR = './suites'
|
||||
DF_CFG_SCENARIOS_DIR = './scenarios'
|
||||
DF_CFG_SUITES_DIR = ['./suites']
|
||||
DF_CFG_SCENARIOS_DIR = ['./scenarios']
|
||||
DF_CFG_TRIAL_DIR = './trial'
|
||||
DF_CFG_DEFAULT_SUITES_CONF = './default-suites.conf'
|
||||
DF_CFG_DEFAULTS_CONF = './defaults.conf'
|
||||
|
@ -122,11 +122,16 @@ def _get_main_config_path():
|
|||
MAIN_CONFIG_PATH = _find_main_config_path()
|
||||
return MAIN_CONFIG_PATH
|
||||
|
||||
def main_config_path_to_abspath(path):
|
||||
def main_config_path_to_abspath(val):
|
||||
'Relative files in main config are relative towards the config file, not towards $CWD'
|
||||
if not path.startswith(os.pathsep):
|
||||
return os.path.realpath(os.path.join(os.path.dirname(_get_main_config_path()), path))
|
||||
return path
|
||||
# If val is a list of paths, recurse to translate its paths.
|
||||
if isinstance(val, list):
|
||||
for i in range(len(val)):
|
||||
val[i] = main_config_path_to_abspath(val[i])
|
||||
return val
|
||||
if not val.startswith(os.pathsep):
|
||||
return os.path.realpath(os.path.join(os.path.dirname(_get_main_config_path()), val))
|
||||
return val
|
||||
|
||||
def _get_main_config():
|
||||
global MAIN_CONFIG
|
||||
|
@ -169,11 +174,11 @@ def read_config_file(cfg_name, validation_schema=None, if_missing_return=False):
|
|||
def get_state_dir():
|
||||
return Dir(get_main_config_value(CFG_STATE_DIR))
|
||||
|
||||
def get_suites_dir():
|
||||
return Dir(get_main_config_value(CFG_SUITES_DIR))
|
||||
def get_suites_dirs():
|
||||
return [Dir(d) for d in get_main_config_value(CFG_SUITES_DIR)]
|
||||
|
||||
def get_scenarios_dir():
|
||||
return Dir(get_main_config_value(CFG_SCENARIOS_DIR))
|
||||
def get_scenarios_dirs():
|
||||
return [Dir(d) for d in get_main_config_value(CFG_SCENARIOS_DIR)]
|
||||
|
||||
DEFAULTS_CONF = None
|
||||
def get_defaults(for_kind):
|
||||
|
|
|
@ -88,25 +88,41 @@ class Scenario(log.Origin, dict):
|
|||
self.update(conf)
|
||||
|
||||
def get_scenario(name, validation_schema=None):
|
||||
scenarios_dir = config.get_scenarios_dir()
|
||||
found = False
|
||||
path = None
|
||||
param_list = []
|
||||
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)
|
||||
scenarios_dirs = config.get_scenarios_dirs()
|
||||
for d in scenarios_dirs:
|
||||
path = d.child(name)
|
||||
if os.path.isfile(path):
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
raise RuntimeError('No such scenario file %s in %r' % (name, scenarios_dirs))
|
||||
sc = Scenario(name, path)
|
||||
else: # parametrized scenario:
|
||||
# Allow first matching complete matching names (eg: scenario@param1,param2.conf),
|
||||
# this allows setting specific content in different files for specific values.
|
||||
if not os.path.isfile(path):
|
||||
scenarios_dirs = config.get_scenarios_dirs()
|
||||
for d in scenarios_dirs:
|
||||
path = d.child(name)
|
||||
if os.path.isfile(path):
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
# get "scenario@.conf" from "scenario@param1,param2.conf":
|
||||
for d in scenarios_dirs:
|
||||
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))
|
||||
path = d.child(prefix_name)
|
||||
if os.path.isfile(path):
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
raise RuntimeError('No such scenario file %r (nor %s) in %r' % (name, prefix_name, scenarios_dirs))
|
||||
# At this point, we have existing file path. Let's now scrap the parameter(s):
|
||||
# get param1,param2 str from scenario@param1,param2.conf
|
||||
param_list_str = name.split('@', 1)[1][:-len('.conf')]
|
||||
|
|
|
@ -232,12 +232,16 @@ def load(suite_name):
|
|||
if suite is not None:
|
||||
return suite
|
||||
|
||||
suites_dir = config.get_suites_dir()
|
||||
suite_dir = suites_dir.child(suite_name)
|
||||
if not suites_dir.exists(suite_name):
|
||||
raise RuntimeError('Suite not found: %r in %r' % (suite_name, suites_dir))
|
||||
if not suites_dir.isdir(suite_name):
|
||||
raise RuntimeError('Suite name found, but not a directory: %r' % (suite_dir))
|
||||
suites_dirs = config.get_suites_dirs()
|
||||
suite_dir = None
|
||||
found = False
|
||||
for d in suites_dirs:
|
||||
suite_dir = d.child(suite_name)
|
||||
if d.exists(suite_name) and d.isdir(suite_name):
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
raise RuntimeError('Suite not found: %r in %r' % (suite_name, suites_dirs))
|
||||
|
||||
suite_def = SuiteDefinition(suite_dir)
|
||||
loaded_suite_definitions[suite_name] = suite_def
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
state_dir: '/var/tmp/osmo-gsm-tester/state'
|
||||
suites_dir: './suites'
|
||||
scenarios_dir: './scenarios'
|
||||
suites_dir: ['./suites']
|
||||
scenarios_dir: ['./scenarios']
|
||||
default_suites_conf_path: './default-suites.conf'
|
||||
defaults_conf_path: './defaults.conf'
|
||||
resource_conf_path: './resources.conf'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
state_dir: '/var/tmp/osmo-gsm-tester/state'
|
||||
suites_dir: './suites'
|
||||
scenarios_dir: './scenarios'
|
||||
suites_dir: ['./suites']
|
||||
scenarios_dir: ['./scenarios']
|
||||
default_suites_conf_path: './default-suites.conf'
|
||||
defaults_conf_path: '../defaults.conf'
|
||||
resource_conf_path: './resources.conf'
|
||||
|
|
Loading…
Reference in New Issue