From 7ecb64158674297fe50d67787fe5acf3c5a6bb35 Mon Sep 17 00:00:00 2001 From: Fernando Governatore Date: Fri, 15 Jan 2021 20:50:24 -0300 Subject: [PATCH 01/15] Adds MQTT backend --- README.md | 4 ++- broadcaster/_backends/mqtt.py | 39 ++++++++++++++++++++ broadcaster/_base.py | 6 ++++ docker-compose.yaml | 6 ++++ example/README.md | 1 + example/requirements.txt | 2 +- scripts/start | 7 ++-- setup.py | 67 +++++++++++++++++++++++++++++++++++ tests/test_broadcast.py | 10 ++++++ 9 files changed, 137 insertions(+), 5 deletions(-) create mode 100644 broadcaster/_backends/mqtt.py create mode 100644 setup.py diff --git a/README.md b/README.md index d11a9ed..48377f5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Broadcaster helps you develop realtime streaming functionality by providing a simple broadcast API onto a number of different backend services. -It currently supports [Redis PUB/SUB](https://redis.io/topics/pubsub), [Apache Kafka](https://kafka.apache.org/), and [Postgres LISTEN/NOTIFY](https://www.postgresql.org/docs/current/sql-notify.html), plus a simple in-memory backend, that you can use for local development or during testing. +It currently supports [Redis PUB/SUB](https://redis.io/topics/pubsub), [Apache Kafka](https://kafka.apache.org/), and [Postgres LISTEN/NOTIFY](https://www.postgresql.org/docs/current/sql-notify.html), [MQTT](https://mqtt.org/) plus a simple in-memory backend, that you can use for local development or during testing. WebSockets Demo @@ -78,6 +78,7 @@ Python 3.8+ * `pip install broadcaster[redis]` * `pip install broadcaster[postgres]` * `pip install broadcaster[kafka]` +* `pip install broadcaster[mqtt]` ## Available backends @@ -85,6 +86,7 @@ Python 3.8+ * `Broadcast("redis://localhost:6379")` * `Broadcast("postgres://localhost:5432/broadcaster")` * `Broadcast("kafka://localhost:9092")` +* `Broadcast("mqtt://localhost:1883")` ### Using custom backends diff --git a/broadcaster/_backends/mqtt.py b/broadcaster/_backends/mqtt.py new file mode 100644 index 0000000..614a466 --- /dev/null +++ b/broadcaster/_backends/mqtt.py @@ -0,0 +1,39 @@ +import asyncio_mqtt +import typing +from urllib.parse import urlparse +from .base import BroadcastBackend +from .._base import Event +from contextlib import AsyncExitStack, asynccontextmanager + +class MqttBackend(BroadcastBackend): + def __init__(self, url: str): + parsed_url = urlparse(url) + self._host = parsed_url.hostname or "localhost" + self._port = 8883 if parsed_url.scheme == 'mqtts' else 1883 + self._port = parsed_url.port or self._port + + async def connect(self) -> None: + self.stack = AsyncExitStack() + + self.client = asyncio_mqtt.Client(self._host, port=self._port) + self.messages = self.client.filtered_messages('#') + + self.client = await self.stack.enter_async_context(self.client) + self.messages = await self.stack.enter_async_context(self.messages) + + async def disconnect(self) -> None: + await self.stack.aclose() + + async def subscribe(self, channel: str) -> None: + await self.client.subscribe(channel) + + async def unsubscribe(self, channel: str) -> None: + await self.client.unsubscribe(channel) + + async def publish(self, channel: str, message: typing.Any) -> None: + await self.client.publish(channel, message, retain=False) + + async def next_published(self) -> Event: + async for message in self.messages: + return Event(channel=message.topic, message=message.payload) + diff --git a/broadcaster/_base.py b/broadcaster/_base.py index 0166034..f00dce1 100644 --- a/broadcaster/_base.py +++ b/broadcaster/_base.py @@ -52,6 +52,12 @@ def _create_backend(self, url: str) -> BroadcastBackend: from broadcaster._backends.memory import MemoryBackend return MemoryBackend(url) + + elif parsed_url.scheme in ("mqtt", "mqtts"): + from ._backends.mqtt import MqttBackend + + return MqttBackend(url) + raise ValueError(f"Unsupported backend: {parsed_url.scheme}") async def __aenter__(self) -> Broadcast: diff --git a/docker-compose.yaml b/docker-compose.yaml index 60073b4..b38a1ba 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -36,3 +36,9 @@ services: - POSTGRES_USER=postgres ports: - 5432:5432 + mqtt: + image: "eclipse-mosquitto" + hostname: mqtt + ports: + - 1883:1883 + - 8883:8883 diff --git a/example/README.md b/example/README.md index 069d978..26b8ef0 100644 --- a/example/README.md +++ b/example/README.md @@ -22,3 +22,4 @@ In order to run the app with different backends, you have to set the env | kafka | `export BROADCAST_URL=kafka://localhost:9092` | `docker-compose up kafka` | | redis | `export BROADCAST_URL=redis://localhost:6379` | `docker-compose up redis` | | postgres | `export BROADCAST_URL=postgres://localhost:5432/broadcaster` | `docker-compose up postgres` | +| mqtt | `export BROADCAST_URL=mqtt://localhost:1883` | `docker-compose up mqtt` | diff --git a/example/requirements.txt b/example/requirements.txt index 44835e5..5fccb92 100644 --- a/example/requirements.txt +++ b/example/requirements.txt @@ -2,4 +2,4 @@ uvicorn websockets starlette jinja2 -broadcaster[redis,postgres,kafka] +broadcaster[redis,postgres,kafka,mqtt] diff --git a/scripts/start b/scripts/start index 188ffae..9c08216 100755 --- a/scripts/start +++ b/scripts/start @@ -1,12 +1,13 @@ #!/bin/sh -e -# Accepted values: postgres, kafka, redis +# Accepted values: postgres, kafka, redis, mqtt # If no variable provided all services will start if [ -n "$1" ]; then - if [ "$1" != "kafka" ] && [ "$1" != "redis" ] && [ "$1" != "postgres" ]; then + if [ "$1" != "kafka" ] && [ "$1" != "redis" ] && [ "$1" != "postgres" ] && [ "$1" != "mqtt" ]; then echo "Not a valid value. Choose one or none: kafka redis - postgres "; + postgres + mqtt "; exit 1; fi fi diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..8212b0e --- /dev/null +++ b/setup.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +import os +import re + +from setuptools import setup + + +def get_version(package): + """ + Return package version as listed in `__version__` in `init.py`. + """ + with open(os.path.join(package, "__init__.py")) as f: + return re.search("__version__ = ['\"]([^'\"]+)['\"]", f.read()).group(1) + + +def get_long_description(): + """ + Return the README. + """ + with open("README.md", encoding="utf8") as f: + return f.read() + + +def get_packages(package): + """ + Return root package and all sub-packages. + """ + return [ + dirpath + for dirpath, dirnames, filenames in os.walk(package) + if os.path.exists(os.path.join(dirpath, "__init__.py")) + ] + + +setup( + name="broadcaster", + python_requires=">=3.7", + version=get_version("broadcaster"), + url="https://github.com/encode/broadcaster", + license="BSD", + description="Simple broadcast channels.", + long_description=get_long_description(), + long_description_content_type="text/markdown", + author="Tom Christie", + author_email="tom@tomchristie.com", + packages=get_packages("broadcaster"), + extras_require={ + "redis": ["asyncio-redis"], + "postgres": ["asyncpg"], + "kafka": ["aiokafka"], + "mqtt": ["asyncio-mqtt"] + }, + classifiers=[ + "Development Status :: 3 - Alpha", + "Environment :: Web Environment", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Topic :: Internet :: WWW/HTTP", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + ], + # zip_safe=False, +) diff --git a/tests/test_broadcast.py b/tests/test_broadcast.py index b516ee2..d9ae916 100644 --- a/tests/test_broadcast.py +++ b/tests/test_broadcast.py @@ -76,6 +76,16 @@ async def test_kafka(): assert event.message == "hello" +@pytest.mark.asyncio +async def test_mqtt(): + async with Broadcast("mqtt://localhost:1883") as broadcast: + async with broadcast.subscribe("chatroom") as subscriber: + await broadcast.publish("chatroom", "hello") + event = await subscriber.get() + assert event.channel == "chatroom" + assert event.message.decode("utf-8") == "hello" + + @pytest.mark.asyncio async def test_custom(): backend = CustomBackend("") From 912d9ce525dadb080020b84b6997d39a1ca2ac9c Mon Sep 17 00:00:00 2001 From: Marcelo Trylesinski Date: Sat, 20 Aug 2022 13:13:31 +0200 Subject: [PATCH 02/15] Update setup.py --- setup.py | 67 -------------------------------------------------------- 1 file changed, 67 deletions(-) delete mode 100644 setup.py diff --git a/setup.py b/setup.py deleted file mode 100644 index 8212b0e..0000000 --- a/setup.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- - -import os -import re - -from setuptools import setup - - -def get_version(package): - """ - Return package version as listed in `__version__` in `init.py`. - """ - with open(os.path.join(package, "__init__.py")) as f: - return re.search("__version__ = ['\"]([^'\"]+)['\"]", f.read()).group(1) - - -def get_long_description(): - """ - Return the README. - """ - with open("README.md", encoding="utf8") as f: - return f.read() - - -def get_packages(package): - """ - Return root package and all sub-packages. - """ - return [ - dirpath - for dirpath, dirnames, filenames in os.walk(package) - if os.path.exists(os.path.join(dirpath, "__init__.py")) - ] - - -setup( - name="broadcaster", - python_requires=">=3.7", - version=get_version("broadcaster"), - url="https://github.com/encode/broadcaster", - license="BSD", - description="Simple broadcast channels.", - long_description=get_long_description(), - long_description_content_type="text/markdown", - author="Tom Christie", - author_email="tom@tomchristie.com", - packages=get_packages("broadcaster"), - extras_require={ - "redis": ["asyncio-redis"], - "postgres": ["asyncpg"], - "kafka": ["aiokafka"], - "mqtt": ["asyncio-mqtt"] - }, - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Web Environment", - "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Topic :: Internet :: WWW/HTTP", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - ], - # zip_safe=False, -) From c2bad5cec014b954b1591a5908d1b55cb9409db2 Mon Sep 17 00:00:00 2001 From: Fernando Date: Sat, 20 Aug 2022 16:58:40 -0300 Subject: [PATCH 03/15] Uses double quotes for strings on new MQTT code --- broadcaster/_backends/mqtt.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/broadcaster/_backends/mqtt.py b/broadcaster/_backends/mqtt.py index 614a466..c9220ba 100644 --- a/broadcaster/_backends/mqtt.py +++ b/broadcaster/_backends/mqtt.py @@ -9,14 +9,14 @@ class MqttBackend(BroadcastBackend): def __init__(self, url: str): parsed_url = urlparse(url) self._host = parsed_url.hostname or "localhost" - self._port = 8883 if parsed_url.scheme == 'mqtts' else 1883 + self._port = 8883 if parsed_url.scheme == "mqtts" else 1883 self._port = parsed_url.port or self._port async def connect(self) -> None: self.stack = AsyncExitStack() self.client = asyncio_mqtt.Client(self._host, port=self._port) - self.messages = self.client.filtered_messages('#') + self.messages = self.client.filtered_messages("#") self.client = await self.stack.enter_async_context(self.client) self.messages = await self.stack.enter_async_context(self.messages) From 89bb5794d12e92fa4f840f85d13255e104cd5cc2 Mon Sep 17 00:00:00 2001 From: Fernando Date: Sat, 20 Aug 2022 16:59:31 -0300 Subject: [PATCH 04/15] Fixes linting on new MQTT code --- broadcaster/_backends/mqtt.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/broadcaster/_backends/mqtt.py b/broadcaster/_backends/mqtt.py index c9220ba..d77a2f9 100644 --- a/broadcaster/_backends/mqtt.py +++ b/broadcaster/_backends/mqtt.py @@ -1,9 +1,12 @@ -import asyncio_mqtt import typing +from contextlib import AsyncExitStack from urllib.parse import urlparse -from .base import BroadcastBackend + +import asyncio_mqtt + from .._base import Event -from contextlib import AsyncExitStack, asynccontextmanager +from .base import BroadcastBackend + class MqttBackend(BroadcastBackend): def __init__(self, url: str): @@ -36,4 +39,3 @@ async def publish(self, channel: str, message: typing.Any) -> None: async def next_published(self) -> Event: async for message in self.messages: return Event(channel=message.topic, message=message.payload) - From b3b85989104b82d96e0a7a34cb4875dcab95ba76 Mon Sep 17 00:00:00 2001 From: Fernando Date: Sat, 20 Aug 2022 17:01:48 -0300 Subject: [PATCH 05/15] Fixes blank lines in new MQTT code --- broadcaster/_backends/mqtt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/broadcaster/_backends/mqtt.py b/broadcaster/_backends/mqtt.py index d77a2f9..c580642 100644 --- a/broadcaster/_backends/mqtt.py +++ b/broadcaster/_backends/mqtt.py @@ -8,6 +8,7 @@ from .base import BroadcastBackend + class MqttBackend(BroadcastBackend): def __init__(self, url: str): parsed_url = urlparse(url) From d7d1090b803f7017b4a391acc6aa2183c5d82452 Mon Sep 17 00:00:00 2001 From: Fernando Date: Sat, 20 Aug 2022 17:06:30 -0300 Subject: [PATCH 06/15] Removes unused import from new MQTT code --- broadcaster/_backends/mqtt.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/broadcaster/_backends/mqtt.py b/broadcaster/_backends/mqtt.py index c580642..03bfedf 100644 --- a/broadcaster/_backends/mqtt.py +++ b/broadcaster/_backends/mqtt.py @@ -7,6 +7,9 @@ from .._base import Event from .base import BroadcastBackend +from contextlib import AsyncExitStack, asynccontextmanager + +from contextlib import AsyncExitStack class MqttBackend(BroadcastBackend): From 4ee12fa453d018cc40906f306a79aeadbae4bfb5 Mon Sep 17 00:00:00 2001 From: Fernando Governatore Date: Sat, 20 Aug 2022 17:31:56 -0300 Subject: [PATCH 07/15] Works around mypy problem MyPy would complain the method has a "missing return" even though the return is explicit. This seems to happen because of the "async" block. Putting the value that was returned in a variable and returning the variable from outside the "async for" block makes MyPy happy. --- broadcaster/_backends/mqtt.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/broadcaster/_backends/mqtt.py b/broadcaster/_backends/mqtt.py index 03bfedf..9c868f8 100644 --- a/broadcaster/_backends/mqtt.py +++ b/broadcaster/_backends/mqtt.py @@ -42,4 +42,7 @@ async def publish(self, channel: str, message: typing.Any) -> None: async def next_published(self) -> Event: async for message in self.messages: - return Event(channel=message.topic, message=message.payload) + event = Event(channel=message.topic, message=message.payload) + break + + return event From 9e6fe71a2a0012e07bd840142115f8c91aa6765c Mon Sep 17 00:00:00 2001 From: Fernando Governatore Date: Sat, 20 Aug 2022 17:34:02 -0300 Subject: [PATCH 08/15] Fixes import ordering --- broadcaster/_backends/mqtt.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/broadcaster/_backends/mqtt.py b/broadcaster/_backends/mqtt.py index 9c868f8..6fa825b 100644 --- a/broadcaster/_backends/mqtt.py +++ b/broadcaster/_backends/mqtt.py @@ -7,10 +7,6 @@ from .._base import Event from .base import BroadcastBackend -from contextlib import AsyncExitStack, asynccontextmanager - -from contextlib import AsyncExitStack - class MqttBackend(BroadcastBackend): def __init__(self, url: str): From c648bb526d08473b823c9e4b4b9d17fa848886f3 Mon Sep 17 00:00:00 2001 From: Fernando Governatore Date: Sun, 21 Aug 2022 02:26:18 -0300 Subject: [PATCH 09/15] The returned message type is bytes MQTT allows for binary messages, deciding for the user that we should convert it to a string would force us to also decide on an encoding. Lets leave this decision to the user. --- tests/test_broadcast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_broadcast.py b/tests/test_broadcast.py index d9ae916..0378bb5 100644 --- a/tests/test_broadcast.py +++ b/tests/test_broadcast.py @@ -83,7 +83,7 @@ async def test_mqtt(): await broadcast.publish("chatroom", "hello") event = await subscriber.get() assert event.channel == "chatroom" - assert event.message.decode("utf-8") == "hello" + assert event.message == b"hello" @pytest.mark.asyncio From 0aeec88e5bb2b9d4fabcc48698ced4ece675577e Mon Sep 17 00:00:00 2001 From: Fernando Governatore Date: Sun, 21 Aug 2022 02:40:48 -0300 Subject: [PATCH 10/15] Configures MQTT to accept anonymous users for testing --- docker-compose.yaml | 3 ++- scripts/docker/mqtt/mosquitto-no-auth.conf | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 scripts/docker/mqtt/mosquitto-no-auth.conf diff --git a/docker-compose.yaml b/docker-compose.yaml index b38a1ba..03fcbaa 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -39,6 +39,7 @@ services: mqtt: image: "eclipse-mosquitto" hostname: mqtt + command: mosquitto -c /mosquitto-no-auth.conf ports: - 1883:1883 - - 8883:8883 + diff --git a/scripts/docker/mqtt/mosquitto-no-auth.conf b/scripts/docker/mqtt/mosquitto-no-auth.conf new file mode 100644 index 0000000..40dd92b --- /dev/null +++ b/scripts/docker/mqtt/mosquitto-no-auth.conf @@ -0,0 +1,5 @@ +# This is a Mosquitto configuration file that creates a listener on port 1883 +# that allows unauthenticated access. + +listener 1883 +allow_anonymous true From bc34a32c531c1d936bc268cbf8dd827a64b3e946 Mon Sep 17 00:00:00 2001 From: Fernando Governatore Date: Sun, 21 Aug 2022 03:02:37 -0300 Subject: [PATCH 11/15] Adds the MQTT service to GitHub workflow --- .github/workflows/test-suite.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 81db761..d67e6c4 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -51,6 +51,11 @@ jobs: POSTGRES_USER: postgres ports: - 5432:5432 + mqtt: + image: "eclipse-mosquitto" + ports: + - 1883:1883 + options: --hostname mqtt mosquitto -c /mosquitto-no-auth.conf steps: - uses: "actions/checkout@v2" From 96942df5b6b3c78b3f7b4bf710183ae64c5ab898 Mon Sep 17 00:00:00 2001 From: Fernando Governatore Date: Sun, 21 Aug 2022 03:07:20 -0300 Subject: [PATCH 12/15] Adds mqtt to the requirements file --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ed2926b..aca606f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ --e .[redis,postgres,kafka] +-e .[redis,postgres,kafka,mqtt] # Documentation mkdocs==1.5.3 From fb905af5358e2152fb73a5bb59380fe388e55ef9 Mon Sep 17 00:00:00 2001 From: "alex.oleshkevich" Date: Mon, 22 Apr 2024 18:42:03 +0200 Subject: [PATCH 13/15] Add mqtt backend --- broadcaster/_backends/mqtt.py | 44 +++++++++++++++++++++-------------- pyproject.toml | 1 + tests/test_broadcast.py | 2 +- 3 files changed, 29 insertions(+), 18 deletions(-) diff --git a/broadcaster/_backends/mqtt.py b/broadcaster/_backends/mqtt.py index 6fa825b..aa08f74 100644 --- a/broadcaster/_backends/mqtt.py +++ b/broadcaster/_backends/mqtt.py @@ -1,8 +1,8 @@ +import asyncio import typing -from contextlib import AsyncExitStack from urllib.parse import urlparse -import asyncio_mqtt +import aiomqtt from .._base import Event from .base import BroadcastBackend @@ -14,31 +14,41 @@ def __init__(self, url: str): self._host = parsed_url.hostname or "localhost" self._port = 8883 if parsed_url.scheme == "mqtts" else 1883 self._port = parsed_url.port or self._port + self._client = aiomqtt.Client(self._host, port=self._port) + self._queue: asyncio.Queue[aiomqtt.Message] = asyncio.Queue() + self._listener_task = asyncio.create_task(self._listener()) async def connect(self) -> None: - self.stack = AsyncExitStack() - - self.client = asyncio_mqtt.Client(self._host, port=self._port) - self.messages = self.client.filtered_messages("#") - - self.client = await self.stack.enter_async_context(self.client) - self.messages = await self.stack.enter_async_context(self.messages) + await self._client.__aenter__() async def disconnect(self) -> None: - await self.stack.aclose() + self._listener_task.cancel() + try: + await self._listener_task + except asyncio.CancelledError: + pass + + await self._client.__aexit__(None, None, None) async def subscribe(self, channel: str) -> None: - await self.client.subscribe(channel) + await self._client.subscribe(channel) async def unsubscribe(self, channel: str) -> None: - await self.client.unsubscribe(channel) + await self._client.unsubscribe(channel) async def publish(self, channel: str, message: typing.Any) -> None: - await self.client.publish(channel, message, retain=False) + await self._client.publish(channel, message, retain=False) async def next_published(self) -> Event: - async for message in self.messages: - event = Event(channel=message.topic, message=message.payload) - break + message = await self._queue.get() + + # Event.message is string, not bytes + # this is a limiting factor and we need to make sure + # that the payload is bytes in order to properly decode it + assert isinstance(message.payload, bytes), "Payload must be bytes." + + return Event(channel=message.topic.value, message=message.payload.decode()) - return event + async def _listener(self) -> None: + async for message in self._client.messages: + await self._queue.put(message) diff --git a/pyproject.toml b/pyproject.toml index c4e8036..54800d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,6 +35,7 @@ dependencies = [ redis = ["redis"] postgres = ["asyncpg"] kafka = ["aiokafka"] +mqtt = ["aiomqtt"] test = ["pytest", "pytest-asyncio"] [project.urls] diff --git a/tests/test_broadcast.py b/tests/test_broadcast.py index 0378bb5..cc72a65 100644 --- a/tests/test_broadcast.py +++ b/tests/test_broadcast.py @@ -83,7 +83,7 @@ async def test_mqtt(): await broadcast.publish("chatroom", "hello") event = await subscriber.get() assert event.channel == "chatroom" - assert event.message == b"hello" + assert event.message == "hello" @pytest.mark.asyncio From 67ed04a663ee5286974f92316cec8ef2221642db Mon Sep 17 00:00:00 2001 From: "alex.oleshkevich" Date: Mon, 22 Apr 2024 18:56:06 +0200 Subject: [PATCH 14/15] debug service --- .github/workflows/test-suite.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index d67e6c4..5770098 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -55,7 +55,8 @@ jobs: image: "eclipse-mosquitto" ports: - 1883:1883 - options: --hostname mqtt mosquitto -c /mosquitto-no-auth.conf + volumes: + - ./docker/mqtt/mosquitto-no-auth.conf:/mosquitto/config/mosquitto.conf steps: - uses: "actions/checkout@v2" From bfbbc96eccbaacbc798793bfb11cb6e27162b950 Mon Sep 17 00:00:00 2001 From: "alex.oleshkevich" Date: Mon, 22 Apr 2024 20:13:50 +0200 Subject: [PATCH 15/15] debug ci --- .github/workflows/test-suite.yml | 17 +++++++++++------ scripts/docker/mqtt/mosquitto-no-auth.conf | 5 ----- 2 files changed, 11 insertions(+), 11 deletions(-) delete mode 100644 scripts/docker/mqtt/mosquitto-no-auth.conf diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 5770098..0e17d07 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -51,14 +51,13 @@ jobs: POSTGRES_USER: postgres ports: - 5432:5432 - mqtt: - image: "eclipse-mosquitto" - ports: - - 1883:1883 - volumes: - - ./docker/mqtt/mosquitto-no-auth.conf:/mosquitto/config/mosquitto.conf steps: + # eclipse-mosquitto does not support configuration via environment variables + # so it is not possible to use github's service feature to start the broker + # instead, we start the broker using docker run command and stop it at the end of the job + - name: "Start MQTT broker" + run: "docker run -d -p 1883:1883 --name mqtt eclipse-mosquitto:2.0-openssl mosquitto -c /mosquitto-no-auth.conf" - uses: "actions/checkout@v2" - uses: "actions/setup-python@v2" with: @@ -69,7 +68,13 @@ jobs: run: "scripts/check" - name: "Build package & docs" run: "scripts/build" + + - name: "Run tests" run: "scripts/test" - name: "Enforce coverage" run: "scripts/coverage" + + - name: "Stop MQTT broker" + if: always() + run: "docker stop mqtt" \ No newline at end of file diff --git a/scripts/docker/mqtt/mosquitto-no-auth.conf b/scripts/docker/mqtt/mosquitto-no-auth.conf deleted file mode 100644 index 40dd92b..0000000 --- a/scripts/docker/mqtt/mosquitto-no-auth.conf +++ /dev/null @@ -1,5 +0,0 @@ -# This is a Mosquitto configuration file that creates a listener on port 1883 -# that allows unauthenticated access. - -listener 1883 -allow_anonymous true