Skip to content

CI Uses pytest-xdist to parallelize tests #13041

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 93 commits into from
Jun 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
4a60403
TST: Adds pytest-xdist support
thomasjpfan Jan 22, 2019
38f47ab
TST: Add PYTHONHASHSEED to command
thomasjpfan Jan 22, 2019
f42dae4
TST: Fix
thomasjpfan Jan 22, 2019
75693c4
TST: Order pytest parameters
thomasjpfan Jan 22, 2019
b3fef51
TST: Fix for xdist
thomasjpfan Jan 23, 2019
360daa0
TST: Adjusts dicts for 3.5 ordering
thomasjpfan Jan 23, 2019
765d11b
TST: Fix
thomasjpfan Jan 23, 2019
1b4a82e
TST: Fix
thomasjpfan Jan 23, 2019
271ec28
TST: Fix
thomasjpfan Jan 23, 2019
919a451
TST: Fix
thomasjpfan Jan 23, 2019
4294882
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Jan 23, 2019
7c573e8
ENH: Faster
thomasjpfan Jan 23, 2019
8b68c73
TST: Fix
thomasjpfan Jan 24, 2019
4e5e32c
TST: Optimize
thomasjpfan Jan 24, 2019
5cf9558
TST: Fix
thomasjpfan Jan 24, 2019
a5311f6
RFC: Minor
thomasjpfan Jan 24, 2019
4badaa9
RFC: Add commands for parallel pytest
thomasjpfan Jan 24, 2019
4957cb0
RFC
thomasjpfan Jan 24, 2019
3b72e69
Trigger LGTM
thomasjpfan Jan 24, 2019
36d97bb
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Jan 26, 2019
70a4077
RFC: Less diffs
thomasjpfan Jan 26, 2019
e4c49c5
RFC: Less diffs
thomasjpfan Jan 26, 2019
0b21946
RFC: Uses loadscope algorithm
thomasjpfan Jan 26, 2019
b32f961
REV
thomasjpfan Jan 26, 2019
65715b3
RFC: Adjust name
thomasjpfan Jan 26, 2019
d6a96e4
RFC: Moves ENet to use a mixin as well
thomasjpfan Jan 26, 2019
bb65b3e
REV: Turns off pytest-xdist on CI
thomasjpfan Jan 26, 2019
d98bf54
BUG: Runs file on the same worker
thomasjpfan Jan 26, 2019
f749e84
BUG: Uses loadscope
thomasjpfan Jan 26, 2019
ca5a880
BUG: Uses pip to install
thomasjpfan Jan 26, 2019
1e0d96b
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Feb 6, 2019
e002e27
REV
thomasjpfan Feb 6, 2019
6b964da
RFC Uses popen option
thomasjpfan Feb 7, 2019
15222ab
TST Fix
thomasjpfan Feb 13, 2019
bcc68b1
TST Fix
thomasjpfan Feb 13, 2019
1c06910
TST Fix
thomasjpfan Feb 13, 2019
969fb4e
RFC Removes pytest-xdist from travis
thomasjpfan Feb 14, 2019
fff1fda
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Feb 14, 2019
9f7992f
BUG bash fix
thomasjpfan Feb 14, 2019
0d9d945
TST Uses eval
thomasjpfan Feb 14, 2019
4bfb9b9
TST No quotes
thomasjpfan Feb 14, 2019
4dc91ec
TST: Tests for collect-only order
thomasjpfan Feb 15, 2019
448d2e1
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Feb 15, 2019
624b25f
RFC Minizes diffs
thomasjpfan Feb 15, 2019
1d4d807
TST Runs collect test 3 times
thomasjpfan Feb 16, 2019
57070e7
RFC Better name for test
thomasjpfan Feb 16, 2019
7ad5858
DOC Adds term to column_transformer
thomasjpfan Mar 1, 2019
fac786d
DOC Adjusts sphinx resolution
thomasjpfan Mar 1, 2019
4abc3f7
Merge remote-tracking branch 'upstream/master' into pytest-xdist-rapid
thomasjpfan Mar 6, 2019
b4b5a2f
REV Less diffs
thomasjpfan Mar 6, 2019
9ab7c5d
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Mar 6, 2019
c4eb6e7
Hack coordinate descent
thomasjpfan Mar 6, 2019
692d532
Merge branch 'pytest-xdist' into pytest-xdist-rapid
thomasjpfan Mar 6, 2019
78b4985
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Mar 7, 2019
d656b1e
TST Ignore Depreication
thomasjpfan Mar 7, 2019
5e686f7
TST Debug check versions
thomasjpfan Mar 7, 2019
6532e4e
TST Removes virtualenv
thomasjpfan Mar 7, 2019
d4b0529
TST Removes virtualenv
thomasjpfan Mar 7, 2019
70ec9cd
TST Removes virtualenv
thomasjpfan Mar 7, 2019
376fd62
TST Uses python version 3.5 to azure
thomasjpfan Mar 7, 2019
3289689
REV
thomasjpfan Mar 7, 2019
6534ec6
REV Do not use pytest-xdist for ubuntu
thomasjpfan Mar 7, 2019
fe39d43
ENH Adds pytest-xdist
thomasjpfan Mar 7, 2019
2a11e7a
Merge branch 'pytest-xdist-rapid' into pytest-xdist
thomasjpfan Mar 7, 2019
85052e8
TST Fix logic
thomasjpfan Mar 7, 2019
97f71b2
REV Only do collect test on pylatest_conda
thomasjpfan Mar 8, 2019
a21e544
REV Less diffs
thomasjpfan Mar 8, 2019
7a8210d
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Mar 10, 2019
69f4880
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Mar 11, 2019
94efac8
REV Less diffs
thomasjpfan Mar 11, 2019
ceb1a99
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Mar 11, 2019
950ae7c
REV Less diffs
thomasjpfan Mar 11, 2019
b90043b
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Mar 12, 2019
64b333c
REV Remoes SUPERVISED_UNSUPERVISED_METRICS
thomasjpfan Mar 12, 2019
c92b7aa
TST Enable pytest-xdist for one azure instance
thomasjpfan Mar 27, 2019
320a194
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Mar 27, 2019
b03dac1
CLN Moves block up
thomasjpfan Mar 27, 2019
20e6429
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan May 31, 2019
f5a4b74
ENH Adds pytest-xdist to windows
thomasjpfan Jun 4, 2019
a9d0259
ENH Fixes lgtm
thomasjpfan Jun 4, 2019
fcb3c92
ENH Fixes lgtm
thomasjpfan Jun 4, 2019
085805b
ENH Fixes lgtm
thomasjpfan Jun 4, 2019
fd090b7
ENH Fixes lgtm
thomasjpfan Jun 4, 2019
11588a3
ENH Fixes lgtm
thomasjpfan Jun 4, 2019
014b61c
ENH Fixes lgtm
thomasjpfan Jun 4, 2019
59950e3
ENH Fixes lgtm
thomasjpfan Jun 4, 2019
c6230a9
ENH Fixes lgtm
thomasjpfan Jun 4, 2019
d8dd551
ENH Fixes lgtm
thomasjpfan Jun 4, 2019
d1150aa
REV lgtm
thomasjpfan Jun 4, 2019
48a6190
Merge remote-tracking branch 'upstream/master' into pytest-xdist
thomasjpfan Jun 12, 2019
46c6459
REV Less diffs
thomasjpfan Jun 12, 2019
2f9f265
REV Less diffs
thomasjpfan Jun 13, 2019
01743fc
REV Less diffs
thomasjpfan Jun 13, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,15 @@ test-doc:
ifeq ($(BITS),64)
$(PYTEST) $(shell find doc -name '*.rst' | sort)
endif
test-code-parallel: in
$(PYTEST) -n auto --showlocals -v sklearn --durations=20
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a comment that this requires pytest-xdist. Else pytest fails with

pytest: error: unrecognized arguments: -n


test-coverage:
rm -rf coverage .coverage
$(PYTEST) sklearn --showlocals -v --cov=sklearn --cov-report=html:coverage
test-coverage-parallel:
rm -rf coverage .coverage .coverage.*
$(PYTEST) sklearn -n auto --showlocals -v --cov=sklearn --cov-report=html:coverage

test: test-code test-sphinxext test-doc

Expand Down
2 changes: 1 addition & 1 deletion build_tools/azure/install.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ IF "%PYTHON_ARCH%"=="64" (
call deactivate
@rem Clean up any left-over from a previous build
conda remove --all -q -y -n %VIRTUALENV%
conda create -n %VIRTUALENV% -q -y python=%PYTHON_VERSION% numpy scipy cython matplotlib pytest wheel pillow joblib
conda create -n %VIRTUALENV% -q -y python=%PYTHON_VERSION% numpy scipy cython matplotlib pytest wheel pillow joblib pytest-xdist

call activate %VIRTUALENV%
) else (
Expand Down
4 changes: 4 additions & 0 deletions build_tools/azure/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ if [[ "$DISTRIB" == "conda" ]]; then
TO_INSTALL="$TO_INSTALL matplotlib=$MATPLOTLIB_VERSION"
fi

if [[ "$PYTHON_VERSION" == "*" ]]; then
TO_INSTALL="$TO_INSTALL pytest-xdist"
fi

make_conda $TO_INSTALL

elif [[ "$DISTRIB" == "ubuntu" ]]; then
Expand Down
3 changes: 2 additions & 1 deletion build_tools/azure/test_script.cmd
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
@echo on

@rem Only 64 bit uses conda
@rem Only 64 bit uses conda and uses a python newer than 3.5
IF "%PYTHON_ARCH%"=="64" (
call activate %VIRTUALENV%
set PYTEST_ARGS=%PYTEST_ARGS% -n2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Briefly describe -n2 for future us?

)

mkdir %TMP_FOLDER%
Expand Down
4 changes: 4 additions & 0 deletions build_tools/azure/test_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ if [[ -n "$CHECK_WARNINGS" ]]; then
TEST_CMD="$TEST_CMD -Werror::DeprecationWarning -Werror::FutureWarning"
fi

if [[ "$PYTHON_VERSION" == "*" ]]; then
TEST_CMD="$TEST_CMD -n2"
fi

mkdir -p $TEST_DIR
cp setup.cfg $TEST_DIR
cd $TEST_DIR
Expand Down
75 changes: 40 additions & 35 deletions sklearn/metrics/tests/test_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ def test_symmetry():

@pytest.mark.parametrize(
'name',
set(ALL_METRICS) - METRIC_UNDEFINED_BINARY_MULTICLASS)
sorted(set(ALL_METRICS) - METRIC_UNDEFINED_BINARY_MULTICLASS))
def test_sample_order_invariance(name):
random_state = check_random_state(0)
y_true = random_state.randint(0, 2, size=(20, ))
Expand Down Expand Up @@ -561,7 +561,7 @@ def test_sample_order_invariance_multilabel_and_multioutput():

