From b495a67bb873d820c419245520564d4e08614fd9 Mon Sep 17 00:00:00 2001 From: Arian Nasr Date: Sun, 31 May 2026 08:04:25 -0400 Subject: [PATCH 1/3] e2e(api): add initial functional tests & pytest configuration Signed-off-by: Arian Nasr --- e2e/requirements.txt | 3 +++ e2e/unit/api/test_api.py | 22 ++++++++++++++++++++++ e2e/unit/conftest.py | 10 ++++++++++ 3 files changed, 35 insertions(+) create mode 100644 e2e/requirements.txt create mode 100644 e2e/unit/api/test_api.py create mode 100644 e2e/unit/conftest.py diff --git a/e2e/requirements.txt b/e2e/requirements.txt new file mode 100644 index 0000000..9785649 --- /dev/null +++ b/e2e/requirements.txt @@ -0,0 +1,3 @@ +Werkzeug==3.1.8 +pytest==9.0.3 +requests==2.34.2 diff --git a/e2e/unit/api/test_api.py b/e2e/unit/api/test_api.py new file mode 100644 index 0000000..a7c02dc --- /dev/null +++ b/e2e/unit/api/test_api.py @@ -0,0 +1,22 @@ +import pytest +import requests +import io +import os +from werkzeug.utils import secure_filename + + +def test_api_ping(base_url): + response = requests.get(f'{base_url}/ping') + assert response.status_code == 200 + assert response.text == 'pong' + +def test_api_upload_non_audio_file(base_url, upload_folder): + files = {'file': ('test.txt', io.BytesIO(b'not an audio file'))} + expected_filename = os.path.join(upload_folder, secure_filename('test.txt')) + response = requests.post(f'{base_url}/', files=files) + assert response.status_code == 400 + assert "not allowed" in response.json().get("error", "") + assert not os.path.exists(expected_filename) + + if os.path.exists(expected_filename): + os.remove(expected_filename) \ No newline at end of file diff --git a/e2e/unit/conftest.py b/e2e/unit/conftest.py new file mode 100644 index 0000000..c9ec2b3 --- /dev/null +++ b/e2e/unit/conftest.py @@ -0,0 +1,10 @@ +import pytest +import os + +@pytest.fixture(scope='session') +def base_url(): + return os.getenv('BASE_URL', 'http://127.0.0.1:5001') + +@pytest.fixture(scope='session') +def upload_folder(): + return os.getenv('NAVIDROME_MUSIC_FOLDER', '/opt/navidrome/music') \ No newline at end of file -- 2.47.3 From 7599093d90c5aa27961052c39b332c65daccb1ad Mon Sep 17 00:00:00 2001 From: Arian Nasr Date: Sun, 31 May 2026 08:06:48 -0400 Subject: [PATCH 2/3] feat(e2e): add Dockerfile and entrypoint script for testing deb packages Signed-off-by: Arian Nasr --- Dockerfile.test | 36 ++++++++++++++++++++++++++++++++++++ e2e/test-entrypoint.sh | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 Dockerfile.test create mode 100644 e2e/test-entrypoint.sh diff --git a/Dockerfile.test b/Dockerfile.test new file mode 100644 index 0000000..ad4991b --- /dev/null +++ b/Dockerfile.test @@ -0,0 +1,36 @@ +# Navidome-Uploader Dockerfile for testing .deb packages +# Arian Nasr +# May 31, 2026 + +FROM debian:stable + +# Prevent interactive prompts +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update && apt-get install -y \ + curl \ + python3 \ + python3-venv \ + python3-pip \ + && rm -rf /var/lib/apt/lists/* + +# Copy the built deb package into the container +COPY output/*.deb /tmp/navidrome-uploader.deb + +RUN apt-get update && \ + apt-get install -y -f /tmp/navidrome-uploader.deb && \ + rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /opt/navidrome/music && \ + chown -R navidrome-uploader:navidrome-uploader /opt/navidrome/music + +COPY e2e/ /e2e/ + +RUN python3 -m venv /e2e/venv && \ + /e2e/venv/bin/pip install --no-cache-dir -r /e2e/requirements.txt + +RUN chmod +x /e2e/test-entrypoint.sh + +WORKDIR /e2e + +ENTRYPOINT ["/e2e/test-entrypoint.sh"] \ No newline at end of file diff --git a/e2e/test-entrypoint.sh b/e2e/test-entrypoint.sh new file mode 100644 index 0000000..252f913 --- /dev/null +++ b/e2e/test-entrypoint.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +export NAVIDROME_MUSIC_FOLDER="/opt/navidrome/music" +export BASE_URL="http://127.0.0.1:5001" + +# Start the app manually since systemd isn't running in the container +cd /opt/navidrome-uploader +su -s /bin/sh navidrome-uploader -c "/opt/navidrome-uploader/venv/bin/gunicorn --no-control-socket -c gunicorn.conf.py main:app" & + +APP_PID=$! + +TIMEOUT=30 +SERVICE_UP=0 + +while [ $TIMEOUT -gt 0 ]; do + if curl -s $BASE_URL/ping | grep -q "pong"; then + SERVICE_UP=1 + break + fi + sleep 1 + TIMEOUT=$((TIMEOUT-1)) +done + +if [ $SERVICE_UP -eq 0 ]; then + echo "Error: Service failed to start within the timeout period" + kill $APP_PID + exit 1 +fi + +cd /e2e + +/e2e/venv/bin/pytest unit/api/test_api.py + +# Capture the exit code of pytest +TEST_EXIT_CODE=$? + +kill $APP_PID + +exit $TEST_EXIT_CODE \ No newline at end of file -- 2.47.3 From 15bcd258af42dd72142df9d18b951dd3f6a5ad17 Mon Sep 17 00:00:00 2001 From: Arian Nasr Date: Sun, 31 May 2026 08:16:09 -0400 Subject: [PATCH 3/3] feat(ci): update workflow to include testing after deb package build Signed-off-by: Arian Nasr --- .gitea/workflows/build-deb.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/build-deb.yml b/.gitea/workflows/build-deb.yml index 32ca60a..47e6845 100644 --- a/.gitea/workflows/build-deb.yml +++ b/.gitea/workflows/build-deb.yml @@ -1,4 +1,4 @@ -name: Build Debian Package +name: Build and Test Debian Package on: push: @@ -10,7 +10,9 @@ on: jobs: build: runs-on: ubuntu-latest - + outputs: + deb_filename: ${{ steps.get_deb_name.outputs.filename }} + steps: - name: Checkout code uses: actions/checkout@v4 @@ -35,3 +37,26 @@ jobs: name: ${{ steps.get_deb_name.outputs.filename }} path: output/${{ steps.get_deb_name.outputs.filename }} retention-days: 5 + + test: + runs-on: ubuntu-latest + needs: build # only run tests if the build job succeeded + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Create output directory + run: mkdir -p output + + - name: Download Build Artifact + uses: actions/download-artifact@v3 + with: + name: ${{ needs.build.outputs.deb_filename }} + path: output/ + + - name: Build Test Docker Image + run: docker build -t uploader-tester -f Dockerfile.test . + + - name: Run E2E Test Suite + run: docker run --rm uploader-tester \ No newline at end of file -- 2.47.3