]> granicus.if.org Git - esp-idf/commitdiff
tiny-test-fw: fix misc bugs:
authorHe Yin Ling <heyinling@espressif.com>
Tue, 16 Jan 2018 14:16:03 +0000 (22:16 +0800)
committerbot <bot@espressif.com>
Tue, 15 May 2018 03:29:31 +0000 (03:29 +0000)
1. configs are not functional
    * decorator will be executed when search case, need to set default config before search case.
2. fix DUT encode/decode errors
    * python3 serial don't support write string/unicode, need to convert to bytes first.
    * python2 string could failed to encode/decode non-acsii chars
3. fix bug that log folder not created
4. fix bug that test suite name is not correctly passed:
    * the keyward arg should be `test_suite_name` not `test_name`
5. fix bug that test stopped on failed case
6. fix DUT `read` don't return all data cache
    * `_DataCache.get_data` should first copy all data from queue to data cache and then return to user.
7. fix bug that `expect_all` failed even all expected item passed
8. optimize error info for expect
    * print pattern for regular expression when match failed
9. fix bug that set default config doesn't work

tools/tiny-test-fw/App.py
tools/tiny-test-fw/DUT.py
tools/tiny-test-fw/Env.py
tools/tiny-test-fw/EnvConfig.py
tools/tiny-test-fw/Runner.py
tools/tiny-test-fw/TinyFW.py
tools/tiny-test-fw/docs/index.rst
tools/tiny-test-fw/example.py

index 84e8716a171890d36aafd8dca89af8f85a71a767..1dbadf85afd041e297c1494870ce93831873bc93 100644 (file)
@@ -78,9 +78,12 @@ class BaseApp(object):
         if not test_suite_name:
             test_suite_name = os.path.splitext(os.path.basename(sys.modules['__main__'].__file__))[0]
         sdk_path = cls.get_sdk_path()
-        return os.path.join(sdk_path, "TEST_LOGS",
-                            test_suite_name +
-                            time.strftime("_%m%d_%H_%M_%S", time.localtime(LOG_FOLDER_TIMESTAMP)))
+        log_folder = os.path.join(sdk_path, "TEST_LOGS",
+                                  test_suite_name +
+                                  time.strftime("_%m%d_%H_%M_%S", time.localtime(LOG_FOLDER_TIMESTAMP)))
+        if not os.path.exists(log_folder):
+            os.makedirs(log_folder)
+        return log_folder
 
     def process_app_info(self):
         """
index 1cfd2c7d531872cf2ada018940ceaa2a816ec160..882afa1f99990a79711a4cea5bb530c02db2b6d3 100644 (file)
@@ -85,6 +85,14 @@ def _decode_data(data):
     return data
 
 
+def _pattern_to_string(pattern):
+    try:
+        ret = "RegEx: " + pattern.pattern
+    except AttributeError:
+        ret = pattern
+    return ret
+
+
 class _DataCache(_queue.Queue):
     """
     Data cache based on Queue. Allow users to process data cache based on bytes instead of Queue."
@@ -94,6 +102,21 @@ class _DataCache(_queue.Queue):
         _queue.Queue.__init__(self, maxsize=maxsize)
         self.data_cache = str()
 
