aboutsummaryrefslogtreecommitdiffstats
path: root/test/individual_coverage.py
diff options
context:
space:
mode:
authorThomas Kriechbaumer <thomas@kriechbaumer.name>2017-02-15 18:52:32 +0100
committerThomas Kriechbaumer <thomas@kriechbaumer.name>2017-02-16 11:43:45 +0100
commit6b22ca7a32252b5c5963704f6276eeac390a3622 (patch)
treed4436a3ec767bde9627518c94772eda32e3b8a5d /test/individual_coverage.py
parent337b1c9399e525a23dc188ef5df1667f109b108e (diff)
downloadmitmproxy-6b22ca7a32252b5c5963704f6276eeac390a3622.tar.gz
mitmproxy-6b22ca7a32252b5c5963704f6276eeac390a3622.tar.bz2
mitmproxy-6b22ca7a32252b5c5963704f6276eeac390a3622.zip
add individual-coverage check
Diffstat (limited to 'test/individual_coverage.py')
-rw-r--r--test/individual_coverage.py82
1 files changed, 82 insertions, 0 deletions
diff --git a/test/individual_coverage.py b/test/individual_coverage.py
new file mode 100644
index 00000000..35bcd27f
--- /dev/null
+++ b/test/individual_coverage.py
@@ -0,0 +1,82 @@
+import io
+import contextlib
+import os
+import sys
+import glob
+import multiprocessing
+import configparser
+import itertools
+import pytest
+
+
+def run_tests(src, test, fail):
+ stderr = io.StringIO()
+ stdout = io.StringIO()
+ with contextlib.redirect_stderr(stderr):
+ with contextlib.redirect_stdout(stdout):
+ e = pytest.main([
+ '-qq',
+ '--disable-pytest-warnings',
+ '--no-faulthandler',
+ '--cov', src.replace('.py', '').replace('/', '.'),
+ '--cov-fail-under', '100',
+ '--cov-report', 'term-missing:skip-covered',
+ test
+ ])
+
+ if e == 0:
+ if fail:
+ print("SUCCESS but should have FAILED:", src, "Please remove this file from setup.cfg tool:individual_coverage/exclude.")
+ e = 42
+ else:
+ print("SUCCESS:", src)
+ else:
+ if fail:
+ print("Ignoring fail:", src)
+ e = 0
+ else:
+ cov = [l for l in stdout.getvalue().split("\n") if (src in l) or ("was never imported" in l)]
+ if len(cov) == 1:
+ print("FAIL:", cov[0])
+ else:
+ print("FAIL:", src, test, stdout.getvalue(), stdout.getvalue())
+ print(stderr.getvalue())
+ print(stdout.getvalue())
+
+ sys.exit(e)
+
+
+def start_pytest(src, test, fail):
+ # run pytest in a new process, otherwise imports and modules might conflict
+ proc = multiprocessing.Process(target=run_tests, args=(src, test, fail))
+ proc.start()
+ proc.join()
+ return (src, test, proc.exitcode)
+
+
+def main():
+ c = configparser.ConfigParser()
+ c.read('setup.cfg')
+ fs = c['tool:individual_coverage']['exclude'].strip().split('\n')
+ no_individual_cov = [f.strip() for f in fs]
+
+ excluded = ['mitmproxy/contrib/', 'mitmproxy/test/', 'mitmproxy/tools/', 'mitmproxy/platform/']
+ src_files = glob.glob('mitmproxy/**/*.py', recursive=True) + glob.glob('pathod/**/*.py', recursive=True)
+ src_files = [f for f in src_files if os.path.basename(f) != '__init__.py']
+ src_files = [f for f in src_files if not any(os.path.normpath(p) in f for p in excluded)]
+
+ ps = []
+ for src in sorted(src_files):
+ test = os.path.join("test", os.path.dirname(src), "test_" + os.path.basename(src))
+ if os.path.isfile(test):
+ ps.append((src, test, src in no_individual_cov))
+
+ result = list(itertools.starmap(start_pytest, ps))
+
+ if any(e != 0 for _, _, e in result):
+ sys.exit(1)
+ pass
+
+
+if __name__ == '__main__':
+ main()