[oe-commits] [openembedded-core] 06/28: oeqa/core/threaded: Enable support to use the main thread

git at git.openembedded.org git at git.openembedded.org
Thu Jul 20 09:44:26 UTC 2017


This is an automated email from the git hooks/post-receive script.

rpurdie pushed a commit to branch master-next
in repository openembedded-core.

commit 721ce166f2fb2bd2b2e25b8031709bd208b1c4f1
Author: Aníbal Limón <anibal.limon at linux.intel.com>
AuthorDate: Mon Jun 12 16:45:34 2017 -0500

    oeqa/core/threaded: Enable support to use the main thread
    
    Some test cases needs to be executed by the main thread for
    several resons, this implmentation enables usage of the main
    thread to execute suites.
    
    The rules are if some test case request by test class attr
    _main_thread it will be executed, if no tests are scheduled
    to be executed into the main thread the algorithm with take
    the first suite in the pool, finallay this will avoid
    thread usage if only one suite needs to be executed.
    
    Signed-off-by: Aníbal Limón <anibal.limon at linux.intel.com>
---
 meta/lib/oeqa/core/threaded.py | 104 ++++++++++++++++++++++++++++++++---------
 1 file changed, 83 insertions(+), 21 deletions(-)

diff --git a/meta/lib/oeqa/core/threaded.py b/meta/lib/oeqa/core/threaded.py
index 2cafe03..34217f1 100644
--- a/meta/lib/oeqa/core/threaded.py
+++ b/meta/lib/oeqa/core/threaded.py
@@ -27,9 +27,42 @@ class OETestLoaderThreaded(OETestLoader):
             self.process_num = min(multiprocessing.cpu_count(),
                     len(suite._tests))
 
-        suites = []
-        for _ in range(self.process_num):
-            suites.append(self.suiteClass())
+        suites = {}
+        suites['main'] = self.suiteClass()
+        suites['pool'] = []
+        for _ in range(self.process_num - 1):
+            suites['pool'].append(self.suiteClass())
+
+        def _add_to_main_thread(main_suite, case, depends):
+            """
+                Some test cases needs to be run into the main
+                thread for several resons.
+
+                A test case that needs to run in the main thread
+                can be for specific set via test class _main_thread
+                attr or because is on the same module or for a dependency
+                reason.
+            """
+
+            if hasattr(case.__class__, '_main_thread') and \
+                    case.__class__._main_thread or \
+                    self.process_num == 1:
+                main_suite.addTest(case)
+                return True
+
+            for c in main_suite._tests:
+                if case.__module__ == c.__module__:
+                    main_suite.addTest(case)
+                    return True
+
+            if case.id() in depends:
+                case_depends = depends[case.id()]
+                for c in main_suite._tests:
+                    if c.id() in case_depends:
+                        main_suite.addTest(case)
+                        return True
+
+            return False
 
         def _search_for_module_idx(suites, case):
             """
@@ -37,8 +70,7 @@ class OETestLoaderThreaded(OETestLoader):
                 in the same thread because PyUnit keeps track
                 of setUp{Module, Class,} and tearDown{Module, Class,}.
             """
-
-            for idx in range(self.process_num):
+            for idx in range(self.process_num - 1):
                 suite = suites[idx]
                 for c in suite._tests:
                     if case.__module__ == c.__module__:
@@ -53,7 +85,7 @@ class OETestLoaderThreaded(OETestLoader):
                 of dependant test to figure out if skip or not.
             """
 
-            for idx in range(self.process_num):
+            for idx in range(self.process_num - 1):
                 suite = suites[idx]
 
                 for case in suite._tests:
@@ -62,6 +94,11 @@ class OETestLoaderThreaded(OETestLoader):
             return -1
 
         def _get_best_idx(suites):
+            """
+                The best index is selected to the suite that has
+                minor test cases to run.
+            """
+
             sizes = [len(suite._tests) for suite in suites]
             return sizes.index(min(sizes))
 
@@ -71,27 +108,35 @@ class OETestLoaderThreaded(OETestLoader):
                 if isinstance(case, TestSuite):
                     _fill_suites(case)
                 else:
-                    idx = _search_for_module_idx(suites, case)
-
                     depends = {}
                     if 'depends' in self.tc._registry:
                         depends = self.tc._registry['depends']
 
+                    if _add_to_main_thread(suites['main'], case, depends):
+                        continue
+
+                    # Get the best index in the suite pool to add the case
+                    idx = _search_for_module_idx(suites['pool'], case)
                     if idx == -1 and case.id() in depends:
                         case_depends = depends[case.id()] 
-                        idx = _search_for_depend_idx(suites, case_depends)
-
+                        idx = _search_for_depend_idx(suites['pool'], case_depends)
                     if idx == -1:
-                        idx = _get_best_idx(suites)
+                        idx = _get_best_idx(suites['pool'])
+                    suites['pool'][idx].addTest(case)
 
-                    suites[idx].addTest(case)
         _fill_suites(suite)
 
-        suites_tmp = suites
-        suites = []
+        # clean suites in pool without test cases
+        suites_tmp = suites['pool']
+        suites['pool'] = []
         for suite in suites_tmp:
             if len(suite._tests) > 0:
-                suites.append(suite)
+                suites['pool'].append(suite)
+
+        # if the main suite doesn't have test cases
+        # use the first element of the suites pool
+        if not len(suites['main']._tests):
+            suites['main'] = suites['pool'].pop(0)
 
         return suites
 
@@ -251,16 +296,33 @@ class OETestRunnerThreaded(OETestRunner):
     def run(self, suites):
         result = OETestResultThreaded(self.tc)
 
-        pool = _ThreadedPool(len(suites), len(suites), stream=self.stream,
-                result=result)
-        for s in suites:
-            pool.add_task(super(OETestRunnerThreaded, self).run, s)
-        pool.start()
-        pool.wait_completion()
+        pool = None
+        if suites['pool']:
+            thread_no = len(suites['pool'])
+            pool = _ThreadedPool(thread_no, thread_no, stream=self.stream,
+                    result=result)
+            for s in suites['pool']:
+                pool.add_task(super(OETestRunnerThreaded, self).run, s)
+            pool.start()
+
+        run_start_time = time.time()
+        rc = super(OETestRunnerThreaded, self).run(suites['main'])
+        run_end_time = time.time()
+        result.addResult(rc, run_start_time, run_end_time)
+        self.stream.finish()
+
+        if pool:
+            pool.wait_completion()
         result._fill_tc_results()
 
         return result
 
+    def list_tests(self, suite, display_type):
+        suite['pool'].insert(0, suite['main'])
+
+        return super(OETestRunnerThreaded, self).list_tests(
+                suite['pool'], display_type)
+
 class OETestContextThreaded(OETestContext):
     loaderClass = OETestLoaderThreaded
     runnerClass = OETestRunnerThreaded

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Openembedded-commits mailing list