summaryrefslogtreecommitdiff
path: root/scripts/code_cov_gather_on_test
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@kernel.org>2022-04-14 14:24:51 +0200
committerPetri Latvala <petri.latvala@intel.com>2022-04-14 18:19:39 +0300
commitce05f2d4d34b2f4b506ffce04b34b9d242b3c4cc (patch)
tree1198745725fb26573d04f53fd581429360b32f0f /scripts/code_cov_gather_on_test
parenta3885810ccc0ce9e6552a20c910a0a322eca466c (diff)
scripts/code_cov*: remove the extensions from them
As those scripts will be installed and executed from the PATH, remove the extensions from them, in order to make it more elegant when installed on distros. Reviewed-by: Petri Latvala <petri.latvala@intel.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org>
Diffstat (limited to 'scripts/code_cov_gather_on_test')
-rwxr-xr-xscripts/code_cov_gather_on_test91
1 files changed, 91 insertions, 0 deletions
diff --git a/scripts/code_cov_gather_on_test b/scripts/code_cov_gather_on_test
new file mode 100755
index 00000000..b4356aa1
--- /dev/null
+++ b/scripts/code_cov_gather_on_test
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0 OR MIT
+#
+# Copyright (C) 2022 Intel Corporation
+#
+# gather_on_test.py
+#
+# by Tomi Sarvela <tomi.p.sarvela@intel.com>
+#
+# Faster implementation for linux kernel GCOV data collection
+# Command line compatible with original gather_on_test.sh
+#
+# Refs:
+# https://www.kernel.org/doc/html/latest/dev-tools/gcov.html
+#
+import argparse
+import errno
+import io
+import os
+import sys
+import tarfile
+
+def parse_args() -> argparse.Namespace:
+ '''Command line arguments'''
+ ap = argparse.ArgumentParser(description="Gather Linux kernel GCOV data")
+ ap.add_argument('output',
+ help="Output file name (.tar.gz will be added)")
+ ap.add_argument('--gcov', default='/sys/kernel/debug/gcov',
+ help="GCOV directory, default: /sys/kernel/debug/gcov")
+ return ap.parse_args()
+
+def tar_add_link(tar:tarfile.TarFile, filename:str):
+ '''Add filename as symlink to tarfile'''
+ info = tarfile.TarInfo(filename)
+ if info.name[0] == '/': info.name = info.name[1:]
+ info.type = tarfile.SYMTYPE
+ info.linkname = os.readlink(filename)
+ tar.addfile(info)
+
+def tar_add_file(tar:tarfile.TarFile, filename:str):
+ '''Add filename to tarfile, file size expected to be invalid'''
+ try:
+ with open(filename, "rb") as fp:
+ data = fp.read() # big gulp
+ except OSError as e:
+ print(f"ERROR: {filename}: {e}", file=sys.stderr)
+ return
+ info = tarfile.TarInfo(filename)
+ if info.name[0] == '/': info.name = info.name[1:]
+ info.size = len(data)
+ tar.addfile(info, io.BytesIO(data))
+
+def tar_add_tree(tar:tarfile.TarFile, tree:str):
+ '''Add gcov files in directory tree to tar'''
+ # FIXME: should dirs be added to tar for compatibility?
+ for root, _, files in os.walk(tree, followlinks=False):
+ for file in files:
+ filepath = os.path.join(root, file)
+ if file.endswith('.gcda'): tar_add_file(tar, filepath)
+ if file.endswith('.gcno'): tar_add_link(tar, filepath)
+
+def main() -> int:
+ '''MAIN'''
+ if not os.path.isdir(args.gcov):
+ print(f"ERROR: [Errno {errno.ENOTDIR}] {os.strerror(errno.ENOTDIR)}: '{args.gcov}'",
+ file=sys.stderr)
+ return errno.ENOTDIR
+ if args.output == '-':
+ # reopen stdout as bytes for tarfile
+ fp = os.fdopen(sys.stdout.fileno(), "wb", closefd=False)
+ else:
+ if not args.output.endswith('.tgz') and \
+ not args.output.endswith('.tar.gz'):
+ args.output+='.tar.gz'
+ try:
+ fp = open(args.output, 'wb')
+ except OSError as e:
+ print(f"ERROR: {e}", file=sys.stderr)
+ return e.errno
+ with tarfile.open(fileobj=fp, mode='w:gz') as tar:
+ tar_add_tree(tar, args.gcov)
+ fp.close()
+ return 0
+
+if __name__ == '__main__':
+ try:
+ args = parse_args()
+ sys.exit(main())
+ except KeyboardInterrupt:
+ print("Interrupted", file=sys.stderr)
+ sys.exit(errno.EINTR)