1#
2# Copyright (C) 2016 Intel Corporation
3#
4# SPDX-License-Identifier: MIT
5#
6
7from functools import wraps
8from abc import ABCMeta
9
10decoratorClasses = set()
11
12def registerDecorator(cls):
13    decoratorClasses.add(cls)
14    return cls
15
16class OETestDecorator(object, metaclass=ABCMeta):
17    case = None # Reference of OETestCase decorated
18    attrs = None # Attributes to be loaded by decorator implementation
19
20    def __init__(self, *args, **kwargs):
21        if not self.attrs:
22            return
23
24        for idx, attr in enumerate(self.attrs):
25            if attr in kwargs:
26                value = kwargs[attr]
27            else:
28                value = args[idx]
29            setattr(self, attr, value)
30
31    def __call__(self, func):
32        @wraps(func)
33        def wrapped_f(*args, **kwargs):
34            self.attrs = self.attrs # XXX: Enables OETestLoader discover
35            return func(*args, **kwargs)
36        return wrapped_f
37
38    # OETestLoader call it when is loading test cases.
39    # XXX: Most methods would change the registry for later
40    # processing; be aware that filtrate method needs to
41    # run later than bind, so there could be data (in the
42    # registry) of a cases that were filtered.
43    def bind(self, registry, case):
44        self.case = case
45        self.logger = case.tc.logger
46        self.case.decorators.append(self)
47
48    # OETestRunner call this method when tries to run
49    # the test case.
50    def setUpDecorator(self):
51        pass
52
53    # OETestRunner call it after a test method has been
54    # called even if the method raised an exception.
55    def tearDownDecorator(self):
56        pass
57
58class OETestDiscover(OETestDecorator):
59
60    # OETestLoader call it after discover test cases
61    # needs to return the cases to be run.
62    @staticmethod
63    def discover(registry):
64        return registry['cases']
65
66def OETestTag(*tags):
67    def decorator(item):
68        if hasattr(item, "__oeqa_testtags"):
69            # do not append, create a new list (to handle classes with inheritance)
70            item.__oeqa_testtags = list(item.__oeqa_testtags) + list(tags)
71        else:
72            item.__oeqa_testtags = tags
73        return item
74    return decorator
75