Skip to content

Commit 40dd2de

Browse files
authored
Merge pull request #2 from beachmachine/tests
SIANXKE-133: Added tests
2 parents 0cdab75 + 3807472 commit 40dd2de

File tree

14 files changed

+482
-2
lines changed

14 files changed

+482
-2
lines changed

.github/workflows/test.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Run linter and tests
2+
on: [push, pull_request]
3+
4+
jobs:
5+
test:
6+
runs-on: ubuntu-latest
7+
services:
8+
rabbitmq:
9+
image: rabbitmq:3.8-management
10+
ports:
11+
- 5672:5672
12+
strategy:
13+
fail-fast: false
14+
matrix:
15+
python-version:
16+
- "3.6"
17+
- "3.7"
18+
- "3.8"
19+
- "3.9"
20+
- "3.10"
21+
celery-version:
22+
- "5.0"
23+
- "5.1"
24+
25+
steps:
26+
- uses: actions/checkout@v2
27+
28+
- name: Set up Python ${{ matrix.python-version }}
29+
uses: actions/setup-python@v2
30+
with:
31+
python-version: ${{ matrix.python-version }}
32+
33+
- name: Install dependencies and package
34+
run: |
35+
python -m pip install --upgrade pip
36+
pip install -r requirements.txt
37+
pip install celery~=${{ matrix.celery-version }}.0
38+
39+
- name: Lint with flake8
40+
run: |
41+
# stop the build if there are Python syntax errors or undefined names
42+
flake8 './celery_amqp_backend' --count --select=E9,F63,F7,F82 --show-source --statistics
43+
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
44+
flake8 './celery_amqp_backend' --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
45+
46+
- name: Run tests
47+
run: |
48+
# prepare Django application
49+
ln -s ./tests/test_project/test_project test_project
50+
ln -s ./tests/test_project/manage.py manage.py
51+
52+
# run tests with coverage
53+
coverage run --source='./celery_amqp_backend' manage.py test
54+
coverage xml
55+
56+
- name: Upload coverage to Codecov
57+
uses: codecov/codecov-action@v1

README.md

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,19 @@
11
celery-amqp-backend
22
===================
33

