Skip to content

Commit

Permalink
Use TCP instead of UDS for tests (#35)
Browse files Browse the repository at this point in the history
* Use TCP instead of UDS for tests
* Fix codecov
  • Loading branch information
d5h authored Apr 13, 2023
1 parent 454bc61 commit 9540840
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 58 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ jobs:
python-version: '3.11'
architecture: x64
- run: pip install nox==2022.1.7 toml==0.10.2 poetry==1.0.9
- run: nox --sessions tests-3.11 coverage
env:
CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}}
- run: nox --sessions tests-3.11
- uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
18 changes: 9 additions & 9 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@
@nox.session(python=PY_VERSIONS)
def tests(session):
"""Run the test suite."""
args = session.posargs or ["--cov", "-ra", "-vv"]
args = session.posargs or [
"--cov",
"--cov-report",
"term-missing",
"--cov-report",
"xml",
"-ra",
"-vv",
]
session.run("poetry", "install", "--no-dev", external=True)
install_with_constraints(
session,
Expand All @@ -40,14 +48,6 @@ def xdoctest(session) -> None:
session.run("python", "-m", "xdoctest", "grpc_interceptor", *args)


@nox.session(python=PY_LATEST)
def coverage(session):
"""Upload coverage data."""
install_with_constraints(session, "coverage[toml]", "codecov")
session.run("coverage", "xml", "--fail-under=0")
session.run("codecov", *session.posargs)


@nox.session(python=PY_LATEST)
def docs(session):
"""Build the documentation."""
Expand Down
15 changes: 1 addition & 14 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "grpc-interceptor"
version = "0.15.0"
version = "0.15.1"
description = "Simplifies gRPC interceptors"
license = "MIT"
readme = "README.md"
Expand Down Expand Up @@ -35,7 +35,6 @@ mypy = "^1.2.0"
mypy-protobuf = "^1.23"
flake8-docstrings = "^1.5.0"
sphinx = "^3.1.2"
codecov = "^2.1.8"
xdoctest = "^0.13.0"
pytest-asyncio = {version = "^0.19.0", python = ">=3.7"}

Expand Down
59 changes: 29 additions & 30 deletions src/grpc_interceptor/testing/dummy_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import asyncio
from concurrent import futures
from contextlib import contextmanager
import os
from tempfile import gettempdir
from threading import Event, Thread
from typing import (
Any,
Expand All @@ -16,7 +14,6 @@
List,
Optional,
)
from uuid import uuid4

import grpc

Expand Down Expand Up @@ -229,23 +226,6 @@ def dummy_channel(
if not interceptors:
interceptors = []

if os.name == "nt": # pragma: no cover
# We use Unix domain sockets when they're supported, to avoid port conflicts.
# However, on Windows, just pick a port.
channel_descriptor = "localhost:50051"
else:
channel_descriptor = f"unix://{gettempdir()}/{uuid4()}.sock"

if aio_client:
channel = grpc_aio.insecure_channel(channel_descriptor)
# Client interceptors might work, but I haven't tested them yet.
if client_interceptors:
raise TypeError("Client interceptors not supported with async channel")
else:
channel = grpc.insecure_channel(channel_descriptor)
if client_interceptors:
channel = grpc.intercept_channel(channel, *client_interceptors)

if aio_server:
service = (
AsyncReadWriteDummyService(special_cases)
Expand All @@ -256,27 +236,47 @@ def dummy_channel(
aio_thread = _AsyncServerThread(
aio_loop,
service,
channel if aio_client else None,
channel_descriptor,
interceptors,
)
aio_thread.start()
aio_thread.wait_for_server()
port = aio_thread.port
else:
dummy_service = DummyService(special_cases)
server = grpc.server(
futures.ThreadPoolExecutor(max_workers=1), interceptors=interceptors
)
dummy_pb2_grpc.add_DummyServiceServicer_to_server(dummy_service, server)
server.add_insecure_port(channel_descriptor)
port = server.add_insecure_port("localhost:0")
server.start()

channel_descriptor = f"localhost:{port}"

if aio_client:
channel = grpc_aio.insecure_channel(channel_descriptor)
# Client interceptors might work, but I haven't tested them yet.
if client_interceptors:
raise TypeError("Client interceptors not supported with async channel")
# We close the channel in _AsyncServerThread because we need to await
# it, and doing that in this thread is problematic because dummy_client
# isn't always used in an async context. We could get around that by
# creating a new loop or something, but will be lazy and use the server
# thread / loop for now.
if not aio_server:
raise ValueError("aio_server must be True if aio_client is True")
aio_thread.async_channel = channel
else:
channel = grpc.insecure_channel(channel_descriptor)
if client_interceptors:
channel = grpc.intercept_channel(channel, *client_interceptors)

try:
yield channel
finally:
if not aio_client:
# async channel is closed by _AsyncServerThread
channel.close()

if aio_server:
aio_thread.stop()
aio_thread.join()
Expand All @@ -285,19 +285,18 @@ def dummy_channel(


class _AsyncServerThread(Thread):
port: int = 0
async_channel = None

def __init__(
self,
loop: asyncio.AbstractEventLoop,
service,
optional_async_client_channel,
channel_descriptor: str,
interceptors: List[AsyncServerInterceptor],
):
super().__init__()
self.__loop = loop
self.__service = service
self.__optional_async_client_channel = optional_async_client_channel
self.__channel_descriptor = channel_descriptor
self.__interceptors = interceptors
self.__started = Event()

Expand All @@ -308,12 +307,12 @@ def run(self):
async def __run_server(self):
self.__server = grpc_aio.server(interceptors=tuple(self.__interceptors))
dummy_pb2_grpc.add_DummyServiceServicer_to_server(self.__service, self.__server)
self.__server.add_insecure_port(self.__channel_descriptor)
self.port = self.__server.add_insecure_port("localhost:0")
await self.__server.start()
self.__started.set()
await self.__server.wait_for_termination()
if self.__optional_async_client_channel:
await self.__optional_async_client_channel.close()
if self.async_channel:
await self.async_channel.close()

def wait_for_server(self):
self.__started.wait()
Expand Down

0 comments on commit 9540840

Please sign in to comment.