Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
e4aa518
initial commit
theomonnom Apr 12, 2025
e3f839a
Update tool_context.py
theomonnom Apr 12, 2025
ac2eee6
Delete test.py
theomonnom Apr 12, 2025
0c0c7a8
ruff
theomonnom Apr 12, 2025
69e0844
e.g timeout toxic
theomonnom Apr 12, 2025
e3210c9
Update test_tts.py
theomonnom Apr 12, 2025
a02b823
wip
theomonnom Apr 14, 2025
35b2c73
Update vad.py
theomonnom Apr 14, 2025
71dc2ed
Merge branch 'theo/error-details' into theo/toxic-proxy
theomonnom Apr 14, 2025
6a1bb4d
wip
theomonnom Apr 14, 2025
20b37d8
Update conftest.py
theomonnom Apr 14, 2025
aaae1fc
Merge branch 'theo/detect-leaks' into theo/toxic-proxy
theomonnom Apr 14, 2025
b0ce122
Update conftest.py
theomonnom Apr 14, 2025
0f22249
Merge branch 'theo/detect-leaks' into theo/toxic-proxy
theomonnom Apr 14, 2025
50855d7
Update test_tts.py
theomonnom Apr 14, 2025
103dd04
wip
theomonnom Apr 14, 2025
102fd8b
Merge branch 'theo/detect-leaks' into theo/toxic-proxy
theomonnom Apr 14, 2025
5e7375f
Update conftest.py
theomonnom Apr 14, 2025
8eb9fb9
Update conftest.py
theomonnom Apr 14, 2025
6716746
Merge branch 'theo/detect-leaks' into theo/toxic-proxy
theomonnom Apr 14, 2025
2ca39b4
Update test_tts.py
theomonnom Apr 14, 2025
8ce5b1f
other TTSs
theomonnom Apr 14, 2025
3055c1a
Merge branch 'main' into theo/toxic-proxy
theomonnom Apr 14, 2025
dccab33
wip
theomonnom Apr 14, 2025
73e93b0
wip
theomonnom Apr 16, 2025
027bf20
Merge branch 'main' into theo/toxic-proxy
theomonnom Apr 16, 2025
a3c703b
Update tests.yml
theomonnom Apr 16, 2025
7facb1c
Update tests.yml
theomonnom Apr 16, 2025
11861dc
wip
theomonnom Apr 16, 2025
0f81b90
Update docker-compose.yml
theomonnom Apr 16, 2025
2a041a4
test
theomonnom Apr 16, 2025
4490072
wip
theomonnom Apr 16, 2025
ad183ea
wip
theomonnom Apr 16, 2025
959d474
Update tests.yml
theomonnom Apr 16, 2025
580fd93
Update docker-compose.yml
theomonnom Apr 16, 2025
53b226c
Update docker-compose.yml
theomonnom Apr 16, 2025
e153ffa
uv.lock
theomonnom Apr 16, 2025
bd700ea
run one job per plugin
theomonnom Apr 16, 2025
d036fed
Update tests.yml
theomonnom Apr 16, 2025
bb25472
Update tests.yml
theomonnom Apr 16, 2025
665eb38
Update tests.yml
theomonnom Apr 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 8 additions & 99 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,98 +3,29 @@ name: tests
on:
push:
branches:
# - main
- 0.x
- main
pull_request:
branches:
# - main
- 0.x
- main
workflow_dispatch:

jobs:
tests:
# Don't run tests for PRs on forks
# don't run tests for PRs on forks
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.fork == false
strategy:
fail-fast: false
matrix:
os: [
# disabled Intel Macs due to pytorch 2.3+ not supporting it
# macos-14-large,
macos-latest,
windows-latest,
ubuntu-latest,
ubuntu-24.04-arm,
]
python_version: ["3.9", "3.12"]
test_group: ["base"]
include:
# Include llm, stt, and tts tests only on Ubuntu 20.04 with Python 3.9
- os: ubuntu-latest
python_version: "3.12"
test_group: llm
- os: ubuntu-latest
python_version: "3.12"
test_group: stt
- os: ubuntu-latest
python_version: "3.12"
test_group: tts
plugin: [cartesia, aws, azure, deepgram, elevenlabs, google, groq, neuphonic, playai, resemble, rime]

runs-on: ${{ matrix.os }}
name: ${{ matrix.test_group }} — ${{ matrix.os }}) (py${{ matrix.python_version }})
runs-on: ubuntu-latest
name: livekit-plugins-${{ matrix.plugin }}
steps:
- uses: actions/checkout@v4
with:
submodules: true
lfs: true

- name: Cache packages
uses: actions/cache@v4
with:
path: |
/var/cache/apt/archives
~/Library/Caches/Homebrew
C:\ProgramData\chocolatey\lib\ffmpeg
key: ${{ runner.os }}-cache
restore-keys: |
${{ runner.os }}-cache

- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python_version }}
cache: "pip"

- name: Install ffmpeg (Linux)
if: ${{ startsWith(matrix.os, 'ubuntu') }}
run: sudo apt-get update && sudo apt-get install -y ffmpeg

# Azure plugin fails with OpenSSL3, and Ubuntu 22.04 does not include libssl1.1 in its repos
- name: Install libssl 1.1 (Linux 22.04)
if: ${{ matrix.os == 'ubuntu-24.04-arm' }}
run: |
wget https://old-releases.ubuntu.com/ubuntu/pool/main/o/openssl/libssl1.1_1.1.1-1ubuntu2.1_arm64.deb
wget https://old-releases.ubuntu.com/ubuntu/pool/main/o/openssl/libssl-dev_1.1.1-1ubuntu2.1_arm64.deb
sudo dpkg -i libssl1.1_1.1.1-1ubuntu2.1_arm64.deb
sudo dpkg -i libssl-dev_1.1.1-1ubuntu2.1_arm64.deb

- name: Install ffmpeg (macOS)
if: ${{ startsWith(matrix.os, 'macos') }}
run: brew install ffmpeg

- name: Install ffmpeg (Windows)
if: ${{ startsWith(matrix.os, 'windows') }}
run: choco install ffmpeg

- name: Install packages
shell: bash
run: |
pip install pytest pytest-asyncio pytest-timeout './livekit-agents[codecs]' psutil
pip install -r ./tests/test-requirements.txt
./livekit-plugins/install_local.sh

- name: Run tests
shell: bash
env:
PLUGIN: ${{ matrix.plugin }}
LIVEKIT_URL: ${{ secrets.LIVEKIT_URL }}
LIVEKIT_API_KEY: ${{ secrets.LIVEKIT_API_KEY }}
LIVEKIT_API_SECRET: ${{ secrets.LIVEKIT_API_SECRET }}
Expand All @@ -115,31 +46,9 @@ jobs:
RIME_API_KEY: ${{ secrets.RIME_API_KEY }}
SPEECHMATICS_API_KEY: ${{ secrets.SPEECHMATICS_API_KEY }}
GOOGLE_APPLICATION_CREDENTIALS: google.json
PYTEST_ADDOPTS: "--color=yes"
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
NEUPHONIC_API_KEY: ${{ secrets.NEUPHONIC_API_KEY }}
RESEMBLE_API_KEY: ${{ secrets.RESEMBLE_API_KEY }}
working-directory: tests
run: |
echo "$GOOGLE_CREDENTIALS_JSON" > google.json

case "${{ matrix.test_group }}" in
base)
test_files="test_aio.py test_tokenizer.py test_vad.py test_ipc.py test_tts_fallback.py test_stt_fallback.py test_message_change.py test_build_func_desc.py test_create_func.py test_connection_pool.py"
;;
llm)
test_files="test_llm.py"
;;
stt)
test_files="test_stt.py"
;;
tts)
test_files="test_tts.py"
;;
*)
echo "Unknown test group: ${{ matrix.test_group }}"
exit 1
;;
esac
pytest $test_files
run: make test
2 changes: 1 addition & 1 deletion livekit-agents/livekit/agents/llm/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@
val = await self._event_aiter.__anext__()
except StopAsyncIteration:
if not self._task.cancelled() and (exc := self._task.exception()):
raise exc from None
raise exc

Check failure on line 228 in livekit-agents/livekit/agents/llm/llm.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (B904)

livekit-agents/livekit/agents/llm/llm.py:228:17: B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling

raise StopAsyncIteration from None

Expand Down
2 changes: 1 addition & 1 deletion livekit-agents/livekit/agents/stt/stt.py
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@
val = await self._event_aiter.__anext__()
except StopAsyncIteration:
if not self._task.cancelled() and (exc := self._task.exception()):
raise exc from None
raise exc

Check failure on line 340 in livekit-agents/livekit/agents/stt/stt.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (B904)

livekit-agents/livekit/agents/stt/stt.py:340:17: B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling

raise StopAsyncIteration from None

Expand Down
5 changes: 2 additions & 3 deletions livekit-agents/livekit/agents/tts/tts.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@
val = await self._event_aiter.__anext__()
except StopAsyncIteration:
if not self._synthesize_task.cancelled() and (exc := self._synthesize_task.exception()):
raise exc from None
raise exc

Check failure on line 253 in livekit-agents/livekit/agents/tts/tts.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (B904)

livekit-agents/livekit/agents/tts/tts.py:253:17: B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling

raise StopAsyncIteration from None

Expand Down Expand Up @@ -373,7 +373,6 @@
cancelled=self._task.cancelled(),
label=self._tts._label,
streamed=True,
error=None,
)
self._tts.emit("metrics_collected", metrics)

