diff --git a/.github/workflows/modoboa.yml b/.github/workflows/modoboa.yml index 1016f6aed..fd102787f 100644 --- a/.github/workflows/modoboa.yml +++ b/.github/workflows/modoboa.yml @@ -72,7 +72,7 @@ jobs: strategy: matrix: database: ['postgres', 'mysql'] - python-version: ['3.10', '3.11', '3.12', '3.13'] + python-version: ['3.10', '3.11', '3.12', '3.13', '3.14'] fail-fast: false steps: diff --git a/docker/Dockerfile.dev b/docker/Dockerfile.dev index 71d868a2f..7d47f51b7 100644 --- a/docker/Dockerfile.dev +++ b/docker/Dockerfile.dev @@ -1,4 +1,4 @@ -FROM python:3.12-alpine3.20 AS base +FROM python:3.14-alpine AS base LABEL org.opencontainers.image.authors="Antoine Nguyen " diff --git a/modoboa/policyd/management/commands/policy_daemon.py b/modoboa/policyd/management/commands/policy_daemon.py index c8096c96e..2e9942da9 100644 --- a/modoboa/policyd/management/commands/policy_daemon.py +++ b/modoboa/policyd/management/commands/policy_daemon.py @@ -31,7 +31,11 @@ class Command(BaseCommand): def handle(self, *args, **options): """Entry point.""" - loop = asyncio.get_event_loop() + try: + loop = asyncio.get_event_loop() + except RuntimeError: + loop = asyncio.new_event_loop() + asyncio.set_event_loop(loop) coro = asyncio.start_server( core.new_connection, options["host"], options["port"] ) diff --git a/modoboa/policyd/tests.py b/modoboa/policyd/tests.py index aaf6cddf9..e79100fb2 100644 --- a/modoboa/policyd/tests.py +++ b/modoboa/policyd/tests.py @@ -3,11 +3,11 @@ import asyncio from aiosmtplib import send from unittest.mock import AsyncMock +import multiprocessing from multiprocessing import Process import socket import time - from django import db from django.core.management import call_command from django.test import TransactionTestCase @@ -21,6 +21,8 @@ from modoboa.policyd import core as policyd_core from . import constants +multiprocessing.set_start_method("fork") + def start_policy_daemon(): call_command("policy_daemon") @@ -56,7 +58,7 @@ class PolicyDaemonTestCase(RedisTestCaseMixin, ParametersMixin, TransactionTestC self.process.daemon = True self.process.start() # Wait a bit for the daemon to start - self.process.join(0.1) + self.process.join(1.0) def set_domain_limit(self, name, value): """Set daily limit for domain."""