Skip to content

Commit

Permalink
Merge fe8e53d into 15cc037
Browse files Browse the repository at this point in the history
  • Loading branch information
UnDarkle committed Sep 12, 2018
2 parents 15cc037 + fe8e53d commit 6abe8b5
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 43 deletions.
28 changes: 28 additions & 0 deletions src/rotest/common/utils.py
Expand Up @@ -72,3 +72,31 @@ def get_work_dir(base_dir, test_name, test_item):

os.makedirs(work_dir)
return work_dir


def get_class_fields(cls, field_type):
"""Get all fields of the class that inherit from the given type.
* This method searches also in the parent classes.
* Fields of sons override fields of parents.
* Ignores fields starting with '_'.
Args:
cls (type): class to search.
field_type (type): field type to find.
Yields:
tuple. all found (field name, field value).
"""
if cls is object:
return

for parent_class in cls.__bases__:
for (field_name, field) in get_class_fields(parent_class, field_type):
yield (field_name, field)

for field_name in cls.__dict__:
if not field_name.startswith("_"):
field = getattr(cls, field_name)
if isinstance(field, field_type):
yield (field_name, field)
20 changes: 2 additions & 18 deletions src/rotest/core/abstract_test.py
Expand Up @@ -13,6 +13,7 @@
from ipdbugger import debug
from attrdict import AttrDict

from rotest.common.utils import get_class_fields
from rotest.core.models.case_data import TestOutcome
from rotest.management.base_resource import BaseResource
from rotest.management.client.manager import ResourceRequest
Expand Down Expand Up @@ -101,23 +102,6 @@ def release_resource_loggers(self):
for resource in self.all_resources.itervalues():
resource.release_logger(self.logger)

@classmethod
def get_resource_requests_fields(cls):
"""Yield tuples of all the resource request fields of this test.
Yields:
tuple. (requests name, request field) tuples of the test class.
"""
checked_class = cls
while checked_class is not AbstractTest:
for field_name in checked_class.__dict__:
if not field_name.startswith("_"):
field = getattr(checked_class, field_name)
if isinstance(field, BaseResource):
yield (field_name, field)

checked_class = checked_class.__bases__[0]

@classmethod
def get_resource_requests(cls):
"""Return a list of all the resource requests this test makes.
Expand All @@ -130,7 +114,7 @@ def get_resource_requests(cls):
list. resource requests of the test class.
"""
all_requests = list(cls.resources)
for (field_name, field) in cls.get_resource_requests_fields():
for (field_name, field) in get_class_fields(cls, BaseResource):
new_request = request(field_name,
field.__class__,
**field.kwargs)
Expand Down
28 changes: 5 additions & 23 deletions src/rotest/core/block.py
Expand Up @@ -2,6 +2,7 @@
# pylint: disable=dangerous-default-value,too-many-arguments
from itertools import count

from rotest.common.utils import get_class_fields
from rotest.common.config import ROTEST_WORK_DIR
from rotest.core.flow_component import (AbstractFlowComponent, MODE_OPTIONAL,
MODE_FINALLY, MODE_CRITICAL,
Expand Down Expand Up @@ -105,40 +106,21 @@ def get_name(cls):

@classmethod
def get_inputs(cls):
"""Return a list of all the input instances of this block.
"""Return a dict of all the input instances of this block.
Returns:
dict. block's inputs (name: input placeholder instance).
"""
all_inputs = {}
checked_class = cls
while checked_class is not TestBlock:
all_inputs.update({key: value for (key, value) in
checked_class.__dict__.iteritems()
if (isinstance(value, BlockInput) and
key not in all_inputs)})

checked_class = checked_class.__bases__[0]

return all_inputs
return dict(get_class_fields(cls, BlockInput))

@classmethod
def get_outputs(cls):
"""Return a list of all the input instances of this block.
"""Return a dict of all the input instances of this block.
Returns:
dict. block's inputs (name: input placeholder instance).
"""
all_outputs = {}
checked_class = cls
while checked_class is not TestBlock:
all_outputs.update({key: value for (key, value) in
checked_class.__dict__.iteritems()
if isinstance(value, BlockOutput)})

checked_class = checked_class.__bases__[0]

return all_outputs
return dict(get_class_fields(cls, BlockOutput))

def _share_outputs(self):
"""Share all the declared outputs of the block."""
Expand Down
24 changes: 22 additions & 2 deletions src/rotest/management/base_resource.py
Expand Up @@ -10,7 +10,7 @@
from attrdict import AttrDict

from rotest.common import core_log
from rotest.common.utils import get_work_dir
from rotest.common.utils import get_work_dir, get_class_fields


class ConvertToKwargsMeta(type):
Expand Down Expand Up @@ -95,13 +95,33 @@ def __init__(self, data=None, **kwargs):
def create_sub_resources(self):
"""Create and return the sub resources if needed.
By default, this method searches for sub-resources declared as
class fields, where the 'data' attribute in the declaration points
to the name of the sub-resource's data field under the current's data.
Override and assign sub-resources to fields in the current resource,
using the 'data' object.
Returns:
iterable. sub-resources created.
"""
return ()
sub_resources = []
for sub_name, sub_placeholder in get_class_fields(self.__class__,
BaseResource):

sub_class = sub_placeholder.__class__
if sub_class.DATA_CLASS is None:
sub_data = None

else:
sub_data = getattr(self.data, sub_placeholder.data)

sub_resource = sub_class(data=sub_data, **sub_placeholder.kwargs)

setattr(self, sub_name, sub_resource)
sub_resources.append(sub_resource)

return sub_resources

def is_available(self, user_name=""):
"""Return whether resource is available for the given user.
Expand Down

0 comments on commit 6abe8b5

Please sign in to comment.