mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-02-07 13:41:24 +00:00
Fixing things up to a point where "list" and "show" commands work.
This commit is contained in:
parent
92aeca8125
commit
dc6d9676f2
2
setup.py
2
setup.py
@ -78,7 +78,7 @@ params = dict(
|
|||||||
'pyYAML', # YAML-formatted agenda parsing
|
'pyYAML', # YAML-formatted agenda parsing
|
||||||
'requests', # Fetch assets over HTTP
|
'requests', # Fetch assets over HTTP
|
||||||
'devlib', # Interacting with devices
|
'devlib', # Interacting with devices
|
||||||
'louie' # Handles signal callbacks
|
'louie' # callbacks dispatch
|
||||||
],
|
],
|
||||||
extras_require={
|
extras_require={
|
||||||
'other': ['jinja2', 'pandas>=0.13.1'],
|
'other': ['jinja2', 'pandas>=0.13.1'],
|
||||||
|
@ -22,9 +22,9 @@ import wlauto
|
|||||||
from wlauto import Command, settings
|
from wlauto import Command, settings
|
||||||
from wlauto.core.execution import Executor
|
from wlauto.core.execution import Executor
|
||||||
from wlauto.utils.log import add_log_file
|
from wlauto.utils.log import add_log_file
|
||||||
from wlauto.core.configuration import RunConfiguration, WAConfiguration
|
from wlauto.core.configuration import RunConfiguration
|
||||||
from wlauto.core import pluginloader
|
from wlauto.core import pluginloader
|
||||||
from wlauto.core.configuration_parsers import Agenda, ConfigFile, EnvrironmentVars, CommandLineArgs
|
from wlauto.core.configuration.parsers import AgendaParser, ConfigParser, CommandLineArgsParser
|
||||||
|
|
||||||
|
|
||||||
class RunCommand(Command):
|
class RunCommand(Command):
|
||||||
@ -74,7 +74,7 @@ class RunCommand(Command):
|
|||||||
|
|
||||||
# STAGE 1: Gather configuratation
|
# STAGE 1: Gather configuratation
|
||||||
|
|
||||||
env = EnvrironmentVars()
|
env = EnvironmentVars()
|
||||||
args = CommandLineArgs(args)
|
args = CommandLineArgs(args)
|
||||||
|
|
||||||
# STAGE 2.1a: Early WAConfiguration, required to find config files
|
# STAGE 2.1a: Early WAConfiguration, required to find config files
|
||||||
|
@ -21,7 +21,7 @@ from wlauto.core.version import get_wa_version
|
|||||||
|
|
||||||
|
|
||||||
def init_argument_parser(parser):
|
def init_argument_parser(parser):
|
||||||
parser.add_argument('-c', '--config', help='specify an additional config.py', action='append')
|
parser.add_argument('-c', '--config', help='specify an additional config.py', action='append', default=[])
|
||||||
parser.add_argument('-v', '--verbose', action='count',
|
parser.add_argument('-v', '--verbose', action='count',
|
||||||
help='The scripts will produce verbose output.')
|
help='The scripts will produce verbose output.')
|
||||||
parser.add_argument('--version', action='version', version='%(prog)s {}'.format(get_wa_version()))
|
parser.add_argument('--version', action='version', version='%(prog)s {}'.format(get_wa_version()))
|
||||||
|
@ -13,7 +13,6 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
from wlauto.core.configuration.configuration import (settings,
|
from wlauto.core.configuration.configuration import (settings,
|
||||||
WAConfiguration,
|
|
||||||
RunConfiguration,
|
RunConfiguration,
|
||||||
JobGenerator,
|
JobGenerator,
|
||||||
ConfigurationPoint)
|
ConfigurationPoint)
|
||||||
|
@ -492,36 +492,11 @@ class CpuFreqParameters(object):
|
|||||||
class Configuration(object):
|
class Configuration(object):
|
||||||
|
|
||||||
config_points = []
|
config_points = []
|
||||||
name = ""
|
name = ''
|
||||||
|
|
||||||
# The below line must be added to all subclasses
|
# The below line must be added to all subclasses
|
||||||
configuration = {cp.name: cp for cp in config_points}
|
configuration = {cp.name: cp for cp in config_points}
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
# Load default values for configuration points
|
|
||||||
for confpoint in self.configuration.itervalues():
|
|
||||||
confpoint.set_value(self, check_mandatory=False)
|
|
||||||
|
|
||||||
def set(self, name, value, check_mandatory=True):
|
|
||||||
if name not in self.configuration:
|
|
||||||
raise ConfigError('Unknown {} configuration "{}"'.format(self.name, name))
|
|
||||||
self.configuration[name].set_value(self, value, check_mandatory=check_mandatory)
|
|
||||||
|
|
||||||
def update_config(self, values, check_mandatory=True):
|
|
||||||
for k, v in values.iteritems():
|
|
||||||
self.set(k, v, check_mandatory=check_mandatory)
|
|
||||||
|
|
||||||
def validate(self):
|
|
||||||
for cfg_point in self.configuration.itervalues():
|
|
||||||
cfg_point.validate(self)
|
|
||||||
|
|
||||||
def to_pod(self):
|
|
||||||
pod = {}
|
|
||||||
for cfg_point_name in self.configuration.iterkeys():
|
|
||||||
value = getattr(self, cfg_point_name, None)
|
|
||||||
if value is not None:
|
|
||||||
pod[cfg_point_name] = value
|
|
||||||
return pod
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
def from_pod(cls, pod, plugin_cache):
|
def from_pod(cls, pod, plugin_cache):
|
||||||
@ -535,11 +510,46 @@ class Configuration(object):
|
|||||||
instance.validate()
|
instance.validate()
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
for confpoint in self.config_points:
|
||||||
|
confpoint.set_value(self, check_mandatory=False)
|
||||||
|
|
||||||
|
def set(self, name, value, check_mandatory=True):
|
||||||
|
if name not in self.configuration:
|
||||||
|
raise ConfigError('Unknown {} configuration "{}"'.format(self.name, name))
|
||||||
|
self.configuration[name].set_value(self, value, check_mandatory=check_mandatory)
|
||||||
|
|
||||||
|
def update_config(self, values, check_mandatory=True):
|
||||||
|
for k, v in values.iteritems():
|
||||||
|
self.set(k, v, check_mandatory=check_mandatory)
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
for cfg_point in self.config_points:
|
||||||
|
cfg_point.validate(self)
|
||||||
|
|
||||||
|
def to_pod(self):
|
||||||
|
pod = {}
|
||||||
|
for cfg_point_name in self.configuration.iterkeys():
|
||||||
|
value = getattr(self, cfg_point_name, None)
|
||||||
|
if value is not None:
|
||||||
|
pod[cfg_point_name] = value
|
||||||
|
return pod
|
||||||
|
|
||||||
|
|
||||||
# This configuration for the core WA framework
|
# This configuration for the core WA framework
|
||||||
class WAConfiguration(Configuration):
|
class WAConfiguration(Configuration):
|
||||||
|
|
||||||
name = "WA Configuration"
|
name = "WA Configuration"
|
||||||
|
|
||||||
|
plugin_packages = [
|
||||||
|
'wlauto.commands',
|
||||||
|
'wlauto.workloads',
|
||||||
|
'wlauto.instrumentation',
|
||||||
|
'wlauto.result_processors',
|
||||||
|
'wlauto.managers',
|
||||||
|
'wlauto.resource_getters',
|
||||||
|
]
|
||||||
|
|
||||||
config_points = [
|
config_points = [
|
||||||
ConfigurationPoint(
|
ConfigurationPoint(
|
||||||
'user_directory',
|
'user_directory',
|
||||||
@ -550,48 +560,6 @@ class WAConfiguration(Configuration):
|
|||||||
kind=str,
|
kind=str,
|
||||||
default=os.path.join(os.path.expanduser('~'), '.workload_automation'),
|
default=os.path.join(os.path.expanduser('~'), '.workload_automation'),
|
||||||
),
|
),
|
||||||
ConfigurationPoint(
|
|
||||||
'plugin_packages',
|
|
||||||
kind=list_of_strings,
|
|
||||||
default=[
|
|
||||||
'wlauto.commands',
|
|
||||||
'wlauto.workloads',
|
|
||||||
'wlauto.instrumentation',
|
|
||||||
'wlauto.result_processors',
|
|
||||||
'wlauto.managers',
|
|
||||||
'wlauto.resource_getters',
|
|
||||||
],
|
|
||||||
description="""
|
|
||||||
List of packages that will be scanned for WA plugins.
|
|
||||||
""",
|
|
||||||
),
|
|
||||||
ConfigurationPoint(
|
|
||||||
'plugin_paths',
|
|
||||||
kind=list_of_strings,
|
|
||||||
default=[
|
|
||||||
'workloads',
|
|
||||||
'instruments',
|
|
||||||
'targets',
|
|
||||||
'processors',
|
|
||||||
|
|
||||||
# Legacy
|
|
||||||
'managers',
|
|
||||||
'result_processors',
|
|
||||||
],
|
|
||||||
description="""
|
|
||||||
List of paths that will be scanned for WA plugins.
|
|
||||||
""",
|
|
||||||
merge=True
|
|
||||||
),
|
|
||||||
ConfigurationPoint(
|
|
||||||
'plugin_ignore_paths',
|
|
||||||
kind=list_of_strings,
|
|
||||||
default=[],
|
|
||||||
description="""
|
|
||||||
List of (sub)paths that will be ignored when scanning
|
|
||||||
``plugin_paths`` for WA plugins.
|
|
||||||
""",
|
|
||||||
),
|
|
||||||
ConfigurationPoint(
|
ConfigurationPoint(
|
||||||
'assets_repository',
|
'assets_repository',
|
||||||
description="""
|
description="""
|
||||||
@ -623,7 +591,7 @@ class WAConfiguration(Configuration):
|
|||||||
Verbosity of console output.
|
Verbosity of console output.
|
||||||
""",
|
""",
|
||||||
),
|
),
|
||||||
ConfigurationPoint( # TODO: Needs some format for dates ect/ comes from cfg
|
ConfigurationPoint( # TODO: Needs some format for dates etc/ comes from cfg
|
||||||
'default_output_directory',
|
'default_output_directory',
|
||||||
default="wa_output",
|
default="wa_output",
|
||||||
description="""
|
description="""
|
||||||
@ -636,7 +604,19 @@ class WAConfiguration(Configuration):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def dependencies_directory(self):
|
def dependencies_directory(self):
|
||||||
return "{}/dependencies/".format(self.user_directory)
|
return os.path.join(self.user_directory, 'dependencies')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def plugins_directory(self):
|
||||||
|
return os.path.join(self.user_directory, 'plugins')
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, environ):
|
||||||
|
super(WAConfiguration, self).__init__()
|
||||||
|
user_directory = environ.pop('WA_USER_DIRECTORY', '')
|
||||||
|
if user_directory:
|
||||||
|
self.set('user_directory', user_directory)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# This is generic top-level configuration for WA runs.
|
# This is generic top-level configuration for WA runs.
|
||||||
@ -1029,4 +1009,4 @@ class JobGenerator(object):
|
|||||||
|
|
||||||
yield job_spec
|
yield job_spec
|
||||||
|
|
||||||
settings = WAConfiguration()
|
settings = WAConfiguration(os.environ)
|
||||||
|
@ -283,23 +283,11 @@ class AgendaParser(object):
|
|||||||
raise ConfigError('Error in "{}":\n\t{}'.format(source, str(e)))
|
raise ConfigError('Error in "{}":\n\t{}'.format(source, str(e)))
|
||||||
|
|
||||||
|
|
||||||
class EnvironmentVarsParser(object):
|
|
||||||
def __init__(self, wa_config, environ):
|
|
||||||
user_directory = environ.pop('WA_USER_DIRECTORY', '')
|
|
||||||
if user_directory:
|
|
||||||
wa_config.set('user_directory', user_directory)
|
|
||||||
plugin_paths = environ.pop('WA_PLUGIN_PATHS', '')
|
|
||||||
if plugin_paths:
|
|
||||||
wa_config.set('plugin_paths', plugin_paths.split(os.pathsep))
|
|
||||||
ext_paths = environ.pop('WA_EXTENSION_PATHS', '')
|
|
||||||
if ext_paths:
|
|
||||||
wa_config.set('plugin_paths', ext_paths.split(os.pathsep))
|
|
||||||
|
|
||||||
|
|
||||||
# Command line options are parsed in the "run" command. This is used to send
|
# Command line options are parsed in the "run" command. This is used to send
|
||||||
# certain arguments to the correct configuration points and keep a record of
|
# certain arguments to the correct configuration points and keep a record of
|
||||||
# how WA was invoked
|
# how WA was invoked
|
||||||
class CommandLineArgsParser(object):
|
class CommandLineArgsParser(object):
|
||||||
|
|
||||||
def __init__(self, cmd_args, wa_config, jobs_config):
|
def __init__(self, cmd_args, wa_config, jobs_config):
|
||||||
wa_config.set("verbosity", cmd_args.verbosity)
|
wa_config.set("verbosity", cmd_args.verbosity)
|
||||||
# TODO: Is this correct? Does there need to be a third output dir param
|
# TODO: Is this correct? Does there need to be a third output dir param
|
||||||
|
@ -24,6 +24,7 @@ import warnings
|
|||||||
from wlauto.core.configuration import settings
|
from wlauto.core.configuration import settings
|
||||||
from wlauto.core import pluginloader
|
from wlauto.core import pluginloader
|
||||||
from wlauto.core.command import init_argument_parser
|
from wlauto.core.command import init_argument_parser
|
||||||
|
from wlauto.core.host import init_user_directory
|
||||||
from wlauto.exceptions import WAError, ConfigError
|
from wlauto.exceptions import WAError, ConfigError
|
||||||
from wlauto.utils.misc import get_traceback
|
from wlauto.utils.misc import get_traceback
|
||||||
from wlauto.utils.log import init_logging
|
from wlauto.utils.log import init_logging
|
||||||
@ -45,7 +46,11 @@ def load_commands(subparsers):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
if not os.path.exists(settings.user_directory):
|
||||||
|
init_user_directory()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|
||||||
description = ("Execute automated workloads on a remote device and process "
|
description = ("Execute automated workloads on a remote device and process "
|
||||||
"the resulting output.\n\nUse \"wa <subcommand> -h\" to see "
|
"the resulting output.\n\nUse \"wa <subcommand> -h\" to see "
|
||||||
"help for individual subcommands.")
|
"help for individual subcommands.")
|
||||||
@ -57,10 +62,7 @@ def main():
|
|||||||
commands = load_commands(parser.add_subparsers(dest='command')) # each command will add its own subparser
|
commands = load_commands(parser.add_subparsers(dest='command')) # each command will add its own subparser
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
#TODO: Set this stuff properly, i.e dont use settings (if possible)
|
settings.set("verbosity", args.verbose)
|
||||||
#settings.set("verbosity", args.verbose)
|
|
||||||
#settings.load_user_config()
|
|
||||||
#settings.debug = args.debug
|
|
||||||
|
|
||||||
for config in args.config:
|
for config in args.config:
|
||||||
if not os.path.exists(config):
|
if not os.path.exists(config):
|
||||||
|
33
wlauto/core/host.py
Normal file
33
wlauto/core/host.py
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from wlauto.core.configuration import settings
|
||||||
|
|
||||||
|
def init_user_directory(overwrite_existing=False): # pylint: disable=R0914
|
||||||
|
"""
|
||||||
|
Initialise a fresh user directory.
|
||||||
|
"""
|
||||||
|
if os.path.exists(settings.user_directory):
|
||||||
|
if not overwrite_existing:
|
||||||
|
raise RuntimeError('Environment {} already exists.'.format(settings.user_directory))
|
||||||
|
shutil.rmtree(settings.user_directory)
|
||||||
|
|
||||||
|
os.makedirs(settings.user_directory)
|
||||||
|
os.makedirs(settings.dependencies_directory)
|
||||||
|
os.makedirs(settings.plugins_directory)
|
||||||
|
|
||||||
|
# TODO: generate default config.yaml here
|
||||||
|
|
||||||
|
if os.getenv('USER') == 'root':
|
||||||
|
# If running with sudo on POSIX, change the ownership to the real user.
|
||||||
|
real_user = os.getenv('SUDO_USER')
|
||||||
|
if real_user:
|
||||||
|
import pwd # done here as module won't import on win32
|
||||||
|
user_entry = pwd.getpwnam(real_user)
|
||||||
|
uid, gid = user_entry.pw_uid, user_entry.pw_gid
|
||||||
|
os.chown(settings.user_directory, uid, gid)
|
||||||
|
# why, oh why isn't there a recusive=True option for os.chown?
|
||||||
|
for root, dirs, files in os.walk(settings.user_directory):
|
||||||
|
for d in dirs:
|
||||||
|
os.chown(os.path.join(root, d), uid, gid)
|
||||||
|
for f in files:
|
||||||
|
os.chown(os.path.join(root, f), uid, gid)
|
@ -25,13 +25,14 @@ from collections import OrderedDict, defaultdict
|
|||||||
from itertools import chain
|
from itertools import chain
|
||||||
from copy import copy
|
from copy import copy
|
||||||
|
|
||||||
from wlauto.exceptions import NotFoundError, LoaderError, ValidationError, ConfigError
|
from wlauto.exceptions import NotFoundError, LoaderError, ValidationError, ConfigError, HostError
|
||||||
from wlauto.utils.misc import (ensure_directory_exists as _d,
|
from wlauto.utils.misc import (ensure_directory_exists as _d,
|
||||||
walk_modules, load_class, merge_dicts_simple, get_article)
|
walk_modules, load_class, merge_dicts_simple, get_article)
|
||||||
from wlauto.core.configuration import settings
|
from wlauto.core.configuration import settings
|
||||||
from wlauto.utils.types import identifier, boolean
|
from wlauto.utils.types import identifier, boolean
|
||||||
from wlauto.core.configuration.configuration import ConfigurationPoint as Parameter
|
from wlauto.core.configuration.configuration import ConfigurationPoint as Parameter
|
||||||
|
|
||||||
|
|
||||||
MODNAME_TRANS = string.maketrans(':/\\.', '____')
|
MODNAME_TRANS = string.maketrans(':/\\.', '____')
|
||||||
|
|
||||||
|
|
||||||
@ -697,10 +698,9 @@ class PluginLoader(object):
|
|||||||
for package in packages:
|
for package in packages:
|
||||||
for module in walk_modules(package):
|
for module in walk_modules(package):
|
||||||
self._discover_in_module(module)
|
self._discover_in_module(module)
|
||||||
except ImportError as e:
|
except HostError as e:
|
||||||
source = getattr(e, 'path', package)
|
|
||||||
message = 'Problem loading plugins from {}: {}'
|
message = 'Problem loading plugins from {}: {}'
|
||||||
raise LoaderError(message.format(source, e.message))
|
raise LoaderError(message.format(e.module, str(e.orig_exc)))
|
||||||
|
|
||||||
def _discover_from_paths(self, paths, ignore_paths):
|
def _discover_from_paths(self, paths, ignore_paths):
|
||||||
paths = paths or []
|
paths = paths or []
|
||||||
|
@ -38,8 +38,7 @@ class __LoaderWrapper(object):
|
|||||||
from wlauto.core.plugin import PluginLoader
|
from wlauto.core.plugin import PluginLoader
|
||||||
from wlauto.core.configuration import settings
|
from wlauto.core.configuration import settings
|
||||||
self._loader = PluginLoader(settings.plugin_packages,
|
self._loader = PluginLoader(settings.plugin_packages,
|
||||||
settings.plugin_paths,
|
[settings.plugins_directory], [])
|
||||||
settings.plugin_ignore_paths)
|
|
||||||
|
|
||||||
def update(self, packages=None, paths=None, ignore_paths=None):
|
def update(self, packages=None, paths=None, ignore_paths=None):
|
||||||
if not self._loader:
|
if not self._loader:
|
||||||
|
@ -14,7 +14,9 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
from wlauto.utils.misc import get_traceback, TimeoutError # NOQA pylint: disable=W0611
|
from wlauto.utils.misc import get_traceback
|
||||||
|
|
||||||
|
from devlib.exception import DevlibError, HostError, TargetError, TimeoutError
|
||||||
|
|
||||||
|
|
||||||
class WAError(Exception):
|
class WAError(Exception):
|
||||||
|
@ -8,8 +8,8 @@ from mock.mock import Mock, MagicMock, call
|
|||||||
from wlauto.exceptions import ConfigError
|
from wlauto.exceptions import ConfigError
|
||||||
from wlauto.core.configuration.parsers import * # pylint: disable=wildcard-import
|
from wlauto.core.configuration.parsers import * # pylint: disable=wildcard-import
|
||||||
from wlauto.core.configuration.parsers import _load_file, _collect_valid_id, _resolve_params_alias
|
from wlauto.core.configuration.parsers import _load_file, _collect_valid_id, _resolve_params_alias
|
||||||
from wlauto.core.configuration import (WAConfiguration, RunConfiguration, JobGenerator,
|
from wlauto.core.configuration import RunConfiguration, JobGenerator, PluginCache, ConfigurationPoint
|
||||||
PluginCache, ConfigurationPoint)
|
from wlauto.core.configuration.configuration import WAConfiguration
|
||||||
from wlauto.utils.types import toggle_set, reset_counter
|
from wlauto.utils.types import toggle_set, reset_counter
|
||||||
|
|
||||||
|
|
||||||
@ -125,9 +125,6 @@ class TestFunctions(TestCase):
|
|||||||
with self.assertRaises(ConfigError):
|
with self.assertRaises(ConfigError):
|
||||||
_resolve_params_alias(test, "new_name")
|
_resolve_params_alias(test, "new_name")
|
||||||
|
|
||||||
def test_construct_valid_entry(self):
|
|
||||||
raise Exception()
|
|
||||||
|
|
||||||
|
|
||||||
class TestConfigParser(TestCase):
|
class TestConfigParser(TestCase):
|
||||||
|
|
||||||
@ -362,44 +359,6 @@ class TestAgendaParser(TestCase):
|
|||||||
assert_equal(workload['workload_name'], "test")
|
assert_equal(workload['workload_name'], "test")
|
||||||
|
|
||||||
|
|
||||||
class TestEnvironmentVarsParser(TestCase):
|
|
||||||
|
|
||||||
def test_environmentvarsparser(self):
|
|
||||||
wa_config = Mock(spec=WAConfiguration)
|
|
||||||
calls = [call('user_directory', '/testdir'),
|
|
||||||
call('plugin_paths', ['/test', '/some/other/path', '/testy/mc/test/face'])]
|
|
||||||
|
|
||||||
# Valid env vars
|
|
||||||
valid_environ = {"WA_USER_DIRECTORY": "/testdir",
|
|
||||||
"WA_PLUGIN_PATHS": "/test:/some/other/path:/testy/mc/test/face"}
|
|
||||||
EnvironmentVarsParser(wa_config, valid_environ)
|
|
||||||
wa_config.set.assert_has_calls(calls)
|
|
||||||
|
|
||||||
# Alternative env var name
|
|
||||||
wa_config.reset_mock()
|
|
||||||
alt_valid_environ = {"WA_USER_DIRECTORY": "/testdir",
|
|
||||||
"WA_EXTENSION_PATHS": "/test:/some/other/path:/testy/mc/test/face"}
|
|
||||||
EnvironmentVarsParser(wa_config, alt_valid_environ)
|
|
||||||
wa_config.set.assert_has_calls(calls)
|
|
||||||
|
|
||||||
# Test that WA_EXTENSION_PATHS gets merged with WA_PLUGIN_PATHS.
|
|
||||||
# Also checks that other enviroment variables don't cause errors
|
|
||||||
wa_config.reset_mock()
|
|
||||||
calls = [call('user_directory', '/testdir'),
|
|
||||||
call('plugin_paths', ['/test', '/some/other/path']),
|
|
||||||
call('plugin_paths', ['/testy/mc/test/face'])]
|
|
||||||
ext_and_plgin = {"WA_USER_DIRECTORY": "/testdir",
|
|
||||||
"WA_PLUGIN_PATHS": "/test:/some/other/path",
|
|
||||||
"WA_EXTENSION_PATHS": "/testy/mc/test/face",
|
|
||||||
"RANDOM_VAR": "random_value"}
|
|
||||||
EnvironmentVarsParser(wa_config, ext_and_plgin)
|
|
||||||
# If any_order=True then the calls can be in any order, but they must all appear
|
|
||||||
wa_config.set.assert_has_calls(calls, any_order=True)
|
|
||||||
|
|
||||||
# No WA enviroment variables present
|
|
||||||
wa_config.reset_mock()
|
|
||||||
EnvironmentVarsParser(wa_config, {"RANDOM_VAR": "random_value"})
|
|
||||||
wa_config.set.assert_not_called()
|
|
||||||
|
|
||||||
|
|
||||||
class TestCommandLineArgsParser(TestCase):
|
class TestCommandLineArgsParser(TestCase):
|
||||||
|
@ -492,7 +492,7 @@ def merge_config_values(base, other):
|
|||||||
are treated as atomic, and not mergeable.
|
are treated as atomic, and not mergeable.
|
||||||
s: A sequence. Anything iterable that is not a dict or
|
s: A sequence. Anything iterable that is not a dict or
|
||||||
a string (strings are considered scalars).
|
a string (strings are considered scalars).
|
||||||
m: A key-value mapping. ``dict`` and it's derivatives.
|
m: A key-value mapping. ``dict`` and its derivatives.
|
||||||
n: ``None``.
|
n: ``None``.
|
||||||
o: A mergeable object; this is an object that implements both
|
o: A mergeable object; this is an object that implements both
|
||||||
``merge_with`` and ``merge_into`` methods.
|
``merge_with`` and ``merge_into`` methods.
|
||||||
|
@ -51,7 +51,7 @@ import yaml as _yaml
|
|||||||
import dateutil.parser
|
import dateutil.parser
|
||||||
|
|
||||||
from wlauto.exceptions import SerializerSyntaxError
|
from wlauto.exceptions import SerializerSyntaxError
|
||||||
from wlauto.utils.types import regex_type
|
from wlauto.utils.types import regex_type, none_type
|
||||||
from wlauto.utils.misc import isiterable
|
from wlauto.utils.misc import isiterable
|
||||||
|
|
||||||
|
|
||||||
@ -70,12 +70,14 @@ POD_TYPES = [
|
|||||||
tuple,
|
tuple,
|
||||||
dict,
|
dict,
|
||||||
set,
|
set,
|
||||||
basestring,
|
str,
|
||||||
|
unicode,
|
||||||
int,
|
int,
|
||||||
float,
|
float,
|
||||||
bool,
|
bool,
|
||||||
datetime,
|
datetime,
|
||||||
regex_type
|
regex_type,
|
||||||
|
none_type,
|
||||||
]
|
]
|
||||||
|
|
||||||
class WAJSONEncoder(_json.JSONEncoder):
|
class WAJSONEncoder(_json.JSONEncoder):
|
||||||
@ -257,3 +259,4 @@ def _read_pod(fh, fmt=None):
|
|||||||
|
|
||||||
def is_pod(obj):
|
def is_pod(obj):
|
||||||
return type(obj) in POD_TYPES
|
return type(obj) in POD_TYPES
|
||||||
|
|
||||||
|
@ -169,6 +169,7 @@ list_or_bool = list_or(boolean)
|
|||||||
|
|
||||||
|
|
||||||
regex_type = type(re.compile(''))
|
regex_type = type(re.compile(''))
|
||||||
|
none_type = type(None)
|
||||||
|
|
||||||
|
|
||||||
def regex(value):
|
def regex(value):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user