[gnome-control-center/wip/benzea/ci-network: 15/17] tests: Add helper for glib based test binaries



commit 7630bf963e7e29faddc178f9c7ec9b93d6669249
Author: Benjamin Berg <bberg redhat com>
Date:   Fri Apr 6 17:01:29 2018 +0200

    tests: Add helper for glib based test binaries
    
    This makes running glib based tests inside a dbusmock environment easier
    and more beautiful (i.e. output is supressed unless an error occurs).
    
    This helper has been submitted for inclusion in dbusmock. If it cannot$
    live there in some form, then we should try to find a home in the GNOME$
    project for it.$

 tests/shared/gtest.py | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)
---
diff --git a/tests/shared/gtest.py b/tests/shared/gtest.py
new file mode 100644
index 000000000..bb7130daf
--- /dev/null
+++ b/tests/shared/gtest.py
@@ -0,0 +1,113 @@
+#!/usr/bin/python3
+# Copyright © 2018 Red Hat, Inc
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# Authors: Benjamin Berg <bberg redhat com>
+
+import os
+import sys
+import subprocess
+import functools
+
+class _GTestSingleProp(object):
+    """Property which creates a bound method for calling the specified test."""
+    def __init__(self, test):
+        self.test = test
+
+    @staticmethod
+    def __func(self, test):
+        self._gtest_single(test)
+
+    def __get__(self, obj, cls):
+        bound_method = self.__func.__get__(obj, cls)
+        partial_method = functools.partial(bound_method, self.test)
+        partial_method.__doc__ = bound_method.__doc__
+
+        return partial_method
+
+
+class _GTestMeta(type):
+    def __new__(cls, name, bases, namespace, **kwds):
+        result = type.__new__(cls, name, bases, dict(namespace))
+
+        if result.g_test_exe is not None:
+            try:
+                _GTestMeta.make_tests(result.g_test_exe, result)
+            except Exception as e:
+                print('')
+                print(e)
+                print('Error generating separate test funcs, will call binary once.')
+                result.test_all = result._gtest_all
+
+        return result
+
+    @staticmethod
+    def make_tests(exe, result):
+        env = os.environ.copy()
+        env['G_MESSAGES_DEBUG'] = ''
+        test = subprocess.Popen([exe, '-l'], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env)
+        stdout, stderr = test.communicate()
+
+        if test.returncode != 0:
+            raise AssertionError('Execution of GTest executable to query the tests returned non-zero exit 
code!')
+
+        stdout = stdout.decode('utf-8')
+
+        for i, test in enumerate(stdout.split('\n')):
+            if not test:
+                continue
+
+            # Number it and make sure the function name is prefixed with 'test'.
+            # Keep the rest as is, we don't care about the fact that the function
+            # names cannot be typed in.
+            name = 'test_%03d_' % (i + 1) + test
+            setattr(result, name, _GTestSingleProp(test))
+
+
+class GTest(metaclass = _GTestMeta):
+    """Helper class to run GLib test. A test function will be created for each
+    test from the executable.
+
+    Use by using this class as a mixin and setting g_test_exe to an appropriate
+    value.
+    """
+
+    #: The GTest based executable
+    g_test_exe = None
+    #: Timeout when running a single test
+    g_test_single_timeout = None
+    #: Timeout when running all tests in one go
+    g_test_all_timeout = None
+
+    def _gtest_single(self, test):
+        assert(test)
+        p = subprocess.Popen([self.g_test_exe, '-q', '-p', test], stdout=subprocess.PIPE, 
stderr=subprocess.STDOUT)
+        try:
+            stdout, stderr = p.communicate(timeout=self.g_test_single_timeout)
+        except subprocess.TimeoutExpired:
+            p.kill()
+            stdout, stderr = p.communicate()
+            stdout += b'\n\nTest was aborted due to timeout'
+
+        try:
+            stdout = stdout.decode('utf-8')
+        except UnicodeDecodeError:
+            pass
+
+        if p.returncode != 0:
+            self.fail(stdout)
+
+    def _gtest_all(self):
+        subprocess.check_call([self.g_test_exe], timeout=self.g_test_all_timeout)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]