Skip to content

Commit

Permalink
New Example: examples/vhost
Browse files Browse the repository at this point in the history
  • Loading branch information
Nusnus committed Mar 17, 2024
1 parent ed67255 commit ad766c5
Show file tree
Hide file tree
Showing 8 changed files with 219 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,36 @@ jobs:
timeout-minutes: 10
run: |
pytest -xsv tests
vhost:
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
python-version: ["3.12"]
os: ["ubuntu-latest"]

steps:
- name: Install apt packages
if: startsWith(matrix.os, 'ubuntu-')
run: |
sudo apt update
- uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
cache-dependency-path: '**/setup.py'
- name: Install dependencies
working-directory: examples/vhost
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
working-directory: examples/vhost
timeout-minutes: 10
run: |
pytest -xsv tests
1 change: 1 addition & 0 deletions docs/userguide/examples/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,6 @@ Every example is an independent project and is tested via the
rabbitmq_management
range
myutils
vhost
django
hybrid_setup
105 changes: 105 additions & 0 deletions docs/userguide/examples/vhost.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
.. _examples_vhost:

=======
vhost
=======

:Release: |version|
:Date: |today|

.. contents::
:local:
:depth: 2

Description
===========

This example project demonstrates how to use a single Redis container as both a broker and a result backend,
using different vhosts for each purpose.

Breakdown
=========

File Structure
~~~~~~~~~~~~~~

The following diagram lists the relevant files in the project.

.. code-block:: text
rabbitmq_management/
├── tests/
│ ├── __init__.py
│ ├── conftest.py
│ └── test_vhost.py
└── requirements.txt
conftest.py
~~~~~~~~~~~

We create our own Redis container, and then use it as both a broker and a result backend.

.. code-block:: python
redis_image = fetch(repository=REDIS_IMAGE)
redis_test_container: RedisContainer = container(
image="{redis_image.id}",
ports=REDIS_PORTS,
environment=REDIS_ENV,
network="{default_pytest_celery_network.name}",
wrapper_class=RedisContainer,
timeout=REDIS_CONTAINER_TIMEOUT,
)
As the default vhost is "0", we can use it as the broker, and create a new vhost for the result backend.

.. code-block:: python
@pytest.fixture
def redis_broker(redis_test_container: RedisContainer) -> RedisTestBroker:
broker = RedisTestBroker(redis_test_container)
yield broker
broker.teardown()
@pytest.fixture
def celery_broker_cluster(redis_broker: RedisTestBroker) -> CeleryBrokerCluster:
cluster = CeleryBrokerCluster(redis_broker)
yield cluster
cluster.teardown()
For the backend, we need to change some settings to use a different vhost, so we create our own
Redis backend and work it out there.

.. code-block:: python
class MyRedisTestBackend(RedisTestBackend):
def config(self, *args: tuple, **kwargs: dict) -> dict:
return super().config(vhost=1, *args, **kwargs)
Lastly, we add our backend that uses the same Redis container as the broker and our
``MyRedisTestBackend`` class.

.. code-block:: python
@pytest.fixture
def redis_backend(redis_test_container: RedisContainer) -> MyRedisTestBackend:
backend = MyRedisTestBackend(redis_test_container)
yield backend
backend.teardown()
@pytest.fixture
def celery_backend_cluster(redis_backend: MyRedisTestBackend) -> CeleryBackendCluster:
cluster = CeleryBackendCluster(redis_backend)
yield cluster
cluster.teardown()
test_vhost.py
~~~~~~~~~~~~~

We can now run tests that will share the same Redis container for both the broker and the result backend components.

.. literalinclude:: ../../../examples/vhost/tests/test_vhost.py
:language: python
:caption: examples.vhost.tests.test_vhost.py
5 changes: 5 additions & 0 deletions examples/vhost/pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[pytest]
log_cli = true
log_cli_level = INFO
log_cli_format = %(asctime)s [%(levelname)8s] %(message)s (%(filename)s:%(lineno)s)
log_cli_date_format = %Y-%m-%d %H:%M:%S
3 changes: 3 additions & 0 deletions examples/vhost/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pytest>=7.4.4
pytest-xdist>=3.5.0
pytest-celery[all]@git+https://github.com/celery/pytest-celery.git
Empty file.
56 changes: 56 additions & 0 deletions examples/vhost/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import pytest
from pytest_docker_tools import container
from pytest_docker_tools import fetch

from pytest_celery import REDIS_CONTAINER_TIMEOUT
from pytest_celery import REDIS_ENV
from pytest_celery import REDIS_IMAGE
from pytest_celery import REDIS_PORTS
from pytest_celery import CeleryBackendCluster
from pytest_celery import CeleryBrokerCluster
from pytest_celery import RedisContainer
from pytest_celery import RedisTestBackend
from pytest_celery import RedisTestBroker

redis_image = fetch(repository=REDIS_IMAGE)
redis_test_container: RedisContainer = container(
image="{redis_image.id}",
ports=REDIS_PORTS,
environment=REDIS_ENV,
network="{default_pytest_celery_network.name}",
wrapper_class=RedisContainer,
timeout=REDIS_CONTAINER_TIMEOUT,
)


@pytest.fixture
def redis_broker(redis_test_container: RedisContainer) -> RedisTestBroker:
broker = RedisTestBroker(redis_test_container)
yield broker
broker.teardown()


@pytest.fixture
def celery_broker_cluster(redis_broker: RedisTestBroker) -> CeleryBrokerCluster:
cluster = CeleryBrokerCluster(redis_broker)
yield cluster
cluster.teardown()


class MyRedisTestBackend(RedisTestBackend):
def config(self, *args: tuple, **kwargs: dict) -> dict:
return super().config(vhost=1, *args, **kwargs)


@pytest.fixture
def redis_backend(redis_test_container: RedisContainer) -> MyRedisTestBackend:
backend = MyRedisTestBackend(redis_test_container)
yield backend
backend.teardown()


@pytest.fixture
def celery_backend_cluster(redis_backend: MyRedisTestBackend) -> CeleryBackendCluster:
cluster = CeleryBackendCluster(redis_backend)
yield cluster
cluster.teardown()
16 changes: 16 additions & 0 deletions examples/vhost/tests/test_vhost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from pytest_celery import RESULT_TIMEOUT
from pytest_celery import CeleryTestSetup
from pytest_celery import ping


class TestVhost:
def test_ping(self, celery_setup: CeleryTestSetup):
assert ping.s().delay().get(timeout=RESULT_TIMEOUT) == "pong"

def test_vhost(self, celery_setup: CeleryTestSetup):
assert celery_setup.app.conf.broker_url[:-1] == celery_setup.app.conf.result_backend[:-1]
assert celery_setup.app.conf.broker_url.endswith("/0")
assert celery_setup.app.conf.result_backend.endswith("/1")

def test_single_redis(self, celery_setup: CeleryTestSetup):
assert celery_setup.broker.container.id == celery_setup.backend.container.id

0 comments on commit ad766c5

Please sign in to comment.