+    def _move_from_queue_to_cache(self):
+        """
+        move all of the available data in the queue to cache
+
+        :return: True if moved any item from queue to data cache, else False
+        """
+        ret = False
+        while True:
+            try:
+                self.data_cache += _decode_data(self.get(0))
+                ret = True
+            except _queue.Empty:
+                break
+        return ret
+
     def get_data(self, timeout=0):
         """
         get a copy of data from cache.
@@ -105,12 +128,16 @@ class _DataCache(_queue.Queue):
         if timeout < 0:
             timeout = 0
 
-        try:
-            data = self.get(timeout=timeout)
-            self.data_cache += _decode_data(data)
-        except _queue.Empty:
-            # don't do anything when on update for cache
-            pass
+        ret = self._move_from_queue_to_cache()
+
+        if not ret:
+            # we only wait for new data if we can't provide a new data_cache
+            try:
+                data = self.get(timeout=timeout)
+                self.data_cache += _decode_data(data)
+            except _queue.Empty:
+                # don't do anything when on update for cache
+                pass
         return copy.deepcopy(self.data_cache)
 
     def flush(self, index=0xFFFFFFFF):
@@ -417,7 +444,7 @@ class BaseDUT(object):
             data = self.data_cache.get_data(time.time() + timeout - start_time)
 
         if ret is None:
-            raise ExpectTimeout(self.name + ": " + str(pattern))
+            raise ExpectTimeout(self.name + ": " + _pattern_to_string(pattern))
         return ret
 
     def _expect_multi(self, expect_all, expect_item_list, timeout):
@@ -457,12 +484,11 @@ class BaseDUT(object):
                     if expect_item["ret"] is not None:
                         # match succeed for one item
                         matched_expect_items.append(expect_item)
-                        break
 
             # if expect all, then all items need to be matched,
             # else only one item need to matched
             if expect_all:
-                match_succeed = (matched_expect_items == expect_items)
+                match_succeed = len(matched_expect_items) == len(expect_items)
             else:
                 match_succeed = True if matched_expect_items else False
 
@@ -482,7 +508,7 @@ class BaseDUT(object):
             # flush already matched data
             self.data_cache.flush(slice_index)
         else:
-            raise ExpectTimeout(self.name + ": " + str(expect_items))
+            raise ExpectTimeout(self.name + ": " + str([_pattern_to_string(x) for x in expect_items]))
 
     @_expect_lock
     def expect_any(self, *expect_items, **timeout):
index fa194d10c97f121084d5b757c914b1bafc8f878a..b623847edb6ba9998365c4b90c343abdd3bd50bd 100644 (file)
@@ -49,12 +49,12 @@ class Env(object):
                  dut=None,
                  env_tag=None,
                  env_config_file=None,
-                 test_name=None,
+                 test_suite_name=None,
                  **kwargs):
         self.app_cls = app
         self.default_dut_cls = dut
         self.config = EnvConfig.Config(env_config_file, env_tag)
-        self.log_path = self.app_cls.get_log_folder(test_name)
+        self.log_path = self.app_cls.get_log_folder(test_suite_name)
         if not os.path.exists(self.log_path):
             os.makedirs(self.log_path)
 
index 2ce28d811e3ff5055c24d58295dd78c2bfa06488..79de6bd3f896ac7288d879f6cde53862dcf8e916 100644 (file)
@@ -53,7 +53,7 @@ class Config(object):
         try:
             with open(config_file) as f:
                 configs = yaml.load(f)[env_name]
-        except (OSError, TypeError):
+        except (OSError, TypeError, IOError):
             configs = dict()
         return configs
 
index 0adf441fe0bf7e626f029275b097c86370a9eb11..70f60eb35412f241d75e3e41a1f3b26fa02c834e 100644 (file)
@@ -40,18 +40,22 @@ class Runner(threading.Thread):
     def __init__(self, test_case, case_config, env_config_file=None):
         super(Runner, self).__init__()
         self.setDaemon(True)
-        test_methods = SearchCases.Search.search_test_cases(test_case)
-        self.test_cases = CaseConfig.Parser.apply_config(test_methods, case_config)
-        self.test_result = True
         if case_config:
             test_suite_name = os.path.splitext(os.path.basename(case_config))[0]
         else:
             test_suite_name = "TestRunner"
         TinyFW.set_default_config(env_config_file=env_config_file, test_suite_name=test_suite_name)
+        test_methods = SearchCases.Search.search_test_cases(test_case)
+        self.test_cases = CaseConfig.Parser.apply_config(test_methods, case_config)
+        self.test_result = []
 
     def run(self):
         for case in self.test_cases:
-            self.test_result = self.test_result and case.run()
+            result = case.run()
+            self.test_result.append(result)
+    
+    def get_test_result(self):
+        return self.test_result and all(self.test_result)
 
 
 if __name__ == '__main__':
@@ -76,5 +80,5 @@ if __name__ == '__main__':
         except KeyboardInterrupt:
             print("exit by Ctrl-C")
             break
-    if not runner.test_result:
+    if not runner.get_test_result():
         sys.exit(1)
index 09b950c583a582e5ffe76ddcffc1ce43c7852d69..b227cf7aadc18f106fad4a3817c8522ede9efc39 100644 (file)
@@ -132,12 +132,6 @@ def test_method(**kwargs):
         case_info["name"] = test_func.__name__
         case_info.update(kwargs)
 
-        # create env instance
-        env_config = DefaultEnvConfig.get_default_config()
-        for key in kwargs:
-            if key in env_config:
-                env_config[key] = kwargs[key]
-
         @functools.wraps(test_func)
         def handle_test(extra_data=None, **overwrite):
             """
@@ -147,6 +141,12 @@ def test_method(**kwargs):
             :param overwrite: args that runner or main want to overwrite
             :return: None
             """
+            # create env instance
+            env_config = DefaultEnvConfig.get_default_config()
+            for key in kwargs:
+                if key in env_config:
+                    env_config[key] = kwargs[key]
+
             env_config.update(overwrite)
             env_inst = Env.Env(**env_config)
             # prepare for xunit test results
index bc3a3f5f82cbbc431c81cc2e0208b42357b1d0ec..b83254cb184a47868867efa455c3acf3b1f4b853 100644 (file)
@@ -69,7 +69,7 @@ Let's first check a simple simple::
 
 
     if __name__ == '__main__':
-        TinyFW.set_default_config(config_file="EnvConfigTemplate.yml")
+        TinyFW.set_default_config(env_config_file="EnvConfigTemplate.yml")
         test_examples_protocol_https_request()
 
 
index df1b25576e0fd04bcdf88f3c303ae4194ba5e4f5..324c90438340cf8615a742a2fd42b90d58a7bf16 100644 (file)
@@ -47,5 +47,5 @@ def test_examples_protocol_https_request(env, extra_data):
 
 
 if __name__ == '__main__':
-    TinyFW.set_default_config(config_file="EnvConfigTemplate.yml", dut=IDF.IDFDUT)
+    TinyFW.set_default_config(env_config_file="EnvConfigTemplate.yml", dut=IDF.IDFDUT)
     test_examples_protocol_https_request()