aboutsummaryrefslogtreecommitdiffstats
path: root/test/tools/dump_coveralls.py
diff options
context:
space:
mode:
authorAnton Yuzhaninov <citrin+git@citrin.ru>2018-10-20 04:15:40 -0400
committerVsevolod Stakhov <vsevolod@highsecure.ru>2018-10-20 09:15:40 +0100
commit97a9de385402020d3add12517c7bccae93af593b (patch)
treeff53c36cd794f85f2159cbea19ed3bd7a1466583 /test/tools/dump_coveralls.py
parent97662a53f4dce272df30dac9b6aa4fc4013b0fc4 (diff)
downloadrspamd-97a9de385402020d3add12517c7bccae93af593b.tar.gz
rspamd-97a9de385402020d3add12517c7bccae93af593b.zip
Fix coverage (#2603)
* Add utility to prepare C coverage for upload to coveralls.io It turned out that it is more easy to write own script then debug and fix coveralls utility (https://github.com/eddyxu/cpp-coveralls). gcov-coveralls.py can be used as a replacement for coveralls. * Save coverage data from .gcda files only once Coverage data in .gcda files is merged after each binary invocation, so we can run all test and then gather coverage data. If we dump them two times execution counts will be more then they be. * Switch from coveralls (cpp-coveralls) to own script Problem with coveralls was, that coverage for source files outside build directory was not added to the report. * Add tool to dump info from json for coveralls.io * Add debug * Fix: don't die if there is no service_job_id in json * Debug * Fix dump_coveralls.py * Rename to gcov_coveralls.py (s/-/_/) For most files in this repo '_' is used as separator. * Don't add source code to coveralls JSON According to https://docs.coveralls.io/api-introduction Coverals don't need source code, only MD5 digest to tracks changes. Anyway source code is already added by luacov-coveralls and source_digest is added by cpp-coveralls and gcov_coveralls.py Both options seems to work for now. * Provide path to source directory to merge_coveralls.py merge_coveralls.py has code to filter files and remove prefixes. When --root points to source directory merge_coveralls.py can strip prefix from absolute path in JSONs generated by luacov-coveralls. * Style Don't add parameters with default values. * Make --output optional It useful mainly for debugging. We can send report without saving it. * Log CI_COMMIT_AUTHOR env var It is not clear from drone.io source how CI_COMMIT_AUTHOR variable is set. Log it to see what it means. * Move merge_coveralls.py to test/tools This script is used not only for funcional test coverage, but for rspamd-test coverage too. * Remove debug * Style Use more compact formatting. * Write comment about parallel tests running [SKIP CI] Document why running tests in parallel may be bad idea (but still do so). * Fix typo [SKIP CI]
Diffstat (limited to 'test/tools/dump_coveralls.py')
-rwxr-xr-xtest/tools/dump_coveralls.py66
1 files changed, 66 insertions, 0 deletions
diff --git a/test/tools/dump_coveralls.py b/test/tools/dump_coveralls.py
new file mode 100755
index 000000000..c453d0511
--- /dev/null
+++ b/test/tools/dump_coveralls.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python3
+
+# Small tool to dump JSON payload for coveralls.io API
+
+import json
+from operator import itemgetter
+import os
+import sys
+
+
+def warn(*args, **kwargs):
+ print(*args, file=sys.stderr, **kwargs)
+
+
+def dump_file(json_file):
+ """Dumps coveralls.io API payload stored in json_file
+ Returns: 0 if successful, 1 otherwise
+ """
+ try:
+ with open(json_file, encoding='utf8') as f:
+ data = json.load(f)
+ except OSError as err:
+ warn(err)
+ return os.EX_DATAERR
+ except json.decoder.JSONDecodeError:
+ warn("{}: json parsing error".format(json_file))
+ return 1
+
+ if 'source_files' not in data:
+ warn("{}: no source_files, not a coveralls.io payload?".format(json_file))
+ return 1
+
+ print("{} ({} soource files)".format(json_file, len(data['source_files'])))
+
+ for src_file in sorted(data['source_files'], key=itemgetter('name')):
+ covered_lines = not_skipped_lines = 0
+ for cnt in src_file['coverage']:
+ if cnt is None:
+ continue
+ not_skipped_lines += 1
+ if cnt > 0:
+ covered_lines += 1
+ if not_skipped_lines > 0:
+ coverage = "{:.0%}".format(covered_lines / not_skipped_lines)
+ else:
+ coverage = 'N/A'
+
+ print("\t{:>3} {}".format(coverage, src_file['name']))
+
+ return 0
+
+
+def main():
+ if (len(sys.argv) < 2):
+ warn("usage: {} file.json ...".format(sys.argv[0]))
+ return os.EX_USAGE
+
+ exit_status = 0
+ for f in sys.argv[1:]:
+ exit_status += dump_file(f)
+
+ return exit_status
+
+
+if __name__ == '__main__':
+ sys.exit(main())