@pytest.mark.parametrize(
'name',
set(ALL_METRICS) - METRIC_UNDEFINED_BINARY_MULTICLASS)
sorted(set(ALL_METRICS) - METRIC_UNDEFINED_BINARY_MULTICLASS))
def test_format_invariance_with_1d_vectors(name):
random_state = check_random_state(0)
y1 = random_state.randint(0, 2, size=(20, ))
Expand Down Expand Up @@ -636,8 +636,8 @@ def test_format_invariance_with_1d_vectors(name):


@pytest.mark.parametrize(
'name',
set(CLASSIFICATION_METRICS) - METRIC_UNDEFINED_BINARY_MULTICLASS)
'name',
sorted(set(CLASSIFICATION_METRICS) - METRIC_UNDEFINED_BINARY_MULTICLASS))
def test_classification_invariance_string_vs_numbers_labels(name):
# Ensure that classification metrics with string labels are invariant
random_state = check_random_state(0)
Expand Down Expand Up @@ -767,22 +767,23 @@ def check_single_sample_multioutput(name):


@pytest.mark.parametrize(
'name',
(set(ALL_METRICS)
# Those metrics are not always defined with one sample
# or in multiclass classification
- METRIC_UNDEFINED_BINARY_MULTICLASS
- set(THRESHOLDED_METRICS)))
'name',
sorted(
set(ALL_METRICS)
# Those metrics are not always defined with one sample
# or in multiclass classification
- METRIC_UNDEFINED_BINARY_MULTICLASS - set(THRESHOLDED_METRICS)))
def test_single_sample(name):
check_single_sample(name)


@pytest.mark.parametrize('name', MULTIOUTPUT_METRICS | MULTILABELS_METRICS)
@pytest.mark.parametrize('name',
sorted(MULTIOUTPUT_METRICS | MULTILABELS_METRICS))
def test_single_sample_multioutput(name):
check_single_sample_multioutput(name)


@pytest.mark.parametrize('name', MULTIOUTPUT_METRICS)
@pytest.mark.parametrize('name', sorted(MULTIOUTPUT_METRICS))
def test_multioutput_number_of_output_differ(name):
y_true = np.array([[1, 0, 0, 1], [0, 1, 1, 1], [1, 1, 0, 1]])
y_pred = np.array([[0, 0], [1, 0], [0, 0]])
Expand All @@ -791,7 +792,7 @@ def test_multioutput_number_of_output_differ(name):
assert_raises(ValueError, metric, y_true, y_pred)


@pytest.mark.parametrize('name', MULTIOUTPUT_METRICS)
@pytest.mark.parametrize('name', sorted(MULTIOUTPUT_METRICS))
def test_multioutput_regression_invariance_to_dimension_shuffling(name):
# test invariance to dimension shuffling
random_state = check_random_state(0)
Expand Down Expand Up @@ -846,7 +847,7 @@ def test_multilabel_representation_invariance():
"dense and sparse indicator formats." % name)


@pytest.mark.parametrize('name', MULTILABELS_METRICS)
@pytest.mark.parametrize('name', sorted(MULTILABELS_METRICS))
def test_raise_value_error_multilabel_sequences(name):
# make sure the multilabel-sequence format raises ValueError
multilabel_sequences = [
Expand All @@ -862,7 +863,7 @@ def test_raise_value_error_multilabel_sequences(name):
assert_raises(ValueError, metric, seq, seq)


@pytest.mark.parametrize('name', METRICS_WITH_NORMALIZE_OPTION)
@pytest.mark.parametrize('name', sorted(METRICS_WITH_NORMALIZE_OPTION))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason not to order the dicts?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

METRICS_WITH_NORMALIZE_OPTION is a set. All the sets are sorted, while all the dictionaries become OrderedDicts.

def test_normalize_option_binary_classification(name):
# Test in the binary case
n_samples = 20
Expand All @@ -879,7 +880,7 @@ def test_normalize_option_binary_classification(name):
measure)


@pytest.mark.parametrize('name', METRICS_WITH_NORMALIZE_OPTION)
@pytest.mark.parametrize('name', sorted(METRICS_WITH_NORMALIZE_OPTION))
def test_normalize_option_multiclass_classification(name):
# Test in the multiclass case
random_state = check_random_state(0)
Expand Down Expand Up @@ -986,7 +987,7 @@ def check_averaging(name, y_true, y_true_binarize, y_pred, y_pred_binarize,
raise ValueError("Metric is not recorded as having an average option")


@pytest.mark.parametrize('name', METRICS_WITH_AVERAGING)
@pytest.mark.parametrize('name', sorted(METRICS_WITH_AVERAGING))
def test_averaging_multiclass(name):
n_samples, n_classes = 50, 3
random_state = check_random_state(0)
Expand All @@ -1003,7 +1004,8 @@ def test_averaging_multiclass(name):


@pytest.mark.parametrize(
'name', METRICS_WITH_AVERAGING | THRESHOLDED_METRICS_WITH_AVERAGING)
'name',
sorted(METRICS_WITH_AVERAGING | THRESHOLDED_METRICS_WITH_AVERAGING))
def test_averaging_multilabel(name):
n_samples, n_classes = 40, 5
_, y = make_multilabel_classification(n_features=1, n_classes=n_classes,
Expand All @@ -1019,7 +1021,7 @@ def test_averaging_multilabel(name):
y_pred, y_pred_binarize, y_score)


@pytest.mark.parametrize('name', METRICS_WITH_AVERAGING)
@pytest.mark.parametrize('name', sorted(METRICS_WITH_AVERAGING))
def test_averaging_multilabel_all_zeroes(name):
y_true = np.zeros((20, 3))
y_pred = np.zeros((20, 3))
Expand All @@ -1044,7 +1046,7 @@ def test_averaging_binary_multilabel_all_zeroes():
y_pred_binarize, is_multilabel=True)


@pytest.mark.parametrize('name', METRICS_WITH_AVERAGING)
@pytest.mark.parametrize('name', sorted(METRICS_WITH_AVERAGING))
def test_averaging_multilabel_all_ones(name):
y_true = np.ones((20, 3))
y_pred = np.ones((20, 3))
Expand Down Expand Up @@ -1136,9 +1138,10 @@ def check_sample_weight_invariance(name, metric, y1, y2):


