Skip to content

Commit 0b33c28

Browse files
authored
Added myworker example (#164)
1 parent 2cc4989 commit 0b33c28

File tree

9 files changed

+177
-0
lines changed

9 files changed

+177
-0
lines changed

.github/workflows/examples.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,39 @@ permissions:
2222
contents: read # to fetch code (actions/checkout)
2323

2424
jobs:
25+
myworker:
26+
runs-on: ${{ matrix.os }}
27+
28+
strategy:
29+
fail-fast: false
30+
matrix:
31+
python-version: ["3.12"]
32+
os: ["ubuntu-latest"]
33+
34+
steps:
35+
- name: Install apt packages
36+
if: startsWith(matrix.os, 'ubuntu-')
37+
run: |
38+
sudo apt update
39+
- uses: actions/checkout@v4
40+
- name: Set up Python ${{ matrix.python-version }}
41+
uses: actions/setup-python@v5
42+
with:
43+
python-version: ${{ matrix.python-version }}
44+
cache: 'pip'
45+
cache-dependency-path: '**/setup.py'
46+
- name: Install dependencies
47+
working-directory: examples/myworker
48+
run: |
49+
python -m pip install --upgrade pip
50+
pip install -r requirements.txt
51+
52+
- name: Run tests
53+
working-directory: examples/myworker
54+
timeout-minutes: 5
55+
run: |
56+
pytest -vv tests -n auto
57+
2558
django:
2659
runs-on: ${{ matrix.os }}
2760

examples/myworker/pytest.ini

Whitespace-only changes.

examples/myworker/requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
pytest>=7.4.4
2+
# pytest-celery>=1.0.0
3+
git+https://github.com/celery/pytest-celery.git
4+
pytest-xdist>=3.5.0

examples/myworker/tests/__init__.py

Whitespace-only changes.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import pytest
2+
3+
from pytest_celery.vendors.rabbitmq.defaults import RABBITMQ_PORTS
4+
from tests.myworker.myworker import myworker_container # noqa
5+
from tests.myworker.myworker import myworker_image # noqa
6+
from tests.myworker.myworker import myworker_worker # noqa
7+
8+
9+
@pytest.fixture
10+
def default_rabbitmq_broker_image() -> str:
11+
# Useful for debugging
12+
return "rabbitmq:management"
13+
14+
15+
@pytest.fixture
16+
def default_rabbitmq_broker_ports() -> dict:
17+
# Expose the management UI port
18+
ports = RABBITMQ_PORTS.copy()
19+
ports.update({"15672/tcp": None})
20+
return ports
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
FROM python:3.11-bookworm
2+
3+
# Create a user to run the worker
4+
RUN adduser --disabled-password --gecos "" test_user
5+
6+
# Install system dependencies
7+
RUN apt-get update && apt-get install -y build-essential git
8+
9+
# Set arguments
10+
ARG CELERY_LOG_LEVEL=INFO
11+
ARG CELERY_WORKER_NAME=my_worker
12+
ARG CELERY_WORKER_QUEUE=celery
13+
ENV LOG_LEVEL=$CELERY_LOG_LEVEL
14+
ENV WORKER_NAME=$CELERY_WORKER_NAME
15+
ENV WORKER_QUEUE=$CELERY_WORKER_QUEUE
16+
17+
# Install packages
18+
WORKDIR /src
19+
20+
COPY --chown=test_user:test_user requirements.txt .
21+
RUN pip install --no-cache-dir --upgrade pip
22+
RUN pip install -r ./requirements.txt
23+
RUN git clone https://github.com/celery/celery.git
24+
25+
WORKDIR /src/celery
26+
27+
RUN pip install -e .
28+
29+
# Switch to the test_user
30+
USER test_user
31+
32+
# Start the celery worker
33+
CMD celery -A app worker --loglevel=$LOG_LEVEL -n $WORKER_NAME@%h -Q $WORKER_QUEUE

examples/myworker/tests/myworker/__init__.py

Whitespace-only changes.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from __future__ import annotations
2+
3+
from typing import Any
4+
5+
import pytest
6+
from celery import Celery
7+
from pytest_docker_tools import build
8+
from pytest_docker_tools import container
9+
from pytest_docker_tools import fxtr
10+
11+
from pytest_celery import CeleryTestWorker
12+
from pytest_celery import CeleryWorkerContainer
13+
from pytest_celery import defaults
14+
15+
16+
class MyWorkerContainer(CeleryWorkerContainer):
17+
@property
18+
def client(self) -> Any:
19+
return self
20+
21+
@classmethod
22+
def version(cls) -> str:
23+
return "Celery main branch"
24+
25+
@classmethod
26+
def log_level(cls) -> str:
27+
return "INFO"
28+
29+
@classmethod
30+
def worker_name(cls) -> str:
31+
return "my_worker"
32+
33+
@classmethod
34+
def worker_queue(cls) -> str:
35+
return "myworker"
36+
37+
38+
myworker_image = build(
39+
path=".",
40+
dockerfile="tests/myworker/Dockerfile",
41+
tag="pytest-celery/myworker:example",
42+
buildargs=MyWorkerContainer.buildargs(),
43+
)
44+
45+
46+
myworker_container = container(
47+
image="{myworker_image.id}",
48+
environment=fxtr("default_worker_env"),
49+
network="{default_pytest_celery_network.name}",
50+
volumes={"{default_worker_volume.name}": defaults.DEFAULT_WORKER_VOLUME},
51+
wrapper_class=MyWorkerContainer,
52+
timeout=defaults.DEFAULT_WORKER_CONTAINER_TIMEOUT,
53+
)
54+
55+
56+
@pytest.fixture
57+
def myworker_worker(myworker_container: MyWorkerContainer, celery_setup_app: Celery) -> CeleryTestWorker:
58+
worker = CeleryTestWorker(myworker_container, app=celery_setup_app)
59+
yield worker
60+
worker.teardown()
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import pytest
2+
from celery.canvas import Signature
3+
from celery.result import AsyncResult
4+
5+
from pytest_celery import RESULT_TIMEOUT
6+
from pytest_celery import CeleryTestSetup
7+
from pytest_celery import CeleryTestWorker
8+
from pytest_celery import CeleryWorkerCluster
9+
from pytest_celery import ping
10+
11+
12+
@pytest.fixture
13+
def celery_worker_cluster(
14+
celery_worker: CeleryTestWorker,
15+
myworker_worker: CeleryTestWorker,
16+
) -> CeleryWorkerCluster:
17+
cluster = CeleryWorkerCluster(celery_worker, myworker_worker) # type: ignore
18+
yield cluster
19+
cluster.teardown()
20+
21+
22+
def test_ping(celery_setup: CeleryTestSetup):
23+
worker: CeleryTestWorker
24+
for worker in celery_setup.worker_cluster:
25+
sig: Signature = ping.s()
26+
res: AsyncResult = sig.apply_async(queue=worker.worker_queue)
27+
assert res.get(timeout=RESULT_TIMEOUT) == "pong"

0 commit comments

Comments
 (0)