An incomplete implementation with details to be worked out, but it
works! It makes our long tail tests take significantly less time. At
least when run on their own.
Example: ~25 seconds wall time to run test_multiprocessing_spawn and
test_concurrent_futures on a 12 thread machine for example.
`python -m test -r -j 20 test_multiprocessing_spawn test_concurrent_futures`
Known Issues to work out: result reporting and libregrtest accounting.
You see any sharded test "complete" multiple times and your total tests
run count goes higher than the total number of tests. 😂
Real caveat: This exposes ordering and concurrency weaknesses in some
tests like test_asyncio that'll need fixing.
Which tests get sharded is explicitly opt-in. Currently not in a
maintainable spot. How best to maintain that needs to be worked out,
but I expect we only ever have 10-20 test modules that we declare as
worth sharding.
This implementation is inspired by and with the unittest TestLoader bits
derived directly from the Apache 2.0 licensed
https://github.com/abseil/abseil-py/blob/v1.3.0/absl/testing/absltest.py#L2359
```
:~/oss/cpython (performance/test-sharding)$ ../b/python -m test -r -j 20
test_multiprocessing_spawn test_concurrent_futures
Using random seed 8555091
0:00:00 load avg: 0.98 Run tests in parallel using 20 child processes
0:00:08 load avg: 1.30 [1/2] test_multiprocessing_spawn passed
0:00:10 load avg: 1.68 [2/2] test_concurrent_futures passed
0:00:11 load avg: 1.68 [3/2] test_multiprocessing_spawn passed
0:00:12 load avg: 1.68 [4/2] test_multiprocessing_spawn passed
0:00:12 load avg: 1.68 [5/2] test_multiprocessing_spawn passed
0:00:14 load avg: 1.87 [6/2] test_multiprocessing_spawn passed
0:00:15 load avg: 1.87 [7/2] test_multiprocessing_spawn passed
0:00:16 load avg: 1.87 [8/2] test_concurrent_futures passed
0:00:16 load avg: 1.87 [9/2] test_multiprocessing_spawn passed
0:00:18 load avg: 1.87 [10/2] test_concurrent_futures passed
0:00:20 load avg: 1.72 [11/2] test_concurrent_futures passed
0:00:20 load avg: 1.72 [12/2] test_concurrent_futures passed
0:00:21 load avg: 1.72 [13/2] test_multiprocessing_spawn passed
0:00:21 load avg: 1.72 [14/2] test_concurrent_futures passed
0:00:22 load avg: 1.72 [15/2] test_concurrent_futures passed
0:00:25 load avg: 1.58 [16/2] test_concurrent_futures passed
== Tests result: SUCCESS ==
All 16 tests OK.
Total duration: 25.6 sec
Tests result: SUCCESS
```