Skip to content

Conversation

@Lekensteyn
Copy link
Contributor

@Lekensteyn Lekensteyn commented Apr 24, 2019

'python2' does not exist on macOS, it is called 'python2.7'. Porting to
Python 3 is however more future-proof so do that instead. Rename the
file such that it can be run with pytest.

Do not listen on a fixed host port and use a random port instead.
Otherwise tests could fail if something is listening on those ports.


Note, with this modification, I noticed some ResourceWarnings after calling exec_run due to a Docker socket being leaked. These won't affect the test results though so I just left it there. See docker/docker-py#1293 (comment) I removed the wait logic improvement due to the complexity and the fact that it triggers a bug in docker-py.

I upgraded to Xenial to ensure a newer python3-six version to solve a failure importing docker. docker/docker-py#2294 (comment)

With the file rename, I can now do run a subset of the tests during development:

pytest _dev/interop_test_runner.py -k SIDH -v

and add -nauto to run those tests in parallel (requires pytest-xdist). This can complete all tests in 30 seconds (with 12 jobs). Another nice feature is the ability to pause when an assertion fails and inspect the context:

pytest _dev/interop_test_runner.py -k 'test_SIDH and Server'  --pdb


test-interop:
$(DEV_DIR)/interop_test_runner -v
$(DEV_DIR)/interop_test_runner.py -v
Copy link
Contributor

Choose a reason for hiding this comment

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

what for?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Otherwise pytest won't be able to load the script (see initial description for why pytest helps during development).

# 'ss -Htln' is the modern form, but boringssl image only includes
# netstat (via busybox).
info = c.exec_run('sh -c "ss -Htln 2>/dev/null || netstat -tln"')
if info.exit_code != 0:
Copy link
Contributor

Choose a reason for hiding this comment

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

remove != 0

self.wait_for_ports(c)
return c

def wait_for_ports(self, c):
Copy link
Contributor

Choose a reason for hiding this comment

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

can we do it better without calling shell at all?

Copy link
Contributor Author

@Lekensteyn Lekensteyn Apr 25, 2019

Choose a reason for hiding this comment

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

I couldn't really find a good alternative. I tried to retrieve container IP and try to port scan it from Python. Does not work on Docker for Mac, details.

An alternative is to start a container for the sole purpose of port-scanning a host (it could consist of a single Go binary), but the size of that support code will be slightly larger than the current approach. If you think that this would be better, I can change it though?

Another possibility is to add a HEALTCHECK command, but that would roughly have the same effect as checking ss, except that the logic is moved into the Docker image.

Copy link
Contributor

Choose a reason for hiding this comment

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

I would double check docker-py. I wonder if it's not done by this wrapper itself.
If not can't we just "import socket" and "socket.connect"? It's hard for me to believe python doesn't have something equivalent to ss

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have tried the socket approach before, but it won't work:

Does not work on Docker for Mac, details.

Checking for reachable ports is not something that can be done with the high-level docker-py API (docker/docker-py#2229). Usually healthchecks are used to test whether a service is ready (e.g. aside from checking that a TCP socket can be opened, verify that the HTTP service returns a proper response). In our case, it is sufficient if a TCP socket can be opened.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, keep digging.

@kriskwiatkowski
Copy link
Contributor

This change is a root cause of python issuing such warn's

/usr/lib/python3.5/http/client.py:410: ResourceWarning: unclosed <socket.socket fd=8, family=AddressFamily.AF_UNIX, type=2049, proto=0, raddr=/var/run/docker.sock>
  self._close_conn()

I'm actually getting a lot of those locally. It will need to be fixed before merging

'python2' does not exist on macOS, it is called 'python2.7'. Porting to
Python 3 is however more future-proof so do that instead. Rename the
file such that it can be run with pytest.

Do not listen on a fixed host port and use a random port instead.
Otherwise tests could fail if something is listening on those ports.
@Lekensteyn Lekensteyn changed the title interop_test_runner: use Python 3, improve wait logic interop_test_runner: use Python 3 Apr 29, 2019
@Lekensteyn
Copy link
Contributor Author

I've dropped the whole server start optimization (and kept two versions at https://github.com/cloudflare/tls-tris/commits/pwu/tests-speedup-v0 and https://github.com/cloudflare/tls-tris/commits/pwu/tests-speedup-v1).

Now it only fixes the Python 3 issues, pytest support and some potential resource leaks.

@kriskwiatkowski kriskwiatkowski merged commit a926d3b into master Apr 29, 2019
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.

2 participants