@pytest.mark.parametrize(
'name',
(set(ALL_METRICS).intersection(set(REGRESSION_METRICS))
- METRICS_WITHOUT_SAMPLE_WEIGHT))
'name',
sorted(
set(ALL_METRICS).intersection(set(REGRESSION_METRICS)) -
METRICS_WITHOUT_SAMPLE_WEIGHT))
def test_regression_sample_weight_invariance(name):
n_samples = 50
random_state = check_random_state(0)
Expand All @@ -1150,9 +1153,10 @@ def test_regression_sample_weight_invariance(name):


@pytest.mark.parametrize(
'name',
(set(ALL_METRICS) - set(REGRESSION_METRICS)
- METRICS_WITHOUT_SAMPLE_WEIGHT - METRIC_UNDEFINED_BINARY))
'name',
sorted(
set(ALL_METRICS) - set(REGRESSION_METRICS) -
METRICS_WITHOUT_SAMPLE_WEIGHT - METRIC_UNDEFINED_BINARY))
def test_binary_sample_weight_invariance(name):
# binary
n_samples = 50
Expand All @@ -1168,10 +1172,10 @@ def test_binary_sample_weight_invariance(name):


@pytest.mark.parametrize(
'name',
(set(ALL_METRICS) - set(REGRESSION_METRICS)
- METRICS_WITHOUT_SAMPLE_WEIGHT
- METRIC_UNDEFINED_BINARY_MULTICLASS))
'name',
sorted(
set(ALL_METRICS) - set(REGRESSION_METRICS) -
METRICS_WITHOUT_SAMPLE_WEIGHT - METRIC_UNDEFINED_BINARY_MULTICLASS))
def test_multiclass_sample_weight_invariance(name):
# multiclass
n_samples = 50
Expand All @@ -1187,9 +1191,9 @@ def test_multiclass_sample_weight_invariance(name):


@pytest.mark.parametrize(
'name',
(MULTILABELS_METRICS | THRESHOLDED_MULTILABEL_METRICS |
MULTIOUTPUT_METRICS) - METRICS_WITHOUT_SAMPLE_WEIGHT)
'name',
sorted((MULTILABELS_METRICS | THRESHOLDED_MULTILABEL_METRICS
| MULTIOUTPUT_METRICS) - METRICS_WITHOUT_SAMPLE_WEIGHT))
def test_multilabel_sample_weight_invariance(name):
# multilabel indicator
random_state = check_random_state(0)
Expand Down Expand Up @@ -1235,7 +1239,8 @@ def test_no_averaging_labels():


@pytest.mark.parametrize(
'name', MULTILABELS_METRICS - {"unnormalized_multilabel_confusion_matrix"})
'name',
sorted(MULTILABELS_METRICS - {"unnormalized_multilabel_confusion_matrix"}))
def test_multilabel_label_permutations_invariance(name):
random_state = check_random_state(0)
n_samples, n_classes = 20, 4
Expand All @@ -1255,7 +1260,7 @@ def test_multilabel_label_permutations_invariance(name):


@pytest.mark.parametrize(
'name', THRESHOLDED_MULTILABEL_METRICS | MULTIOUTPUT_METRICS)
'name', sorted(THRESHOLDED_MULTILABEL_METRICS | MULTIOUTPUT_METRICS))
def test_thresholded_multilabel_multioutput_permutations_invariance(name):
random_state = check_random_state(0)
n_samples, n_classes = 20, 4
Expand Down
2 changes: 1 addition & 1 deletion sklearn/tests/test_random_projection.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

all_sparse_random_matrix = [sparse_random_matrix]
all_dense_random_matrix = [gaussian_random_matrix]
all_random_matrix = set(all_sparse_random_matrix + all_dense_random_matrix)
all_random_matrix = all_sparse_random_matrix + all_dense_random_matrix

all_SparseRandomProjection = [SparseRandomProjection]
all_DenseRandomProjection = [GaussianRandomProjection]
Expand Down
2 changes: 1 addition & 1 deletion sklearn/tree/tests/test_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -1375,7 +1375,7 @@ def test_sparse_input(tree_type, dataset):


@pytest.mark.parametrize("tree_type",
set(SPARSE_TREES).intersection(REG_TREES))
sorted(set(SPARSE_TREES).intersection(REG_TREES)))
@pytest.mark.parametrize("dataset", ["boston", "reg_small"])
def test_sparse_input_reg_trees(tree_type, dataset):
# Due to numerical instability of MSE and too strict test, we limit the
Expand Down