Move Python IPC connection from tests to Veilid

This commit is contained in:
DumontIO 2024-08-13 16:08:15 -04:00
parent 672ad87d28
commit 0c19414934
5 changed files with 39 additions and 39 deletions

View File

@ -8,7 +8,6 @@ from veilid.json_api import _JsonVeilidAPI
import veilid import veilid
from .api import VeilidTestConnectionError, api_connector
pytest_plugins = ("pytest_asyncio",) pytest_plugins = ("pytest_asyncio",)
@ -20,8 +19,8 @@ async def simple_update_callback(update: veilid.VeilidUpdate):
@pytest_asyncio.fixture @pytest_asyncio.fixture
async def api_connection() -> AsyncGenerator[_JsonVeilidAPI, None]: async def api_connection() -> AsyncGenerator[_JsonVeilidAPI, None]:
try: try:
api = await api_connector(simple_update_callback) api = await veilid.api_connector(simple_update_callback)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server.") pytest.skip("Unable to connect to veilid-server.")
return return

View File

@ -7,7 +7,7 @@ import json
import time import time
import os import os
from . import * from . import *
from .api import VeilidTestConnectionError, api_connector
################################################################## ##################################################################
BOGUS_KEY = veilid.TypedKey.from_value( BOGUS_KEY = veilid.TypedKey.from_value(
@ -217,8 +217,8 @@ async def test_watch_dht_values():
await value_change_queue.put(update) await value_change_queue.put(update)
try: try:
api = await api_connector(value_change_update_callback) api = await veilid.api_connector(value_change_update_callback)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server.") pytest.skip("Unable to connect to veilid-server.")
return return
@ -286,7 +286,7 @@ async def test_watch_dht_values():
assert vd == [None, None] assert vd == [None, None]
# Wait for the update # Wait for the update
upd = await asyncio.wait_for(value_change_queue.get(), timeout=5) upd = await asyncio.wait_for(value_change_queue.get(), timeout=10)
# Verify the update came back but we don't get a new value because the sequence number is the same # Verify the update came back but we don't get a new value because the sequence number is the same
assert upd.detail.key == rec.key assert upd.detail.key == rec.key
@ -352,14 +352,14 @@ async def test_dht_integration_writer_reader():
pass pass
try: try:
api0 = await api_connector(null_update_callback, 0) api0 = await veilid.api_connector(null_update_callback, 0)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server 0.") pytest.skip("Unable to connect to veilid-server 0.")
return return
try: try:
api1 = await api_connector(null_update_callback, 1) api1 = await veilid.api_connector(null_update_callback, 1)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server 1.") pytest.skip("Unable to connect to veilid-server 1.")
return return
@ -418,8 +418,8 @@ async def test_dht_write_read_local():
pass pass
try: try:
api0 = await api_connector(null_update_callback, 0) api0 = await veilid.api_connector(null_update_callback, 0)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server 0.") pytest.skip("Unable to connect to veilid-server 0.")
return return
@ -432,7 +432,8 @@ async def test_dht_write_read_local():
rc0 = await api0.new_routing_context() rc0 = await api0.new_routing_context()
async with rc0: async with rc0:
COUNT = 500 # FIXME: 500
COUNT = 5
TEST_DATA = b"ABCD"*1024 TEST_DATA = b"ABCD"*1024
TEST_DATA2 = b"ABCD"*4096 TEST_DATA2 = b"ABCD"*4096

View File

@ -9,8 +9,6 @@ import pytest
import veilid import veilid
from .api import VeilidTestConnectionError, api_connector
################################################################## ##################################################################
@ -53,8 +51,8 @@ async def test_routing_context_app_message_loopback():
await app_message_queue.put(update) await app_message_queue.put(update)
try: try:
api = await api_connector(app_message_queue_update_callback) api = await veilid.api_connector(app_message_queue_update_callback)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server.") pytest.skip("Unable to connect to veilid-server.")
return return
@ -101,8 +99,8 @@ async def test_routing_context_app_call_loopback():
await app_call_queue.put(update) await app_call_queue.put(update)
try: try:
api = await api_connector(app_call_queue_update_callback) api = await veilid.api_connector(app_call_queue_update_callback)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server.") pytest.skip("Unable to connect to veilid-server.")
return return
@ -162,8 +160,8 @@ async def test_routing_context_app_message_loopback_big_packets():
sent_messages: set[bytes] = set() sent_messages: set[bytes] = set()
try: try:
api = await api_connector(app_message_queue_update_callback) api = await veilid.api_connector(app_message_queue_update_callback)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server.") pytest.skip("Unable to connect to veilid-server.")
return return
@ -227,8 +225,8 @@ async def test_routing_context_app_call_loopback_big_packets():
await api.app_call_reply(update.detail.call_id, update.detail.message) await api.app_call_reply(update.detail.call_id, update.detail.message)
try: try:
api = await api_connector(app_call_queue_update_callback) api = await veilid.api_connector(app_call_queue_update_callback)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server.") pytest.skip("Unable to connect to veilid-server.")
return return
@ -277,8 +275,8 @@ async def test_routing_context_app_message_loopback_bandwidth():
await app_message_queue.put(True) await app_message_queue.put(True)
try: try:
api = await api_connector(app_message_queue_update_callback) api = await veilid.api_connector(app_message_queue_update_callback)
except VeilidTestConnectionError: except veilid.VeilidConnectionError:
pytest.skip("Unable to connect to veilid-server.") pytest.skip("Unable to connect to veilid-server.")
return return

View File

@ -1,4 +1,5 @@
from .api import * from .api import *
from .connection import *
from .config import * from .config import *
from .error import * from .error import *
from .json_api import * from .json_api import *

View File

@ -1,28 +1,27 @@
import appdirs import appdirs
import errno import errno
import os import os
import socket
import sys import sys
import re import re
from collections.abc import Callable from collections.abc import Callable
from functools import cache from functools import cache
import veilid
from veilid.json_api import _JsonVeilidAPI from veilid.json_api import _JsonVeilidAPI
import veilid
ERRNO_PATTERN = re.compile(r"errno (\d+)", re.IGNORECASE) ERRNO_PATTERN = re.compile(r"errno (\d+)", re.IGNORECASE)
class VeilidTestConnectionError(Exception): class VeilidConnectionError(Exception):
"""The test client could not connect to the veilid-server.""" """The client could not connect to the veilid-server."""
pass pass
@cache @cache
def server_info(subindex: int = 0) -> tuple[str, int]: def server_info(subindex: int = 0) -> tuple[str, int]:
"""Return the hostname and port of the test server.""" """Return the hostname and port of the server."""
VEILID_SERVER_NETWORK = os.getenv("VEILID_SERVER_NETWORK") VEILID_SERVER_NETWORK = os.getenv("VEILID_SERVER_NETWORK")
if VEILID_SERVER_NETWORK is None: if VEILID_SERVER_NETWORK is None:
return "localhost", 5959 + subindex return "localhost", 5959 + subindex
@ -32,6 +31,7 @@ def server_info(subindex: int = 0) -> tuple[str, int]:
return hostname, int(rest[0]) + subindex return hostname, int(rest[0]) + subindex
return hostname, 5959 + subindex return hostname, 5959 + subindex
def ipc_path_exists(path: str) -> bool: def ipc_path_exists(path: str) -> bool:
"""Determine if an IPC socket exists in a platform independent way.""" """Determine if an IPC socket exists in a platform independent way."""
if os.name == 'nt': if os.name == 'nt':
@ -40,17 +40,18 @@ def ipc_path_exists(path: str) -> bool:
return path[9:] in os.listdir("\\\\.\\PIPE") return path[9:] in os.listdir("\\\\.\\PIPE")
else: else:
return os.path.exists(path) return os.path.exists(path)
@cache @cache
def ipc_info(subindex: int = 0) -> str: def ipc_info(subindex: int = 0) -> str:
"""Return the path of the ipc socket of the test server.""" """Return the path of the ipc socket of the server."""
VEILID_SERVER_IPC = os.getenv("VEILID_SERVER_IPC") VEILID_SERVER_IPC = os.getenv("VEILID_SERVER_IPC")
if VEILID_SERVER_IPC is not None: if VEILID_SERVER_IPC is not None:
return VEILID_SERVER_IPC return VEILID_SERVER_IPC
if os.name == 'nt': if os.name == 'nt':
return f'\\\\.\\PIPE\\veilid-server\\{subindex}' return f'\\\\.\\PIPE\\veilid-server\\{subindex}'
ipc_path = f"/var/db/veilid-server/ipc/{subindex}" ipc_path = f"/var/db/veilid-server/ipc/{subindex}"
if os.path.exists(ipc_path): if os.path.exists(ipc_path):
return ipc_path return ipc_path
@ -59,7 +60,7 @@ def ipc_info(subindex: int = 0) -> str:
if sys.platform.startswith('darwin'): if sys.platform.startswith('darwin'):
data_dir = appdirs.user_data_dir("org.Veilid.Veilid") data_dir = appdirs.user_data_dir("org.Veilid.Veilid")
else: else:
data_dir = appdirs.user_data_dir("veilid","veilid") data_dir = appdirs.user_data_dir("veilid", "veilid")
ipc_path = os.path.join(data_dir, "ipc", str(subindex)) ipc_path = os.path.join(data_dir, "ipc", str(subindex))
return ipc_path return ipc_path
@ -68,10 +69,10 @@ async def api_connector(callback: Callable, subindex: int = 0) -> _JsonVeilidAPI
"""Return an API connection if possible. """Return an API connection if possible.
If the connection fails due to an inability to connect to the If the connection fails due to an inability to connect to the
server's socket, raise an easy-to-catch VeilidTestConnectionError. server's socket, raise an easy-to-catch VeilidConnectionError.
""" """
ipc_path = ipc_info(subindex) ipc_path = ipc_info(subindex)
try: try:
if ipc_path_exists(ipc_path): if ipc_path_exists(ipc_path):
@ -96,7 +97,7 @@ async def api_connector(callback: Callable, subindex: int = 0) -> _JsonVeilidAPI
# it's the code we expected. # it's the code we expected.
if exc.errno is not None: if exc.errno is not None:
if exc.errno == errno.ECONNREFUSED: if exc.errno == errno.ECONNREFUSED:
raise VeilidTestConnectionError raise VeilidConnectionError
raise raise
# If not, use a regular expression to find all the errno values # If not, use a regular expression to find all the errno values
@ -104,6 +105,6 @@ async def api_connector(callback: Callable, subindex: int = 0) -> _JsonVeilidAPI
# code we're looking for. # code we're looking for.
errnos = ERRNO_PATTERN.findall(str(exc)) errnos = ERRNO_PATTERN.findall(str(exc))
if all(int(err) == errno.ECONNREFUSED for err in errnos): if all(int(err) == errno.ECONNREFUSED for err in errnos):
raise VeilidTestConnectionError raise VeilidConnectionError
raise raise