mirror of
https://github.com/ARM-software/workload-automation.git
synced 2025-02-21 20:38:57 +00:00
commit
ae0847e815
@ -18,7 +18,7 @@
|
|||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
|
|
||||||
from nose.tools import raises, assert_equal, assert_not_equal, assert_in, assert_not_in
|
from nose.tools import raises, assert_equal, assert_not_equal, assert_in, assert_not_in
|
||||||
from nose.tools import assert_true, assert_false
|
from nose.tools import assert_true, assert_false, assert_raises, assert_is, assert_list_equal
|
||||||
|
|
||||||
from wa.utils.types import (list_or_integer, list_or_bool, caseless_string,
|
from wa.utils.types import (list_or_integer, list_or_bool, caseless_string,
|
||||||
arguments, prioritylist, enum, level)
|
arguments, prioritylist, enum, level)
|
||||||
@ -97,6 +97,45 @@ class TestPriorityList(TestCase):
|
|||||||
|
|
||||||
class TestEnumLevel(TestCase):
|
class TestEnumLevel(TestCase):
|
||||||
|
|
||||||
|
def test_enum_creation(self):
|
||||||
|
e = enum(['one', 'two', 'three'])
|
||||||
|
assert_list_equal(e.values, [0, 1, 2])
|
||||||
|
|
||||||
|
e = enum(['one', 'two', 'three'], start=10)
|
||||||
|
assert_list_equal(e.values, [10, 11, 12])
|
||||||
|
|
||||||
|
e = enum(['one', 'two', 'three'], start=-10, step=10)
|
||||||
|
assert_list_equal(e.values, [-10, 0, 10])
|
||||||
|
|
||||||
|
def test_enum_name_conflicts(self):
|
||||||
|
assert_raises(ValueError, enum, ['names', 'one', 'two'])
|
||||||
|
|
||||||
|
e = enum(['NAMES', 'one', 'two'])
|
||||||
|
assert_in('names', e.levels)
|
||||||
|
assert_list_equal(e.names, ['names', 'one', 'two'])
|
||||||
|
assert_equal(e.NAMES, 'names')
|
||||||
|
|
||||||
|
def test_enum_behavior(self):
|
||||||
|
e = enum(['one', 'two', 'three'])
|
||||||
|
|
||||||
|
# case-insensitive level name and level value may all
|
||||||
|
# be used for equality comparisons.
|
||||||
|
assert_equal(e.one, 'one')
|
||||||
|
assert_equal(e.one, 'ONE')
|
||||||
|
assert_equal(e.one, 0)
|
||||||
|
assert_not_equal(e.one, '0')
|
||||||
|
|
||||||
|
# ditto for enum membership tests
|
||||||
|
assert_in('one', e.levels)
|
||||||
|
assert_in(2, e.levels)
|
||||||
|
assert_not_in('five', e.levels)
|
||||||
|
|
||||||
|
# The same level object returned, only when
|
||||||
|
# passing in a valid level name/value.
|
||||||
|
assert_is(e('one'), e('ONE'))
|
||||||
|
assert_is(e('one'), e(0))
|
||||||
|
assert_raises(ValueError, e, 'five')
|
||||||
|
|
||||||
def test_serialize_level(self):
|
def test_serialize_level(self):
|
||||||
l = level('test', 1)
|
l = level('test', 1)
|
||||||
s = l.to_pod()
|
s = l.to_pod()
|
||||||
|
@ -741,7 +741,7 @@ class RunConfiguration(Configuration):
|
|||||||
'retry_on_status',
|
'retry_on_status',
|
||||||
kind=list_of(Status),
|
kind=list_of(Status),
|
||||||
default=['FAILED', 'PARTIAL'],
|
default=['FAILED', 'PARTIAL'],
|
||||||
allowed_values=Status.values[Status.RUNNING.value:],
|
allowed_values=Status.levels[Status.RUNNING.value:],
|
||||||
description='''
|
description='''
|
||||||
This is list of statuses on which a job will be considered to have
|
This is list of statuses on which a job will be considered to have
|
||||||
failed and will be automatically retried up to ``max_retries``
|
failed and will be automatically retried up to ``max_retries``
|
||||||
|
@ -186,7 +186,7 @@ def priority(priority):
|
|||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
wrapper.func_name = func.func_name
|
wrapper.func_name = func.func_name
|
||||||
if priority in Priority.values:
|
if priority in Priority.levels:
|
||||||
wrapper.priority = Priority(priority)
|
wrapper.priority = Priority(priority)
|
||||||
else:
|
else:
|
||||||
if not isinstance(priority, int):
|
if not isinstance(priority, int):
|
||||||
|
@ -235,50 +235,6 @@ def get_pager():
|
|||||||
return pager
|
return pager
|
||||||
|
|
||||||
|
|
||||||
def enum_metaclass(enum_param, return_name=False, start=0):
|
|
||||||
"""
|
|
||||||
Returns a ``type`` subclass that may be used as a metaclass for
|
|
||||||
an enum.
|
|
||||||
|
|
||||||
Paremeters:
|
|
||||||
|
|
||||||
:enum_param: the name of class attribute that defines enum values.
|
|
||||||
The metaclass will add a class attribute for each value in
|
|
||||||
``enum_param``. The value of the attribute depends on the type
|
|
||||||
of ``enum_param`` and on the values of ``return_name``. If
|
|
||||||
``return_name`` is ``True``, then the value of the new attribute is
|
|
||||||
the name of that attribute; otherwise, if ``enum_param`` is a ``list``
|
|
||||||
or a ``tuple``, the value will be the index of that param in
|
|
||||||
``enum_param``, optionally offset by ``start``, otherwise, it will
|
|
||||||
be assumed that ``enum_param`` implementa a dict-like inteface and
|
|
||||||
the value will be ``enum_param[attr_name]``.
|
|
||||||
:return_name: If ``True``, the enum values will the names of enum attributes. If
|
|
||||||
``False``, the default, the values will depend on the type of
|
|
||||||
``enum_param`` (see above).
|
|
||||||
:start: If ``enum_param`` is a list or a tuple, and ``return_name`` is ``False``,
|
|
||||||
this specifies an "offset" that will be added to the index of the attribute
|
|
||||||
within ``enum_param`` to form the value.
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
class __EnumMeta(type):
|
|
||||||
def __new__(mcs, clsname, bases, attrs):
|
|
||||||
cls = type.__new__(mcs, clsname, bases, attrs)
|
|
||||||
values = getattr(cls, enum_param, [])
|
|
||||||
if return_name:
|
|
||||||
for name in values:
|
|
||||||
setattr(cls, name, name)
|
|
||||||
else:
|
|
||||||
if isinstance(values, list) or isinstance(values, tuple):
|
|
||||||
for i, name in enumerate(values):
|
|
||||||
setattr(cls, name, i + start)
|
|
||||||
else: # assume dict-like
|
|
||||||
for name in values:
|
|
||||||
setattr(cls, name, values[name])
|
|
||||||
return cls
|
|
||||||
return __EnumMeta
|
|
||||||
|
|
||||||
|
|
||||||
_bash_color_regex = re.compile('\x1b\[[0-9;]+m')
|
_bash_color_regex = re.compile('\x1b\[[0-9;]+m')
|
||||||
|
|
||||||
|
|
||||||
|
@ -557,7 +557,7 @@ def enum(args, start=0, step=1):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def from_pod(cls, pod):
|
def from_pod(cls, pod):
|
||||||
lv = level.from_pod(pod)
|
lv = level.from_pod(pod)
|
||||||
for enum_level in cls.values:
|
for enum_level in cls.levels:
|
||||||
if enum_level == lv:
|
if enum_level == lv:
|
||||||
return enum_level
|
return enum_level
|
||||||
msg = 'Unexpected value "{}" for enum.'
|
msg = 'Unexpected value "{}" for enum.'
|
||||||
@ -574,16 +574,24 @@ def enum(args, start=0, step=1):
|
|||||||
|
|
||||||
raise ValueError('Invalid enum value: {}'.format(repr(name)))
|
raise ValueError('Invalid enum value: {}'.format(repr(name)))
|
||||||
|
|
||||||
|
reserved = ['values', 'levels', 'names']
|
||||||
|
|
||||||
levels = []
|
levels = []
|
||||||
n = start
|
n = start
|
||||||
for v in args:
|
for v in args:
|
||||||
name = caseless_string(identifier(v))
|
id_v = identifier(v)
|
||||||
|
if id_v in reserved:
|
||||||
|
message = 'Invalid enum level name "{}"; must not be in {}'
|
||||||
|
raise ValueError(message.format(v, reserved))
|
||||||
|
name = caseless_string(id_v)
|
||||||
lv = level(v, n)
|
lv = level(v, n)
|
||||||
setattr(Enum, name, lv)
|
setattr(Enum, name, lv)
|
||||||
levels.append(lv)
|
levels.append(lv)
|
||||||
n += step
|
n += step
|
||||||
|
|
||||||
setattr(Enum, 'values', levels)
|
setattr(Enum, 'levels', levels)
|
||||||
|
setattr(Enum, 'values', [lv.value for lv in levels])
|
||||||
|
setattr(Enum, 'names', [lv.name for lv in levels])
|
||||||
|
|
||||||
return Enum
|
return Enum
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user