Updating to capnproto v0.8.0
- Includes some test stabilization - Fixes manylinux2010 build issues (linker flag order due to old gcc) - More rigorous python setup.py clean - Requires capnproto v0.8.0 or greater - Including system libcapnp include path for import (e.g. import stream_capnp) - Bundle libcapnp .capnp files when not using system libcapnp - Removing more distutils usage. Now using pkg-config to determine the system version of libcapnp (mainly for Linux, but should work on macOS with brew) - Removed dead code Resolves issues #215 #216 #217 Lots of fixes for Issue #218 (all sorts of retry methods needed for GitHub Actions)
This commit is contained in:
@@ -1,75 +1,147 @@
|
||||
import os
|
||||
import pytest
|
||||
import socket
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
examples_dir = os.path.join(os.path.dirname(__file__), '..', 'examples')
|
||||
hostname = 'localhost'
|
||||
|
||||
|
||||
processes = []
|
||||
|
||||
@pytest.fixture
|
||||
def cleanup():
|
||||
yield
|
||||
for p in processes:
|
||||
p.kill()
|
||||
|
||||
|
||||
def run_subprocesses(address, server, client):
|
||||
cmd = [sys.executable, os.path.join(examples_dir, server), address]
|
||||
server = subprocess.Popen(cmd)
|
||||
retries = 30
|
||||
server_attempt = 0
|
||||
server_attempts = 2
|
||||
done = False
|
||||
addr, port = address.split(':')
|
||||
while True:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
result = sock.connect_ex((addr, int(port)))
|
||||
if result == 0:
|
||||
break
|
||||
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
||||
result = sock.connect_ex((addr, int(port)))
|
||||
if result == 0:
|
||||
break
|
||||
# Give the server some small amount of time to start listening
|
||||
time.sleep(0.1)
|
||||
retries -= 1
|
||||
if retries == 0:
|
||||
assert False, "Timed out waiting for server to start"
|
||||
cmd = [sys.executable, os.path.join(examples_dir, client), address]
|
||||
client = subprocess.Popen(cmd)
|
||||
while not done:
|
||||
assert server_attempt < server_attempts, "Failed {} server attempts".format(server_attempts)
|
||||
server_attempt += 1
|
||||
|
||||
ret = client.wait(timeout=30)
|
||||
server.kill()
|
||||
assert ret == 0
|
||||
# Start server
|
||||
cmd = [sys.executable, os.path.join(examples_dir, server), address]
|
||||
serverp = subprocess.Popen(cmd, stdout=sys.stdout, stderr=sys.stderr)
|
||||
print("Server started (Attempt #{})".format(server_attempt))
|
||||
processes.append(serverp)
|
||||
retries = 300
|
||||
# Loop until we have a socket connection to the server (with timeout)
|
||||
while True:
|
||||
try:
|
||||
if 'unix' in address:
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
result = sock.connect_ex(port)
|
||||
if result == 0:
|
||||
break
|
||||
else:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
result = sock.connect_ex((addr, int(port)))
|
||||
if result == 0:
|
||||
break
|
||||
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
||||
result = sock.connect_ex((addr, int(port)))
|
||||
if result == 0:
|
||||
break
|
||||
except socket.gaierror as err:
|
||||
print("gaierror: {}".format(err))
|
||||
# Give the server some small amount of time to start listening
|
||||
time.sleep(0.1)
|
||||
retries -= 1
|
||||
if retries == 0:
|
||||
serverp.kill()
|
||||
print("Timed out waiting for server to start")
|
||||
break
|
||||
|
||||
if serverp.poll() is not None:
|
||||
print("Server exited prematurely: {}".format(serverp.returncode))
|
||||
break
|
||||
|
||||
# 3 tries per server try
|
||||
client_attempt = 0
|
||||
client_attempts = 3
|
||||
while not done:
|
||||
if client_attempt >= client_attempts:
|
||||
print("Failed {} client attempts".format(client_attempts))
|
||||
break
|
||||
client_attempt += 1
|
||||
|
||||
# Start client
|
||||
cmd = [sys.executable, os.path.join(examples_dir, client), address]
|
||||
clientp = subprocess.Popen(cmd, stdout=sys.stdout, stderr=sys.stderr)
|
||||
print("Client started (Attempt #{})".format(client_attempt))
|
||||
processes.append(clientp)
|
||||
|
||||
retries = 30 * 10
|
||||
# Loop until the client is finished (with timeout)
|
||||
while True:
|
||||
if clientp.poll() == 0:
|
||||
done = True
|
||||
break
|
||||
|
||||
if clientp.poll() is not None:
|
||||
print("Client exited prematurely: {}".format(clientp.returncode))
|
||||
break
|
||||
time.sleep(0.1)
|
||||
retries -= 1
|
||||
if retries == 0:
|
||||
print("Timed out waiting for client to finish")
|
||||
clientp.kill()
|
||||
break
|
||||
|
||||
# Retrying with different address (ipv4)
|
||||
if 'unix' not in addr:
|
||||
addr = socket.gethostbyname(addr)
|
||||
address = '{}:{}'.format(addr, port)
|
||||
print("Forcing ipv4 -> {}".format(address))
|
||||
serverp.kill()
|
||||
|
||||
serverp.kill()
|
||||
|
||||
|
||||
def test_async_calculator_example():
|
||||
address = 'localhost:36432'
|
||||
def test_async_calculator_example(cleanup):
|
||||
address = '{}:36432'.format(hostname)
|
||||
server = 'async_calculator_server.py'
|
||||
client = 'async_calculator_client.py'
|
||||
run_subprocesses(address, server, client)
|
||||
|
||||
|
||||
def test_thread_example():
|
||||
address = 'localhost:36433'
|
||||
def test_thread_example(cleanup):
|
||||
address = '{}:36433'.format(hostname)
|
||||
server = 'thread_server.py'
|
||||
client = 'thread_client.py'
|
||||
run_subprocesses(address, server, client)
|
||||
|
||||
|
||||
def test_addressbook_example():
|
||||
def test_addressbook_example(cleanup):
|
||||
proc = subprocess.Popen([sys.executable, os.path.join(examples_dir, 'addressbook.py')])
|
||||
ret = proc.wait()
|
||||
assert ret == 0
|
||||
|
||||
|
||||
def test_async_example():
|
||||
address = 'localhost:36434'
|
||||
def test_async_example(cleanup):
|
||||
address = '{}:36434'.format(hostname)
|
||||
server = 'async_server.py'
|
||||
client = 'async_client.py'
|
||||
run_subprocesses(address, server, client)
|
||||
|
||||
|
||||
def test_ssl_async_example():
|
||||
address = 'localhost:36435'
|
||||
def test_ssl_async_example(cleanup):
|
||||
address = '{}:36435'.format(hostname)
|
||||
server = 'async_ssl_server.py'
|
||||
client = 'async_ssl_client.py'
|
||||
run_subprocesses(address, server, client)
|
||||
|
||||
|
||||
def test_ssl_reconnecting_async_example():
|
||||
address = 'localhost:36436'
|
||||
def test_ssl_reconnecting_async_example(cleanup):
|
||||
address = '{}:36436'.format(hostname)
|
||||
server = 'async_ssl_server.py'
|
||||
client = 'async_reconnecting_ssl_client.py'
|
||||
run_subprocesses(address, server, client)
|
||||
|
||||
@@ -111,3 +111,9 @@ def test_remove_import_hook():
|
||||
|
||||
with pytest.raises(ImportError):
|
||||
import addressbook_capnp # noqa: F401
|
||||
|
||||
|
||||
def test_bundled_import_hook():
|
||||
# stream.capnp should be bundled, or provided by the system capnproto
|
||||
capnp.add_import_hook()
|
||||
import stream_capnp
|
||||
|
||||
@@ -14,6 +14,17 @@ sys.path.append(examples_dir)
|
||||
import calculator_client # noqa: E402
|
||||
import calculator_server # noqa: E402
|
||||
|
||||
# Uses run_subprocesses function
|
||||
import test_examples
|
||||
|
||||
processes = []
|
||||
|
||||
@pytest.fixture
|
||||
def cleanup():
|
||||
yield
|
||||
for p in processes:
|
||||
p.kill()
|
||||
|
||||
|
||||
def test_calculator():
|
||||
read, write = socket.socketpair()
|
||||
@@ -22,53 +33,13 @@ def test_calculator():
|
||||
calculator_client.main(read)
|
||||
|
||||
|
||||
def run_subprocesses(address):
|
||||
cmd = [sys.executable, os.path.join(examples_dir, 'calculator_server.py'), address]
|
||||
server = subprocess.Popen(cmd)
|
||||
retries = 30
|
||||
if 'unix' in address:
|
||||
addr = address.split(':')[1]
|
||||
while True:
|
||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
result = sock.connect_ex(addr)
|
||||
if result == 0:
|
||||
break
|
||||
# Give the server some small amount of time to start listening
|
||||
time.sleep(0.1)
|
||||
retries -= 1
|
||||
if retries == 0:
|
||||
assert False, "Timed out waiting for server to start"
|
||||
else:
|
||||
addr, port = address.split(':')
|
||||
while True:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
result = sock.connect_ex((addr, int(port)))
|
||||
if result == 0:
|
||||
break
|
||||
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
|
||||
result = sock.connect_ex((addr, int(port)))
|
||||
if result == 0:
|
||||
break
|
||||
# Give the server some small amount of time to start listening
|
||||
time.sleep(0.1)
|
||||
retries -= 1
|
||||
if retries == 0:
|
||||
assert False, "Timed out waiting for server to start"
|
||||
cmd = [sys.executable, os.path.join(examples_dir, 'calculator_client.py'), address]
|
||||
client = subprocess.Popen(cmd)
|
||||
|
||||
ret = client.wait()
|
||||
server.kill()
|
||||
assert ret == 0
|
||||
|
||||
|
||||
def test_calculator_tcp():
|
||||
def test_calculator_tcp(cleanup):
|
||||
address = 'localhost:36431'
|
||||
run_subprocesses(address)
|
||||
test_examples.run_subprocesses(address, 'calculator_server.py', 'calculator_client.py')
|
||||
|
||||
|
||||
@pytest.mark.skipif(os.name == 'nt', reason="socket.AF_UNIX not supported on Windows")
|
||||
def test_calculator_unix():
|
||||
def test_calculator_unix(cleanup):
|
||||
path = '/tmp/pycapnp-test'
|
||||
try:
|
||||
os.unlink(path)
|
||||
@@ -76,7 +47,7 @@ def test_calculator_unix():
|
||||
pass
|
||||
|
||||
address = 'unix:' + path
|
||||
run_subprocesses(address)
|
||||
test_examples.run_subprocesses(address, 'calculator_server.py', 'calculator_client.py')
|
||||
|
||||
|
||||
def test_calculator_gc():
|
||||
|
||||
Reference in New Issue
Block a user