Expand Down Expand Up @@ -446,7 +445,7 @@
val = await self._event_aiter.__anext__()
except StopAsyncIteration:
if not self._task.cancelled() and (exc := self._task.exception()):
raise exc from None
raise exc

Check failure on line 448 in livekit-agents/livekit/agents/tts/tts.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (B904)

livekit-agents/livekit/agents/tts/tts.py:448:17: B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling

raise StopAsyncIteration from None

Expand Down
4 changes: 2 additions & 2 deletions livekit-agents/livekit/agents/vad.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@
self._input_ch.close()

async def aclose(self) -> None:
"""Close ths stream immediately"""
"""Close the stream immediately"""
self._input_ch.close()
await aio.cancel_and_wait(self._task)
self._event_ch.close()
Expand All @@ -162,7 +162,7 @@
val = await self._event_aiter.__anext__()
except StopAsyncIteration:
if not self._task.cancelled() and (exc := self._task.exception()):
raise exc from None
raise exc

Check failure on line 165 in livekit-agents/livekit/agents/vad.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (B904)

livekit-agents/livekit/agents/vad.py:165:17: B904 Within an `except` clause, raise exceptions with `raise ... from err` or `raise ... from None` to distinguish them from errors in exception handling

raise StopAsyncIteration from None

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from __future__ import annotations

import asyncio
from dataclasses import dataclass

import boto3

Check failure on line 18 in livekit-plugins/livekit-plugins-aws/livekit/plugins/aws/tts.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (F401)

livekit-plugins/livekit-plugins-aws/livekit/plugins/aws/tts.py:18:8: F401 `boto3` imported but unused
import aioboto3
import aiohttp

Expand Down Expand Up @@ -182,14 +183,14 @@
finally:
await utils.aio.gracefully_cancel(push_task)

except asyncio.TimeoutError as e:
raise APITimeoutError() from e
except asyncio.TimeoutError:
raise APITimeoutError() from None
except aiohttp.ClientResponseError as e:
raise APIStatusError(
message=e.message,
status_code=e.status,
request_id=request_id,
body=None,
) from e
) from None
except Exception as e:
raise APIConnectionError() from e
Original file line number Diff line number Diff line change
Expand Up @@ -272,15 +272,15 @@ async def _run(self) -> None:
for frame in bstream.flush():
emitter.push(frame)
emitter.flush()
except asyncio.TimeoutError as e:
raise APITimeoutError() from e
except asyncio.TimeoutError:
raise APITimeoutError() from None
except aiohttp.ClientResponseError as e:
raise APIStatusError(
message=e.message,
status_code=e.status,
request_id=None,
body=None,
) from e
) from None
except Exception as e:
raise APIConnectionError() from e

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import os

import openai
Expand Down
1 change: 0 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ convention = "google"
[tool.pytest.ini_options]
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "function"
timeout = 120
addopts = ["--import-mode=importlib", "--ignore=examples"]


Expand Down
9 changes: 9 additions & 0 deletions tests/Dockerfile.tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM python:3.9-slim

ENV PYTHONUNBUFFERED=1

RUN apt-get update && apt-get install -y curl strace procps

RUN pip install --no-cache-dir uv

WORKDIR /app
19 changes: 19 additions & 0 deletions tests/Dockerfile.toxiproxy
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM golang:1.23-alpine AS builder

RUN apk add --no-cache git make

WORKDIR /build

RUN git clone https://github.com/Shopify/toxiproxy.git .

RUN make build

RUN ls -al dist

FROM alpine:3.18

RUN apk add --no-cache ca-certificates
RUN apk add --no-cache curl

COPY --from=builder /build/dist/toxiproxy-server /usr/local/bin/toxiproxy-server
COPY --from=builder /build/dist/toxiproxy-cli /usr/local/bin/toxiproxy-cli
29 changes: 29 additions & 0 deletions tests/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
PLUGIN ?=

.PHONY: test up down

up:
@if [ -f ../.env ]; then \
echo "Found .env file. Using it..."; \
docker compose --env-file ../.env build; \
docker compose --env-file ../.env up -d; \
else \
echo "No .env file found. Running without it..."; \
docker compose build; \
docker compose up -d; \
fi

down:
docker compose down

test: up
@docker compose exec app bash -c "\
until curl -sf http://toxiproxy:8474/proxies; do \
echo 'Waiting for toxiproxy...'; \
sleep 1; \
done"
echo 'Toxiproxy is ready'

docker compose exec app uv sync --all-extras --dev
docker compose exec -e PLUGIN="$(PLUGIN)" app uv run pytest -s --color=yes --tb=short tests/test_tts.py --show-capture=all
$(MAKE) down
Loading
Loading