aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Victor Huesca <victor.huesca@bootlin.com>2019-08-04 16:21:42 +0200
committerGravatar Thomas Petazzoni <thomas.petazzoni@bootlin.com>2019-08-05 00:02:09 +0200
commite635836494d3d4607146b540cbcd0b3093fc8205 (patch)
tree5971f511a72888f75e70c1bbe065c1fe7471e242
parentbb5576db9b9cf06b5f2d2f9a888730503c730462 (diff)
downloadbuildroot-e635836494d3d4607146b540cbcd0b3093fc8205.tar.gz
buildroot-e635836494d3d4607146b540cbcd0b3093fc8205.tar.bz2
utils/getdeveloperlib.py: add runtime test parsing
This patch extends the Developer class so that it associates each developer with the runtime tests (in support/testing) is in responsible for, according to the DEVELOPERS file. The implementation relies on the unittest module to list all test cases and does some manual parsing of these test-case objects to get the actual list of test-cases per test-suite. A global variable is used to compute the list of unittest only once. This feature will allow to use the getdeveloperlib module to find which developer is responsible for which runtime test, and send e-mail notifications of runtime tests failures. Signed-off-by: Victor Huesca <victor.huesca@bootlin.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
-rw-r--r--utils/getdeveloperlib.py56
1 files changed, 56 insertions, 0 deletions
diff --git a/utils/getdeveloperlib.py b/utils/getdeveloperlib.py
index 81eae7ee9b..c0eff7df29 100644
--- a/utils/getdeveloperlib.py
+++ b/utils/getdeveloperlib.py
@@ -4,6 +4,7 @@ import re
import glob
import subprocess
import sys
+import unittest
#
# Patch parsing functions
@@ -78,6 +79,35 @@ def analyze_patches(patches):
return (allfiles, allinfras)
+#
+# Unit-test parsing functions
+#
+
+def get_all_test_cases(suite):
+ """Generate all test-cases from a given test-suite.
+ :return: (test.module, test.name)"""
+ if issubclass(type(suite), unittest.TestSuite):
+ for test in suite:
+ for res in get_all_test_cases(test):
+ yield res
+ else:
+ yield (suite.__module__, suite.__class__.__name__)
+
+
+def list_unittests(path):
+ """Use the unittest module to retreive all test cases from a given
+ directory"""
+ loader = unittest.TestLoader()
+ suite = loader.discover(path)
+ tests = {}
+ for module, test in get_all_test_cases(suite):
+ module_path = os.path.join(path, *module.split('.'))
+ tests.setdefault(module_path, []).append('%s.%s' % (module, test))
+ return tests
+
+
+unittests = {}
+
#
# DEVELOPERS file parsing functions
#
@@ -89,6 +119,7 @@ class Developer:
self.packages = parse_developer_packages(files)
self.architectures = parse_developer_architectures(files)
self.infras = parse_developer_infras(files)
+ self.runtime_tests = parse_developer_runtime_tests(files)
def hasfile(self, f):
f = os.path.abspath(f)
@@ -108,6 +139,8 @@ class Developer:
things.append('{} archs'.format(len(self.architectures)))
if len(self.infras):
things.append('{} infras'.format(len(self.infras)))
+ if len(self.runtime_tests):
+ things.append('{} tests'.format(len(self.runtime_tests)))
if things:
return 'Developer <{} ({})>'.format(name, ', '.join(things))
else:
@@ -170,12 +203,35 @@ def parse_developer_infras(fnames):
return infras
+def parse_developer_runtime_tests(fnames):
+ """Given a list of file names, returns the runtime tests
+ corresponding to the file."""
+ all_files = []
+ # List all files recursively
+ for fname in fnames:
+ if os.path.isdir(fname):
+ for root, _dirs, files in os.walk(fname):
+ all_files += [os.path.join(root, f) for f in files]
+ else:
+ all_files.append(fname)
+
+ # Get all runtime tests
+ runtimes = set()
+ for f in all_files:
+ name = os.path.splitext(f)[0]
+ if name in unittests:
+ runtimes |= set(unittests[name])
+ return runtimes
+
+
def parse_developers(basepath=None):
"""Parse the DEVELOPERS file and return a list of Developer objects."""
developers = []
linen = 0
if basepath is None:
basepath = os.getcwd()
+ global unittests
+ unittests = list_unittests(os.path.join(basepath, 'support/testing'))
with open(os.path.join(basepath, "DEVELOPERS"), "r") as f:
files = []
name = None