Skip to content

Conversation

@fjetter
Copy link
Member

@fjetter fjetter commented Jun 16, 2022

This PR adds pytest fixtures that ensure a port being used in a test is free (no 100% guarantee)

I added logic to enable this even for concurrent runs using pytest-xdist, i.e. this is a step towards

@fjetter fjetter requested review from crusaderky and gjoseph92 June 16, 2022 17:31
@fjetter fjetter force-pushed the consistent_ports_dask_schdeuler_cli branch from 012ba28 to 5b4e280 Compare June 16, 2022 18:07
@github-actions
Copy link
Contributor

github-actions bot commented Jun 16, 2022

Unit Test Results

See test report for an extended history of previous test failures. This is useful for diagnosing flaky tests.

       15 files  +       6         15 suites  +6   6h 56m 15s ⏱️ + 3h 26m 4s
  2 882 tests +       3    2 795 ✔️ +     11    84 💤  -   11  3 +3 
21 352 runs  +8 648  20 384 ✔️ +8 227  965 💤 +418  3 +3 

For more details on these failures, see this check.

Results for commit 9620479. ± Comparison against base commit 4239aed.

♻️ This comment has been updated with latest results.

def free_port(global_port_lock, name_of_test):
with _get_open_port(global_port_lock) as port:
print(f"Using free port {port} for test {name_of_test}")
yield str(port)
Copy link
Collaborator

Choose a reason for hiding this comment

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

why do you need to change it to str?

Copy link
Member

Choose a reason for hiding this comment

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

@crusaderky
Copy link
Collaborator

+1 I like the idea behind this

@fjetter fjetter requested a review from graingert June 21, 2022 15:00
def free_port(global_port_lock, name_of_test):
with _get_open_port(global_port_lock) as port:
print(f"Using free port {port} for test {name_of_test}")
yield str(port)
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member Author

@fjetter fjetter left a comment

Choose a reason for hiding this comment

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

I removed the file locking nonsense again since it didn't work reliably, at least not with tmpfiles.
If we choose to go for pytest-xdist we might just want to skip the tests that require default ports or ensure they are all scheduled on the same xdist worker


def open_port(host=""):
"""Return a probably-open port
def open_port(host="", port=0):
Copy link
Member Author

Choose a reason for hiding this comment

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

the version of ephemeral-port-reserve seems to be pretty close to what we had but much more sophisticated and likely better tested. Since open_port is something that might've been used elsewhere I decided to vendor the code.

Copy link
Member Author

Choose a reason for hiding this comment

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

That version didn't work on windows so I reverted to the old one.

@fjetter fjetter changed the title WIP / RFC Add fixtures to ensure free ports are picked Always pick an open port when running tests Jun 22, 2022
@fjetter fjetter force-pushed the consistent_ports_dask_schdeuler_cli branch from 771342c to 0d9bb03 Compare June 22, 2022 09:30
@fjetter fjetter marked this pull request as ready for review June 22, 2022 11:53
@fjetter
Copy link
Member Author

fjetter commented Jun 22, 2022

I replaced most occurrences of hard coded ports (there are still plenty in test_core.py)

Comment on lines 112 to 113
"--port",
str(port1),
Copy link
Member

@graingert graingert Jun 22, 2022

Choose a reason for hiding this comment

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

nit: I find f-strings marginally neater here

Suggested change
"--port",
str(port1),
f"--port={port1}",

Copy link
Member Author

@fjetter fjetter Jun 22, 2022

Choose a reason for hiding this comment

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

agreed. I was not entirely sure if our popen would handle this properly but it does 🎉

I changed most occurrences with some regex replacements. might have missed a few but will not go back for this

Copy link
Member

Choose a reason for hiding this comment

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

👍

@fjetter fjetter force-pushed the consistent_ports_dask_schdeuler_cli branch from 42f1a57 to afe006d Compare June 22, 2022 16:53
Comment on lines 530 to 549
@pytest.mark.skipif(WINDOWS, reason="POSIX only")
@pytest.mark.parametrize("sig", [signal.SIGINT, signal.SIGTERM])
def test_signal_handling(loop, sig):
port = open_port()
with subprocess.Popen(
["python", "-m", "distributed.cli.dask_scheduler"],
[
"python",
"-m",
"distributed.cli.dask_scheduler",
f"--port={port}",
"--dashboard-address=:0",
],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
) as scheduler:
# Wait for scheduler to start
with Client(f"127.0.0.1:{Scheduler.default_port}", loop=loop) as c:
with Client(f"127.0.0.1:{port}", loop=loop) as c:
pass
scheduler.send_signal(sig)
stdout, stderr = scheduler.communicate()
Copy link
Member Author

Choose a reason for hiding this comment

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

I believe this test is causing a lot of cascading failures by blocking ports after not shutting down properly. I notice we're not using the custom popen (which I'm OK with) but I'm wondering why this is not shutting down properly. Anyhow, with these port changes this should be more robust

@fjetter
Copy link
Member Author

fjetter commented Jun 23, 2022

On OSX 3.10 I still get a connection refused error but this is likely caused by a conflict in the dashboard port, see also #6612

FAILED distributed/cli/tests/test_dask_scheduler.py::test_defaults - OSError:...
FAILED distributed/cli/tests/test_dask_scheduler.py::test_dashboard - OSError...

@fjetter fjetter merged commit 7a0649a into dask:main Jun 23, 2022
@fjetter fjetter deleted the consistent_ports_dask_schdeuler_cli branch June 23, 2022 09:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants