annotate tests/sitecustomize.py @ 24505:031947baf4d0

run-tests: collect aggregate code coverage Before this patch, every Python process during a code coverage run was writing coverage data to the same file. I'm not sure if the coverage package even tries to obtain a lock on the file. But what I do know is there was some last write wins leading to loss of code coverage data, at least with -j > 1. This patch changes the code coverage mechanism to be multiple process safe. The mechanism for initializing code coverage via sitecustomize.py has been tweaked so each Python process will produce a separate coverage data file on disk. Unless two processes generate the same random value, there are no race conditions writing to the same file. At the end of the test run, we combine all written files into an aggregate report. On my machine, running the full test suite produces a little over 20,000 coverage files consuming ~350 MB. As you can imagine, it takes several seconds to load and merge these coverage files. But when it is done, you have an accurate picture of the aggregate code coverage for the entire test suite, which is ~60% line coverage.
author Gregory Szorc <gregory.szorc@gmail.com>
date Sat, 28 Mar 2015 00:47:58 -0700
parents 0b21ae0a2366
children b12bda49c3e3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
24505
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
1 import os
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
2
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
3 if os.environ.get('COVERAGE_PROCESS_START'):
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
4 try:
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
5 import coverage
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
6 import random
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
7
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
8 # uuid is better, but not available in Python 2.4.
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
9 covpath = os.path.join(os.environ['COVERAGE_DIR'],
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
10 'cov.%s' % random.randrange(0, 1000000000000))
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
11 cov = coverage.coverage(data_file=covpath, auto_data=True)
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
12 cov._warn_no_data = False
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
13 cov._warn_unimported_source = False
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
14 cov.start()
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
15 except ImportError:
031947baf4d0 run-tests: collect aggregate code coverage
Gregory Szorc <gregory.szorc@gmail.com>
parents: 14971
diff changeset
16 pass