4+
[![PyPI](https://badge.fury.io/py/celery-amqp-backend.svg)](https://pypi.org/project/celery-amqp-backend/)
5+
[![Test Status](https://github.com/anexia-it/celery-amqp-backend/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/anexia-it/celery-amqp-backend/actions/workflows/test.yml)
6+
[![Codecov](https://codecov.io/gh/anexia-it/celery-amqp-backend/branch/main/graph/badge.svg)](https://codecov.io/gh/anexia-it/celery-amqp-backend)
7+
48
`celery-amqp-backend` is a rewrite of the Celery's original `amqp://` result backend, which was removed from Celery
59
with version 5.0. Celery encourages you to use the newer `rpc://` result backend, as it does not create a new
610
result queue for each task and thus is faster in many circumstances. However, it's not always possible to switch
711
to the new `rpc://` result backend, as it does have restrictions as follows:
8-
- Results may hold a wrong state.
9-
- It may lose results when using `gevent` or `greenlet`.
12+
- `rpc://` does not support chords.
13+
- `rpc://` results may hold a wrong state.
14+
- `rpc://` may lose results when using `gevent` or `greenlet`.
15+
16+
The result backend `celery_amqp_backend.AMQPBackend://` does not suffer from the same issues.
1017

1118
# Installation
1219

@@ -59,6 +66,16 @@ result_exchange = 'celery_result'
5966
result_exchange_type = 'direct'
6067
```
6168

69+
# Supported versions
70+
71+
| | Celery 5.0 | Celery 5.1 |
72+
|-------------|------------|------------|
73+
| Python 3.6 |||
74+
| Python 3.7 |||
75+
| Python 3.8 |||
76+
| Python 3.9 |||
77+
| Python 3.10 |||
78+
6279
# List of developers
6380

6481
* Andreas Stocker <AStocker@anexia-it.com>, Lead Developer

tests/test_project/manage.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python
2+
"""Django's command-line utility for administrative tasks."""
3+
import os
4+
import sys
5+
6+
7+
def main():
8+
"""Run administrative tasks."""
9+
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'test_project.settings')
10+
try:
11+
from django.core.management import execute_from_command_line
12+
except ImportError as exc:
13+
raise ImportError(
14+
"Couldn't import Django. Are you sure it's installed and "
15+
"available on your PYTHONPATH environment variable? Did you "
16+
"forget to activate a virtual environment?"
17+
) from exc
18+
execute_from_command_line(sys.argv)
19+
20+
21+
if __name__ == '__main__':
22+
main()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from .celery import app as celery_app
2+
3+
4+
__all__ = [
5+
'celery_app',
6+
]
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from celery import Celery
2+
3+
__all__ = [
4+
'app',
5+
]
6+
7+
8+
app = Celery('test_project')
9+
10+
# Using a string here means the worker doesn't have to serialize
11+
# the configuration object to child processes.
12+
# - namespace='CELERY' means all celery-related configuration keys
13+
# should have a `CELERY_` prefix.
14+
app.config_from_object('django.conf:settings', namespace='CELERY')
15+
16+
# Load task modules from all registered Django app configs.
17+
app.autodiscover_tasks()
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
"""
2+
Django settings for test_project project.
3+
4+
Generated by 'django-admin startproject' using Django 3.2.8.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/3.2/topics/settings/
8+
9+
For the full list of settings and their values, see
10+
https://docs.djangoproject.com/en/3.2/ref/settings/
11+
"""
12+
13+
from pathlib import Path
14+
15+
# Build paths inside the project like this: BASE_DIR / 'subdir'.
16+
BASE_DIR = Path(__file__).resolve().parent.parent
17+
18+
19+
# Quick-start development settings - unsuitable for production
20+
# See https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
21+
22+
# SECURITY WARNING: keep the secret key used in production secret!
23+
SECRET_KEY = 'django-insecure-7db3wq7w6q@g3h^al9&ji=una44&ba+i#pz=@q=$+#&cx6%@$g'
24+
25+
# SECURITY WARNING: don't run with debug turned on in production!
26+
DEBUG = True
27+
28+
ALLOWED_HOSTS = []
29+
30+
31+
# Application definition
32+
33+
INSTALLED_APPS = [
34+
'test_project.tests',
35+
]
36+
37+
MIDDLEWARE = []
38+
39+
ROOT_URLCONF = 'test_project.urls'
40+
41+
TEMPLATES = [
42+
{
43+
'BACKEND': 'django.template.backends.django.DjangoTemplates',
44+
'DIRS': [],
45+
'APP_DIRS': True,
46+
'OPTIONS': {
47+
'context_processors': [
48+
'django.template.context_processors.debug',
49+
'django.template.context_processors.request',
50+
'django.contrib.auth.context_processors.auth',
51+
'django.contrib.messages.context_processors.messages',
52+
],
53+
},
54+
},
55+
]
56+
57+
WSGI_APPLICATION = 'test_project.wsgi.application'
58+
59+
60+
# Database
61+
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases
62+
63+
DATABASES = {
64+
'default': {
65+
'ENGINE': 'django.db.backends.sqlite3',
66+
'NAME': BASE_DIR / 'db.sqlite3',
67+
}
68+
}
69+
70+
71+
# Password validation
72+
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
73+
74+
AUTH_PASSWORD_VALIDATORS = []
75+
76+
77+
# Internationalization
78+
# https://docs.djangoproject.com/en/3.2/topics/i18n/
79+
80+
LANGUAGE_CODE = 'en-gb'
81+
82+
TIME_ZONE = 'UTC'
83+
84+
USE_I18N = True
85+
86+
USE_L10N = True
87+
88+
USE_TZ = True
89+
90+
91+
# Static files (CSS, JavaScript, Images)
92+
# https://docs.djangoproject.com/en/3.2/howto/static-files/
93+
94+
STATIC_URL = '/static/'
95+
96+
# Default primary key field type
97+
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
98+
99+
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
100+
101+
102+
# Celery Setup
103+
# http://docs.celeryproject.org/en/latest/django/first-steps-with-django.html
104+
CELERY_BROKER_URL = 'amqp://127.0.0.1/'
105+
CELERY_RESULT_BACKEND = 'celery_amqp_backend.AMQPBackend://'
106+
CELERY_BROKER_POOL_LIMIT = 10
107+
CELERY_TASK_DEFAULT_QUEUE = 'tests.default'
108+
CELERY_EVENT_QUEUE_PREFIX = 'tests.event'
109+
CELERY_RESULT_EXCHANGE = 'tests.result'
110+
CELERY_EVENT_EXCHANGE = 'tests.event'
111+
CELERY_CONTROL_EXCHANGE = 'tests.control'
112+
CELERY_ACCEPT_CONTENT = [
113+
'json',
114+
]
115+
CELERY_TASK_DEFAULT_DELIVERY_MODE = 'transient'
116+
CELERY_RESULT_EXPIRES = 60
117+
CELERY_RESULT_PERSISTENT = False
118+
CELERY_TASK_ACKS_LATE = False
119+
CELERY_TASK_TRACK_STARTED = False
120+
CELERY_TASK_IGNORE_RESULT = False
121+
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
__all__ = [
2+
'default_app_config',
3+
]
4+
5+
default_app_config = 'test_project.tests.apps.TestsConfig'
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from django.apps import AppConfig
2+
3+
__all__ = [
4+
'TestsConfig',
5+
]
6+
7+
8+
class TestsConfig(AppConfig):
9+
name = 'test_project.tests'
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import time
2+
3+
from test_project import *
4+
5+
__all__ = [
6+
'sum_numbers',
7+
'add_numbers',
8+
'add_numbers_slow',
9+
'combine_lists',
10+
'combine_dicts',
11+
]
12+
13+
14+
@celery_app.task
15+
def sum_numbers(numbers):
16+
return sum(numbers)
17+
18+
19+
@celery_app.task
20+
def add_numbers(x, y):
21+
return x + y
22+
23+
24+
@celery_app.task
25+
def add_numbers_slow(x, y):
26+
time.sleep(10)
27+
return x + y
28+
29+
30+
@celery_app.task
31+
def combine_lists(x, y):
32+
return x + y
33+
34+
35+
@celery_app.task
36+
def combine_dicts(x, y):
37+
x.update(y)
38+
return x

tests/test_project/test_project/tests/tests/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)