Skip to content

Commit fce5e67

Browse files
committed
chore: Use running openRAG for tests
1 parent 61e1db1 commit fce5e67

10 files changed

Lines changed: 247 additions & 42 deletions

File tree

.github/workflows/unit_tests.yml

Lines changed: 107 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,129 @@ jobs:
1313
matrix:
1414
python-version: ["3.12"]
1515

16+
env:
17+
APP_PORT: 8080
18+
RAG_BASE_URL: http://localhost:8080
19+
1620
steps:
1721
- name: Checkout repository
1822
uses: actions/checkout@v4
1923

20-
- name: Set up Python
21-
uses: actions/setup-python@v5
24+
- name: env file
25+
run: |
26+
cp tests/.env-tests .env
27+
28+
# Move storage to /mnt to avoid disk space issues
29+
- name: Free up space and move Docker storage to /mnt
30+
run: |
31+
echo "Stopping Docker..."
32+
sudo systemctl stop docker
33+
34+
echo "Creating new Docker root at /mnt/docker..."
35+
sudo mkdir -p /mnt/docker
36+
sudo rsync -aqxP /var/lib/docker/ /mnt/docker
37+
38+
echo "Updating Docker daemon config..."
39+
echo '{"data-root": "/mnt/docker"}' | sudo tee /etc/docker/daemon.json
40+
41+
cat /etc/docker/daemon.json
42+
43+
echo "Restarting Docker..."
44+
sudo systemctl start docker
45+
46+
echo "Verifying Docker root directory:"
47+
docker info | grep "Docker Root Dir"
48+
49+
# Setup docker builds with cache
50+
- name: Set up Docker Buildx
51+
uses: docker/setup-buildx-action@v3
52+
53+
- name: Build openrag image
54+
uses: docker/build-push-action@v6
2255
with:
23-
python-version: ${{ matrix.python-version }}
56+
context: .
57+
file: ./Dockerfile
58+
tags: linagoraai/openrag:latest
59+
push: false
60+
cache-from: type=gha,scope=openrag
61+
cache-to: type=gha,mode=max,scope=openrag
2462

25-
- name: Install uv
63+
64+
# Start openRAG CPU
65+
- name: Start openRAG CPU
66+
run: |
67+
docker compose \
68+
-f docker-compose.yaml \
69+
-f docker-compose-ci.yaml \
70+
--profile cpu up -d \
71+
--no-build
72+
73+
- name: Check containers
2674
run: |
27-
curl -LsSf https://astral.sh/uv/install.sh | sh
28-
echo "$HOME/.local/bin" >> $GITHUB_PATH
75+
docker compose -f docker-compose.yaml -f docker-compose-ci.yaml --profile cpu ps
76+
77+
78+
- name: Wait for RAG API
79+
run: |
80+
echo "Waiting for RAG API on ${RAG_BASE_URL}..."
81+
for i in {1..60}; do
82+
if curl -fsS "${RAG_BASE_URL}/health_check" > /dev/null 2>&1; then
83+
echo "RAG API is up!"
84+
exit 0
85+
fi
86+
sleep 5
87+
done
88+
docker compose logs
89+
exit 1
90+
91+
# Install uv with cache
92+
- name: Install uv
93+
uses: astral-sh/setup-uv@v3
2994

3095
- name: Cache uv
3196
uses: actions/cache@v4
3297
with:
33-
path: |
34-
~/.cache/uv
98+
path: ~/.cache/uv
3599
key: uv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('**/pyproject.toml', '**/uv.lock') }}
36100
restore-keys: |
37101
uv-${{ runner.os }}-${{ matrix.python-version }}-
38102
39-
- name: Install dependencies with uv
103+
# Install deps for tests
104+
- name: Install with test dependencies
40105
run: |
41-
uv sync
106+
uv pip install -e ".[test]"
42107
108+
# Run actual tests
43109
- name: Run tests
44110
run: |
45-
uv run pytest
111+
uv run pytest -vv tests
112+
113+
114+
115+
- name: Dump vllm logs on failure
116+
if: failure()
117+
run: |
118+
echo "=== docker compose ps ==="
119+
docker compose -f docker-compose.yaml -f docker-compose-ci.yaml --profile cpu ps || true
120+
121+
echo "=== vllm-cpu logs ==="
122+
docker compose -f docker-compose.yaml -f docker-compose-ci.yaml --profile cpu logs vllm-cpu || true
123+
124+
echo "=== vllm-cpu container inspect (Health) ==="
125+
cid=$(docker ps -aqf "name=vllm-cpu" || true)
126+
if [ -n "$cid" ]; then
127+
docker inspect "$cid" | sed -n '/"State": {/,/}/p' || true
128+
fi
129+
130+
131+
# Dump logs on failure
132+
# - name: Dump logs on failure
133+
# if: failure()
134+
# run: docker compose logs
135+
136+
# Proper shutdown
137+
- name: Shutdown openRAG
138+
if: always()
139+
run: |
140+
docker compose down -v
141+

docker-compose-ci.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
services:
2+
vllm-cpu:
3+
image: openeuler/vllm-cpu:0.9.1-oe2403lts
4+
build: null
5+
environment:
6+
- VLLM_TARGET_DEVICE=cpu
7+
- VLLM_LOGGING_LEVEL=DEBUG
8+
- VLLM_CPU_KVCACHE_SPACE=8
9+
command: >
10+
--model ${EMBEDDER_MODEL_NAME:-jinaai/jina-embeddings-v3}
11+
--trust-remote-code
12+
--dtype float32
13+
--device cpu
14+
--max-num-seqs 8
15+
--max-model-len ${MAX_MODEL_LEN:-2048}
16+
profiles:
17+
- "cpu"
18+
security_opt:
19+
- seccomp=unconfined

extern/vllm/Dockerfile.cpu

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ ENV PATH="$VIRTUAL_ENV/bin:$PATH"
4141

4242
ENV UV_HTTP_TIMEOUT=500
4343

44-
RUN git clone https://github.com/vllm-project/vllm/ . && git checkout v0.9.2
44+
RUN git clone --depth=1 --branch v0.9.2 https://github.com/vllm-project/vllm/ .
4545

4646
# Install Python dependencies
4747
ENV PIP_EXTRA_INDEX_URL=${PIP_EXTRA_INDEX_URL}
@@ -67,8 +67,9 @@ ENV VLLM_CPU_DISABLE_AVX512=${VLLM_CPU_DISABLE_AVX512}
6767

6868
WORKDIR /workspace/
6969

70-
RUN uv pip install -r requirements/cpu-build.txt --torch-backend auto
71-
RUN uv pip install "transformers<4.54.0" # https://github.com/vllm-project/vllm-ascend/issues/2046
70+
RUN --mount=type=cache,target=/root/.cache/uv \
71+
uv pip install -r requirements/cpu-build.txt --torch-backend auto && \
72+
uv pip install "transformers<4.54.0" # https://github.com/vllm-project/vllm-ascend/issues/2046
7273

7374
RUN if [ "$GIT_REPO_CHECK" != 0 ]; then bash tools/check_repo.sh ; fi
7475

pyproject.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,14 @@ dev = [
5454
"pytest>=8.4.1",
5555
"pytest-asyncio>=1.3.0",
5656
]
57+
58+
[project.optional-dependencies]
59+
test = [
60+
"pytest",
61+
"httpx",
62+
"pytest-timeout"
63+
]
64+
5765
lint = [
5866
"ruff>=0.14.1",
5967
]

pytest.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[pytest]
22
testpaths =
33
openrag
4+
tests
45
pythonpath = ./openrag
56
python_files =
67
test_*.py

tests/.env-tests

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# LLM
2+
BASE_URL=http://localhost:8001/
3+
API_KEY=sk-
4+
MODEL=HuggingFaceTB/SmolLM2-135M-Instruct
5+
6+
# VLM (Visual Language Model) you can set it to the same as LLM if your LLM supports images
7+
VLM_BASE_URL=http://localhost:8002/
8+
VLM_API_KEY=sk-
9+
VLM_MODEL=HuggingFaceTB/SmolVLM-Instruct
10+
11+
## FastAPI App (no need to change it)
12+
# APP_PORT=8080 # this is the forwarded port
13+
# API_NUM_WORKERS=1 # Number of uvicorn workers for the FastAPI app
14+
15+
## To enable API HTTP authentication via HTTPBearer
16+
# AUTH_TOKEN=sk-openrag-1234
17+
18+
SAVE_UPLOADED_FILES=false
19+
20+
# Set to true, it will mount chainlit chat ui to the fastapi app (Default: true)
21+
WITH_CHAINLIT_UI=false
22+
23+
# RETRIEVER
24+
CONTEXTUAL_RETRIEVAL=false
25+
26+
# EMBEDDER
27+
EMBEDDER_MODEL_NAME=ibm-granite/granite-embedding-small-english-r2
28+
EMBEDDER_BASE_URL=http://vllm:8000/v1
29+
# EMBEDDER_API_KEY=EMPTY
30+
31+
# RERANKER
32+
RERANKER_ENABLED=true
33+
RERANKER_MODEL=Alibaba-NLP/gte-multilingual-reranker-base # or jinaai/jina-reranker-v2-base-multilingual
34+
35+
# Prompts
36+
PROMPTS_DIR=../prompts/example1
37+
38+
# Loaders
39+
PDFLoader=MarkerLoader
40+
XDG_CACHE_HOME=/app/model_weights
41+
# If using MarkerLoader
42+
MARKER_MAX_TASKS_PER_CHILD=1
43+
MARKER_MAX_PROCESSES=1
44+
MARKER_MIN_PROCESSES=1
45+
MARKER_POOL_SIZE=1 # Value au increment if you have a cluster of machines
46+
MARKER_NUM_GPUS=0.01
47+
48+
# Ray
49+
RAY_POOL_SIZE=1 # Number of serializer actor instances
50+
RAY_MAX_TASKS_PER_WORKER=2 # Number of tasks per serializer
51+
RAY_DEDUP_LOGS=0 # turns off ray log deduplication that appear across multiple processes
52+
RAY_ENABLE_RECORD_ACTOR_TASK_LOGGING=1 # # to enable logs at task level in ray dashboard
53+
RAY_task_retry_delay_ms=3000
54+
RAY_ENABLE_UV_RUN_RUNTIME_ENV=0 # critical with the newest version of UV
55+
RAY_memory_monitor_refresh_ms=0
56+
57+
# Indexer UI
58+
## 1. replace X.X.X.X with localhost if launching local or with your server IP
59+
## 2. APP_PORT with your FastAPI port (8080 by default)
60+
## 3. Base URL of the Indexer UI (required to prevent CORS issues). Replace INDEXERUI_PORT with its value
61+
## 4. Base URL of your FastAPI backend. Used by the frondend. Replace APP_PORT with the actual port number of your FastAPI backend
62+
63+
VITE_INCLUDE_CREDENTIALS=false # set true if fastapi authentification is enabled
64+
INDEXERUI_PORT=8060 # Port to expose the Indexer UI (default is 3042)
65+
INDEXERUI_URL='http://X.X.X.X:INDEXERUI_PORT'
66+
VITE_API_BASE_URL='http://X.X.X.X:APP_PORT'

tests/conftest.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# tests/conftest.py
2+
import os
3+
import time
4+
import httpx
5+
import pytest
6+
7+
8+
@pytest.fixture(scope="session")
9+
def base_url():
10+
return os.environ.get("RAG_BASE_URL", "http://localhost:8080")
11+
12+
13+
@pytest.fixture(scope="session", autouse=True)
14+
def wait_for_api(base_url):
15+
timeout = 60
16+
start = time.time()
17+
18+
while True:
19+
try:
20+
r = httpx.get(f"{base_url}/health_check", timeout=3)
21+
if r.status_code == 200:
22+
return
23+
except Exception:
24+
pass
25+
26+
if time.time() - start > timeout:
27+
raise RuntimeError("API not ready")
28+
29+
time.sleep(2)

tests/test_partitions.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# tests/test_partition.py
2+
import httpx
3+
import uuid
4+
5+
6+
def test_create_partition(base_url):
7+
client = httpx.Client(timeout=5)
8+
9+
partition_name = "tets-partition"
10+
r = client.post(f"{base_url}/partition/{partition_name}")
11+
assert r.status_code is 200
12+

tests/test_vectordb.py

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)