]> granicus.if.org Git - esp-idf/blob - tools/tiny-test-fw/TinyFW.py
Merge branch 'bugfix/btdm_fix_connect_interval_error_in_slave_adv_params' into 'master'
[esp-idf] / tools / tiny-test-fw / TinyFW.py
1 # Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http:#www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 """ Interface for test cases. """
16 import sys
17 import os
18 import time
19 import traceback
20 import inspect
21 import functools
22
23 import xunitgen
24
25 import Env
26 import DUT
27 import App
28 import Utility
29
30
31 XUNIT_FILE_NAME = "XUNIT_RESULT.xml"
32 XUNIT_RECEIVER = xunitgen.EventReceiver()
33 XUNIT_DEFAULT_TEST_SUITE = "test-suite"
34
35
36 class DefaultEnvConfig(object):
37     """
38     default test configs. There're 3 places to set configs, priority is (high -> low):
39
40     1. overwrite set by caller of test method
41     2. values set by test_method decorator
42     3. default env config get from this class
43     """
44     DEFAULT_CONFIG = {
45         "app": App.BaseApp,
46         "dut": DUT.BaseDUT,
47         "env_tag": "default",
48         "env_config_file": None,
49         "test_suite_name": None,
50     }
51
52     @classmethod
53     def set_default_config(cls, **kwargs):
54         """
55         :param kwargs: configs need to be updated
56         :return: None
57         """
58         cls.DEFAULT_CONFIG.update(kwargs)
59
60     @classmethod
61     def get_default_config(cls):
62         """
63         :return: current default config
64         """
65         return cls.DEFAULT_CONFIG.copy()
66
67
68 set_default_config = DefaultEnvConfig.set_default_config
69 get_default_config = DefaultEnvConfig.get_default_config
70
71
72 class TestResult(object):
73     TEST_RESULT = {
74         "pass": [],
75         "fail": [],
76     }
77
78     @classmethod
79     def get_failed_cases(cls):
80         """
81         :return: failed test cases
82         """
83         return cls.TEST_RESULT["fail"]
84
85     @classmethod
86     def get_passed_cases(cls):
87         """
88         :return: passed test cases
89         """
90         return cls.TEST_RESULT["pass"]
91
92     @classmethod
93     def set_result(cls, result, case_name):
94         """
95         :param result: True or False
96         :param case_name: test case name
97         :return: None
98         """
99         cls.TEST_RESULT["pass" if result else "fail"].append(case_name)
100
101
102 get_failed_cases = TestResult.get_failed_cases
103 get_passed_cases = TestResult.get_passed_cases
104
105
106 MANDATORY_INFO = {
107     "execution_time": 1,
108     "env_tag": "default",
109     "category": "function",
110     "ignore": False,
111 }
112
113
114 def test_method(**kwargs):
115     """
116     decorator for test case function.
117     The following keyword arguments are pre-defined.
118     Any other keyword arguments will be regarded as filter for the test case,
119     able to access them by ``case_info`` attribute of test method.
120
121     :keyword app: class for test app. see :doc:`App <App>` for details
122     :keyword dut: class for current dut. see :doc:`DUT <DUT>` for details
123     :keyword env_tag: name for test environment, used to select configs from config file
124     :keyword env_config_file: test env config file. usually will not set this keyword when define case
125     :keyword test_suite_name: test suite name, used for generating log folder name and adding xunit format test result.
126                               usually will not set this keyword when define case
127     """
128     def test(test_func):
129         # get test function file name
130         frame = inspect.stack()
131         test_func_file_name = frame[1][1]
132
133         case_info = MANDATORY_INFO.copy()
134         case_info["name"] = case_info["ID"] = test_func.__name__
135         case_info.update(kwargs)
136
137         @functools.wraps(test_func)
138         def handle_test(extra_data=None, **overwrite):
139             """
140             create env, run test and record test results
141
142             :param extra_data: extra data that runner or main passed to test case
143             :param overwrite: args that runner or main want to overwrite
144             :return: None
145             """
146             # create env instance
147             env_config = DefaultEnvConfig.get_default_config()
148             for key in kwargs:
149                 if key in env_config:
150                     env_config[key] = kwargs[key]
151
152             env_config.update(overwrite)
153             env_inst = Env.Env(**env_config)
154             # prepare for xunit test results
155             xunit_file = os.path.join(env_inst.app_cls.get_log_folder(env_config["test_suite_name"]),
156                                       XUNIT_FILE_NAME)
157             XUNIT_RECEIVER.begin_case(test_func.__name__, time.time(), test_func_file_name)
158             result = False
159             try:
160                 Utility.console_log("starting running test: " + test_func.__name__, color="green")
161                 # execute test function
162                 test_func(env_inst, extra_data)
163                 # if finish without exception, test result is True
164                 result = True
165             except Exception as e:
166                 # handle all the exceptions here
167                 traceback.print_exc()
168                 # log failure
169                 XUNIT_RECEIVER.failure(str(e), test_func_file_name)
170             finally:
171                 # do close all DUTs, if result is False then print DUT debug info
172                 env_inst.close(dut_debug=(not result))
173             # end case and output result
174             XUNIT_RECEIVER.end_case(test_func.__name__, time.time())
175             with open(xunit_file, "ab+") as f:
176                 f.write(xunitgen.toxml(XUNIT_RECEIVER.results(),
177                                        XUNIT_DEFAULT_TEST_SUITE))
178
179             if result:
180                 Utility.console_log("Test Succeed: " + test_func.__name__, color="green")
181             else:
182                 Utility.console_log(("Test Fail: " + test_func.__name__), color="red")
183             TestResult.set_result(result, test_func.__name__)
184             return result
185
186         handle_test.case_info = case_info
187         handle_test.test_method = True
188         return handle_test
189     return test