From ffe7970e59d81734cf1bf38ce08fad05f86a26a3 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 17:55:27 -0500 Subject: [PATCH 01/26] add vagrant config for easy local testing --- vagrant/.gitignore | 1 + vagrant/README | 51 ++++++++++++++++++++++++++++++++++++++++++++ vagrant/Vagrantfile | 11 ++++++++++ vagrant/provision.sh | 17 +++++++++++++++ vagrant/runtox.sh | 5 +++++ 5 files changed, 85 insertions(+) create mode 100644 vagrant/.gitignore create mode 100644 vagrant/README create mode 100644 vagrant/Vagrantfile create mode 100644 vagrant/provision.sh create mode 100644 vagrant/runtox.sh diff --git a/vagrant/.gitignore b/vagrant/.gitignore new file mode 100644 index 0000000..a977916 --- /dev/null +++ b/vagrant/.gitignore @@ -0,0 +1 @@ +.vagrant/ diff --git a/vagrant/README b/vagrant/README new file mode 100644 index 0000000..0a6280b --- /dev/null +++ b/vagrant/README @@ -0,0 +1,51 @@ +CREATES A VAGRANT ENVIRONMENT TO FACILITATE LOCAL TESTING + +======== +USAGE: +======== +To run tests: + cd to this directory and then issue the following commands: + vagrant up + vagrant ssh + bash /vagrant/vagrant/runtox.sh + + to run with verbose output: + bash /vagrant/vagrant/runtox.sh -- -v 2 + + to run a specific test: + bash /vagrant/vagrant/runtox.sh -- filestreamview.tests.test_filestreamview.FileStreamViewTests.test_syntax_equal + + +To clean after tests run: + rm -R /tmp/vagrant + +To use django's manage.py: + apt-get install -y python3-pip + cd /vagrant + pip3 install -r requirements.txt + python3 manage.py --help + +To use django's manage.py shell: + apt-get install -y python3-pip + cd /vagrant + pip3 install -r requirements.txt + python3 manage.py shell + +To make migrations: + apt-get install -y python3-pip + cd /vagrant + pip3 install -r requirements.txt + python3 manage.py makemigrations + +To migrate: + apt-get install -y python3-pip + cd /vagrant + pip3 install -r requirements.txt + python3 manage.py migrate + +To run tests directly: + apt-get install -y python3-pip + cd /vagrant + pip3 install -r requirements.txt + pip3 install -r requirements_dev.txt + python3 manage.py test diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile new file mode 100644 index 0000000..2ddff7a --- /dev/null +++ b/vagrant/Vagrantfile @@ -0,0 +1,11 @@ +Vagrant.configure("2") do |config| + config.vm.box = "hashicorp/bionic64" + + config.vm.provider "virtualbox" do |v| + v.name = "django-celery-model" + end + + config.vm.provision :shell, path: "provision.sh" + config.vm.synced_folder ".", "/vagrant", disabled: true + config.vm.synced_folder "../", "/vagrant" +end diff --git a/vagrant/provision.sh b/vagrant/provision.sh new file mode 100644 index 0000000..caba974 --- /dev/null +++ b/vagrant/provision.sh @@ -0,0 +1,17 @@ +set -o errexit +set -o pipefail +set -o nounset +shopt -s failglob +set -o xtrace + +export DEBIAN_FRONTEND=noninteractive + +add-apt-repository -y ppa:deadsnakes/ppa +apt-get update +apt-get install -y build-essential libssl-dev python3.5 python3.5-dev python3.6 python3.6-dev python3.7 python3.7-dev + +curl -sSL https://get.docker.com/ | sh +adduser vagrant docker + +curl https://bootstrap.pypa.io/get-pip.py | python3 +pip3 install tox tox-docker diff --git a/vagrant/runtox.sh b/vagrant/runtox.sh new file mode 100644 index 0000000..b520da9 --- /dev/null +++ b/vagrant/runtox.sh @@ -0,0 +1,5 @@ +rsync --recursive --exclude="*/node_modules/*" --exclude="*/.git/*" /vagrant /tmp + +cd /tmp/vagrant + +tox "$@" From 6dadec97592ec4aa6ac8888b1faa518d81222b17 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 18:15:19 -0500 Subject: [PATCH 02/26] clean this up --- vagrant/README | 35 ++--------------------------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/vagrant/README b/vagrant/README index 0a6280b..68a9cda 100644 --- a/vagrant/README +++ b/vagrant/README @@ -10,42 +10,11 @@ To run tests: bash /vagrant/vagrant/runtox.sh to run with verbose output: - bash /vagrant/vagrant/runtox.sh -- -v 2 + bash /vagrant/vagrant/runtox.sh -vv -- -v 2 to run a specific test: - bash /vagrant/vagrant/runtox.sh -- filestreamview.tests.test_filestreamview.FileStreamViewTests.test_syntax_equal + bash /vagrant/vagrant/runtox.sh -vv -- -v 2 path.to.test To clean after tests run: rm -R /tmp/vagrant - -To use django's manage.py: - apt-get install -y python3-pip - cd /vagrant - pip3 install -r requirements.txt - python3 manage.py --help - -To use django's manage.py shell: - apt-get install -y python3-pip - cd /vagrant - pip3 install -r requirements.txt - python3 manage.py shell - -To make migrations: - apt-get install -y python3-pip - cd /vagrant - pip3 install -r requirements.txt - python3 manage.py makemigrations - -To migrate: - apt-get install -y python3-pip - cd /vagrant - pip3 install -r requirements.txt - python3 manage.py migrate - -To run tests directly: - apt-get install -y python3-pip - cd /vagrant - pip3 install -r requirements.txt - pip3 install -r requirements_dev.txt - python3 manage.py test From ad1995f8824c519763d62858fbb9086433ac1d71 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 18:17:28 -0500 Subject: [PATCH 03/26] boilerplate --- djcelery_model/tests/__init__.py | 7 ++ djcelery_model/tests/celery.py | 19 +++++ djcelery_model/tests/settings.py | 77 ++++++++++++++++++ djcelery_model/tests/test_cases.py | 13 +++ djcelery_model/tests/testapp/__init__.py | 0 .../tests/testapp/migrations/0001_initial.py | 24 ++++++ .../tests/testapp/migrations/__init__.py | 0 djcelery_model/tests/testapp/models.py | 5 ++ .../tests/testapp/static/testapp/flower.jpg | Bin 0 -> 32764 bytes runtests.py | 30 +++++++ tox.ini | 31 +++++++ 11 files changed, 206 insertions(+) create mode 100644 djcelery_model/tests/__init__.py create mode 100644 djcelery_model/tests/celery.py create mode 100644 djcelery_model/tests/settings.py create mode 100644 djcelery_model/tests/test_cases.py create mode 100644 djcelery_model/tests/testapp/__init__.py create mode 100644 djcelery_model/tests/testapp/migrations/0001_initial.py create mode 100644 djcelery_model/tests/testapp/migrations/__init__.py create mode 100644 djcelery_model/tests/testapp/models.py create mode 100644 djcelery_model/tests/testapp/static/testapp/flower.jpg create mode 100644 runtests.py create mode 100644 tox.ini diff --git a/djcelery_model/tests/__init__.py b/djcelery_model/tests/__init__.py new file mode 100644 index 0000000..070e835 --- /dev/null +++ b/djcelery_model/tests/__init__.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import, unicode_literals + +# This will make sure the app is always imported when +# Django starts so that shared_task will use this app. +from .celery import app as celery_app + +__all__ = ('celery_app',) diff --git a/djcelery_model/tests/celery.py b/djcelery_model/tests/celery.py new file mode 100644 index 0000000..4b23784 --- /dev/null +++ b/djcelery_model/tests/celery.py @@ -0,0 +1,19 @@ +from __future__ import absolute_import, unicode_literals +import os +from celery import Celery + +# set the default Django settings module for the 'celery' program. +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'djcelery_model.tests.settings') + +app = Celery('project') + +# Using a string here means the worker doesn't have to serialize +# the configuration object to child processes. +# - namespace='CELERY' means all celery-related configuration keys +# should have a `CELERY_` prefix. +app.config_from_object('django.conf:settings', namespace='CELERY') + +# Load task modules from all registered Django app configs. +app.autodiscover_tasks() + +from celery.contrib.testing.tasks import ping diff --git a/djcelery_model/tests/settings.py b/djcelery_model/tests/settings.py new file mode 100644 index 0000000..dbd3306 --- /dev/null +++ b/djcelery_model/tests/settings.py @@ -0,0 +1,77 @@ +# -*- coding: utf-8 +from __future__ import unicode_literals, absolute_import +import os + +DEBUG = True +USE_TZ = True + +# SECURITY WARNING: keep the secret key used in production secret! +SECRET_KEY = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' + +INSTALLED_APPS = [ + 'django.contrib.admin', + 'django.contrib.auth', + 'django.contrib.contenttypes', + 'django.contrib.sites', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.staticfiles', + + 'djcelery_model', + 'djcelery_model.tests.testapp', +] + +SITE_ID = 1 + +MIDDLEWARE = [ + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', +] + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [ + os.path.join(os.path.dirname(__file__), 'templates'), + ], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': [ + 'django.template.context_processors.debug', + 'django.template.context_processors.request', + 'django.contrib.auth.context_processors.auth', + 'django.contrib.messages.context_processors.messages', + ], + }, + }, +] + +ROOT_DIR = os.path.dirname(__file__) +STATIC_ROOT = os.path.join(ROOT_DIR, 'test-static') +MEDIA_ROOT = os.path.join(ROOT_DIR, 'test-media') +MEDIA_URL = '/media/' +STATIC_URL = '/static/' + +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': ':memory:', + } +} + +REDIS_PORT = os.getenv('REDIS_6379_TCP_PORT', 'port-missing-from-env') + +CACHES = { + 'default': { + 'BACKEND': 'redis_cache.RedisCache', + 'LOCATION': 'localhost:%s' % REDIS_PORT, + }, +} + +CELERY_BROKER_URL = 'redis://localhost:%s/0' % REDIS_PORT +CELERY_RESULT_BACKEND = 'redis://localhost:%s/2' % REDIS_PORT +CELERY_TASK_TRACK_STARTED = True +CELERY_TASK_SEND_SENT_EVENT = True +CELERY_SEND_EVENTS = True diff --git a/djcelery_model/tests/test_cases.py b/djcelery_model/tests/test_cases.py new file mode 100644 index 0000000..4410024 --- /dev/null +++ b/djcelery_model/tests/test_cases.py @@ -0,0 +1,13 @@ +from celery.contrib.testing.worker import start_worker +from django.test import TransactionTestCase + +from djcelery_model.tests import celery_app + + +class CeleryTestCase(TransactionTestCase): + def setUp(self): + self.celery_worker = start_worker(celery_app) + self.celery_worker.__enter__() + + def tearDown(self): + self.celery_worker.__exit__(None, None, None) diff --git a/djcelery_model/tests/testapp/__init__.py b/djcelery_model/tests/testapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/djcelery_model/tests/testapp/migrations/0001_initial.py b/djcelery_model/tests/testapp/migrations/0001_initial.py new file mode 100644 index 0000000..d2982a4 --- /dev/null +++ b/djcelery_model/tests/testapp/migrations/0001_initial.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.7 on 2017-04-10 17:22 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='JPEGFile', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('file', models.FileField(upload_to=b'')), + ('etag', models.CharField(max_length=255)), + ], + ), + ] diff --git a/djcelery_model/tests/testapp/migrations/__init__.py b/djcelery_model/tests/testapp/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/djcelery_model/tests/testapp/models.py b/djcelery_model/tests/testapp/models.py new file mode 100644 index 0000000..cfe3297 --- /dev/null +++ b/djcelery_model/tests/testapp/models.py @@ -0,0 +1,5 @@ +from django.db import models + +class JPEGFile(models.Model): + file = models.FileField() + etag = models.CharField(max_length=255) diff --git a/djcelery_model/tests/testapp/static/testapp/flower.jpg b/djcelery_model/tests/testapp/static/testapp/flower.jpg new file mode 100644 index 0000000000000000000000000000000000000000..933719d1cf71cfe3e1794e258eb56a2c15c6fa40 GIT binary patch literal 32764 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 Date: Sun, 10 Nov 2019 18:22:33 -0500 Subject: [PATCH 04/26] make migration --- .../tests/testapp/migrations/0001_initial.py | 9 +++++---- djcelery_model/tests/testapp/models.py | 3 ++- manage.py | 12 ++++++++++++ vagrant/README | 3 +++ 4 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 manage.py diff --git a/djcelery_model/tests/testapp/migrations/0001_initial.py b/djcelery_model/tests/testapp/migrations/0001_initial.py index d2982a4..e3adc85 100644 --- a/djcelery_model/tests/testapp/migrations/0001_initial.py +++ b/djcelery_model/tests/testapp/migrations/0001_initial.py @@ -1,6 +1,4 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.7 on 2017-04-10 17:22 -from __future__ import unicode_literals +# Generated by Django 2.2.7 on 2019-11-10 23:21 from django.db import migrations, models @@ -17,8 +15,11 @@ class Migration(migrations.Migration): name='JPEGFile', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('file', models.FileField(upload_to=b'')), + ('file', models.FileField(upload_to='')), ('etag', models.CharField(max_length=255)), ], + options={ + 'abstract': False, + }, ), ] diff --git a/djcelery_model/tests/testapp/models.py b/djcelery_model/tests/testapp/models.py index cfe3297..1b2ad05 100644 --- a/djcelery_model/tests/testapp/models.py +++ b/djcelery_model/tests/testapp/models.py @@ -1,5 +1,6 @@ from django.db import models +from djcelery_model.models import TaskMixin -class JPEGFile(models.Model): +class JPEGFile(TaskMixin, models.Model): file = models.FileField() etag = models.CharField(max_length=255) diff --git a/manage.py b/manage.py new file mode 100644 index 0000000..2a4c384 --- /dev/null +++ b/manage.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import unicode_literals, absolute_import + +import os +import sys + +if __name__ == "__main__": + os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djcelery_model.tests.settings") + from django.core.management import execute_from_command_line + + execute_from_command_line(sys.argv) diff --git a/vagrant/README b/vagrant/README index 68a9cda..81dbeed 100644 --- a/vagrant/README +++ b/vagrant/README @@ -18,3 +18,6 @@ To run tests: To clean after tests run: rm -R /tmp/vagrant + +To make migrations (after running tests to create tox environment): + /tmp/vagrant/.tox/py35/bin/python /vagrant/manage.py makemigrations From 83bcbb2c3beceae5cb6401141c3d0e317c221119 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 18:31:56 -0500 Subject: [PATCH 05/26] run a simple test --- dev-requirements.txt | 1 + djcelery_model/tests/settings.py | 7 ------- .../tests/{test_cases.py => testapp/tests.py} | 12 +++++++++++- tox.ini | 1 + 4 files changed, 13 insertions(+), 8 deletions(-) rename djcelery_model/tests/{test_cases.py => testapp/tests.py} (54%) diff --git a/dev-requirements.txt b/dev-requirements.txt index d27d29c..1d23dc0 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -22,3 +22,4 @@ urllib3==1.25.3 webencodings==0.5.1 wheel==0.33.6 wrapt==1.11.2 +celery[redis] diff --git a/djcelery_model/tests/settings.py b/djcelery_model/tests/settings.py index dbd3306..385560b 100644 --- a/djcelery_model/tests/settings.py +++ b/djcelery_model/tests/settings.py @@ -63,13 +63,6 @@ REDIS_PORT = os.getenv('REDIS_6379_TCP_PORT', 'port-missing-from-env') -CACHES = { - 'default': { - 'BACKEND': 'redis_cache.RedisCache', - 'LOCATION': 'localhost:%s' % REDIS_PORT, - }, -} - CELERY_BROKER_URL = 'redis://localhost:%s/0' % REDIS_PORT CELERY_RESULT_BACKEND = 'redis://localhost:%s/2' % REDIS_PORT CELERY_TASK_TRACK_STARTED = True diff --git a/djcelery_model/tests/test_cases.py b/djcelery_model/tests/testapp/tests.py similarity index 54% rename from djcelery_model/tests/test_cases.py rename to djcelery_model/tests/testapp/tests.py index 4410024..f33aafb 100644 --- a/djcelery_model/tests/test_cases.py +++ b/djcelery_model/tests/testapp/tests.py @@ -1,8 +1,11 @@ from celery.contrib.testing.worker import start_worker -from django.test import TransactionTestCase +from django.test import TestCase, TransactionTestCase +from djcelery_model.models import ModelTaskMeta, TaskMixin from djcelery_model.tests import celery_app +from .models import JPEGFile + class CeleryTestCase(TransactionTestCase): def setUp(self): @@ -11,3 +14,10 @@ def setUp(self): def tearDown(self): self.celery_worker.__exit__(None, None, None) + + +class TestAppIntegrationTests(TestCase): + def test_model_is_taskmixin(self): + self.assertIsInstance(JPEGFile(), TaskMixin) + + diff --git a/tox.ini b/tox.ini index d6a8051..f4edb16 100644 --- a/tox.ini +++ b/tox.ini @@ -12,6 +12,7 @@ commands = deps = -r{toxinidir}/requirements.txt + -r{toxinidir}/dev-requirements.txt basepython = py37: python3.7 From 587777e035b4a678fe037551276d835fea4ce8d5 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 18:40:30 -0500 Subject: [PATCH 06/26] confirm working celery setup --- dev-requirements.txt | 1 + djcelery_model/tests/testapp/tests.py | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/dev-requirements.txt b/dev-requirements.txt index 1d23dc0..184647c 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -23,3 +23,4 @@ webencodings==0.5.1 wheel==0.33.6 wrapt==1.11.2 celery[redis] +redis diff --git a/djcelery_model/tests/testapp/tests.py b/djcelery_model/tests/testapp/tests.py index f33aafb..0fd10c7 100644 --- a/djcelery_model/tests/testapp/tests.py +++ b/djcelery_model/tests/testapp/tests.py @@ -1,3 +1,4 @@ +from celery.contrib.testing.tasks import ping from celery.contrib.testing.worker import start_worker from django.test import TestCase, TransactionTestCase @@ -21,3 +22,8 @@ def test_model_is_taskmixin(self): self.assertIsInstance(JPEGFile(), TaskMixin) +class TestAppCeleryTests(CeleryTestCase): + def test_worker(self): + result = ping.delay() + pong = result.get(timeout=10) + self.assertEqual(pong, 'pong') From 10a29224be71fb934124c63bea180310a54161b0 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 19:00:44 -0500 Subject: [PATCH 07/26] add test checking result state properties --- .../tests/testapp/migrations/0001_initial.py | 2 +- djcelery_model/tests/testapp/models.py | 2 +- djcelery_model/tests/testapp/tasks.py | 14 +++++++++ djcelery_model/tests/testapp/tests.py | 31 ++++++++++++++++++- 4 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 djcelery_model/tests/testapp/tasks.py diff --git a/djcelery_model/tests/testapp/migrations/0001_initial.py b/djcelery_model/tests/testapp/migrations/0001_initial.py index e3adc85..99cfc06 100644 --- a/djcelery_model/tests/testapp/migrations/0001_initial.py +++ b/djcelery_model/tests/testapp/migrations/0001_initial.py @@ -16,7 +16,7 @@ class Migration(migrations.Migration): fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('file', models.FileField(upload_to='')), - ('etag', models.CharField(max_length=255)), + ('etag', models.CharField(blank=True, max_length=255)), ], options={ 'abstract': False, diff --git a/djcelery_model/tests/testapp/models.py b/djcelery_model/tests/testapp/models.py index 1b2ad05..0913036 100644 --- a/djcelery_model/tests/testapp/models.py +++ b/djcelery_model/tests/testapp/models.py @@ -3,4 +3,4 @@ class JPEGFile(TaskMixin, models.Model): file = models.FileField() - etag = models.CharField(max_length=255) + etag = models.CharField(max_length=255, blank=True) diff --git a/djcelery_model/tests/testapp/tasks.py b/djcelery_model/tests/testapp/tasks.py new file mode 100644 index 0000000..b1dee61 --- /dev/null +++ b/djcelery_model/tests/testapp/tasks.py @@ -0,0 +1,14 @@ +from __future__ import absolute_import, unicode_literals +from hashlib import sha1 +from time import sleep +from celery import shared_task + +from .models import JPEGFile + + +@shared_task +def calculate_etag(pk): + jpeg = JPEGFile.objects.get(pk=pk) + jpeg.etag = sha1(jpeg.file.read()).hexdigest() + sleep(5) + jpeg.save() diff --git a/djcelery_model/tests/testapp/tests.py b/djcelery_model/tests/testapp/tests.py index 0fd10c7..f3ee0a7 100644 --- a/djcelery_model/tests/testapp/tests.py +++ b/djcelery_model/tests/testapp/tests.py @@ -1,11 +1,14 @@ from celery.contrib.testing.tasks import ping from celery.contrib.testing.worker import start_worker +from django.contrib.staticfiles import finders +from django.core.files import File from django.test import TestCase, TransactionTestCase -from djcelery_model.models import ModelTaskMeta, TaskMixin +from djcelery_model.models import TaskMixin from djcelery_model.tests import celery_app from .models import JPEGFile +from .tasks import calculate_etag class CeleryTestCase(TransactionTestCase): @@ -27,3 +30,29 @@ def test_worker(self): result = ping.delay() pong = result.get(timeout=10) self.assertEqual(pong, 'pong') + + def test_state_properties(self): + jpeg = JPEGFile.objects.create( + file=File(open(finders.find('testapp/flower.jpg'), 'rb'), name='flower.jpg') + ) + + self.assertFalse(jpeg.has_running_task) + self.assertFalse(jpeg.has_ready_task) + + result = jpeg.apply_async(calculate_etag, [jpeg.pk]) + self.assertTrue(jpeg.has_running_task) + self.assertFalse(jpeg.has_ready_task) + self.assertFalse(result.ready()) + + result.get(timeout=10) + self.assertTrue(result.ready()) + + self.assertEqual(jpeg.etag, '') + self.assertFalse(jpeg.has_running_task) + self.assertTrue(jpeg.has_ready_task) + + jpeg.refresh_from_db() + + self.assertEqual(jpeg.etag, '80b098e6cd95b9901fa29799d48731433dfaeab0') + self.assertFalse(jpeg.has_running_task) + self.assertTrue(jpeg.has_ready_task) From d799397b43f024ce7046922de36a4cdc7059b2f4 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 19:04:06 -0500 Subject: [PATCH 08/26] test on py35,6,7 --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index f4edb16..e572008 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - {py35} + {py35,py36,py37} [testenv] From adff1434d00d5d19a457d305087a7027887db74d Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 19:20:33 -0500 Subject: [PATCH 09/26] config for travis --- .travis.yml | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index fe60c73..c894e0e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,18 @@ language: python -python: - - "2.7" - - "3.6" - - "pypy" - - "pypy3" -# command to install dependencies +cache: pip +matrix: + include: + - env: TOX_ENV=py35 + python: 3.5 + - env: TOX_ENV=py36 + python: 3.6 + - env: TOX_ENV=py37 + python: 3.7 + dist: bionic + sudo: true + install: - - "pip install -r requirements.txt" + - "pip install -r requirements.txt -r dev-requirements.txt tox tox-docker" - "pip install ." -# command to run tests -script: - - "python -m compileall ." + +script: tox -e $TOX_ENV From d83b488a132506d9c8196e5814c0531ef9270e86 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 20:18:51 -0500 Subject: [PATCH 10/26] cleanup better --- djcelery_model/tests/testapp/tests.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/djcelery_model/tests/testapp/tests.py b/djcelery_model/tests/testapp/tests.py index f3ee0a7..91ad016 100644 --- a/djcelery_model/tests/testapp/tests.py +++ b/djcelery_model/tests/testapp/tests.py @@ -14,10 +14,11 @@ class CeleryTestCase(TransactionTestCase): def setUp(self): self.celery_worker = start_worker(celery_app) - self.celery_worker.__enter__() + celery_app.control.ping() def tearDown(self): self.celery_worker.__exit__(None, None, None) + celery_app.control.purge() class TestAppIntegrationTests(TestCase): From 8807f8bfd945b5e314fe6302a52823bd0d9e41d4 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 20:26:21 -0500 Subject: [PATCH 11/26] be verbose --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c894e0e..56636d6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,4 +15,4 @@ install: - "pip install -r requirements.txt -r dev-requirements.txt tox tox-docker" - "pip install ." -script: tox -e $TOX_ENV +script: tox -vv -e $TOX_ENV From 3f6743c1eb05292cef7910896dbd4b933976df5b Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 20:42:40 -0500 Subject: [PATCH 12/26] add missing __enter__() --- djcelery_model/tests/testapp/tests.py | 1 + 1 file changed, 1 insertion(+) diff --git a/djcelery_model/tests/testapp/tests.py b/djcelery_model/tests/testapp/tests.py index 91ad016..c920ef0 100644 --- a/djcelery_model/tests/testapp/tests.py +++ b/djcelery_model/tests/testapp/tests.py @@ -14,6 +14,7 @@ class CeleryTestCase(TransactionTestCase): def setUp(self): self.celery_worker = start_worker(celery_app) + self.celery_worker.__enter__() celery_app.control.ping() def tearDown(self): From 916fdf5233c983afd6810e89b0059d6452c0e513 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 21:00:16 -0500 Subject: [PATCH 13/26] skip purge - all pass without it --- djcelery_model/tests/testapp/tests.py | 1 - 1 file changed, 1 deletion(-) diff --git a/djcelery_model/tests/testapp/tests.py b/djcelery_model/tests/testapp/tests.py index c920ef0..87f6b16 100644 --- a/djcelery_model/tests/testapp/tests.py +++ b/djcelery_model/tests/testapp/tests.py @@ -19,7 +19,6 @@ def setUp(self): def tearDown(self): self.celery_worker.__exit__(None, None, None) - celery_app.control.purge() class TestAppIntegrationTests(TestCase): From b2558add347db5a7c859f12f272c2c93898cf507 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 21:56:55 -0500 Subject: [PATCH 14/26] shorten worker name --- djcelery_model/tests/testapp/tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/djcelery_model/tests/testapp/tests.py b/djcelery_model/tests/testapp/tests.py index 87f6b16..cd42ef1 100644 --- a/djcelery_model/tests/testapp/tests.py +++ b/djcelery_model/tests/testapp/tests.py @@ -13,12 +13,12 @@ class CeleryTestCase(TransactionTestCase): def setUp(self): - self.celery_worker = start_worker(celery_app) - self.celery_worker.__enter__() + self.worker_context = start_worker(celery_app, perform_ping_check=False) + self.worker = self.worker_context.__enter__() celery_app.control.ping() def tearDown(self): - self.celery_worker.__exit__(None, None, None) + self.worker_context.__exit__(None, None, None) class TestAppIntegrationTests(TestCase): From 1dd23510304a3149dd7efe445c112bad4a1f76ca Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 21:57:42 -0500 Subject: [PATCH 15/26] use worker.ensure_started() instead of ping() - multiple successes --- djcelery_model/tests/testapp/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djcelery_model/tests/testapp/tests.py b/djcelery_model/tests/testapp/tests.py index cd42ef1..25c3de9 100644 --- a/djcelery_model/tests/testapp/tests.py +++ b/djcelery_model/tests/testapp/tests.py @@ -15,7 +15,7 @@ class CeleryTestCase(TransactionTestCase): def setUp(self): self.worker_context = start_worker(celery_app, perform_ping_check=False) self.worker = self.worker_context.__enter__() - celery_app.control.ping() + self.worker.ensure_started() def tearDown(self): self.worker_context.__exit__(None, None, None) From 81446e3505ecc5a7bfbe9deb30a25d138686b95a Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Sun, 10 Nov 2019 22:20:32 -0500 Subject: [PATCH 16/26] confirm sleep fixes travis problems b4 delving into signals listeners --- djcelery_model/tests/testapp/tests.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/djcelery_model/tests/testapp/tests.py b/djcelery_model/tests/testapp/tests.py index 25c3de9..e2565b2 100644 --- a/djcelery_model/tests/testapp/tests.py +++ b/djcelery_model/tests/testapp/tests.py @@ -1,3 +1,4 @@ +from time import sleep from celery.contrib.testing.tasks import ping from celery.contrib.testing.worker import start_worker from django.contrib.staticfiles import finders @@ -48,6 +49,10 @@ def test_state_properties(self): result.get(timeout=10) self.assertTrue(result.ready()) + # not the greatest way to wait for async stuff to happen, but we need + # the signals to complete before testing for side effects + sleep(3) + self.assertEqual(jpeg.etag, '') self.assertFalse(jpeg.has_running_task) self.assertTrue(jpeg.has_ready_task) From ed4fd033210cf2f914e79034c7d6b7e89592febb Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 11:45:09 -0400 Subject: [PATCH 17/26] install specific version fo django --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b546fa8..518cb9d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -django>=1.11 +django>=1.11,<2 celery>=4.2 From 2d356cbaac747f019476026a54a77ae3bc50d325 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 11:46:39 -0400 Subject: [PATCH 18/26] Revert "install specific version fo django" This reverts commit ed4fd033210cf2f914e79034c7d6b7e89592febb. --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 518cb9d..b546fa8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -django>=1.11,<2 +django>=1.11 celery>=4.2 From c8c439e6dea7d0cdeeb710d6ed48fff7e1b1309e Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 11:48:07 -0400 Subject: [PATCH 19/26] pin to django 3.0 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index b546fa8..dfb5a24 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -django>=1.11 +django>=3,<3.1 celery>=4.2 From 3aa8370946ebe5ca060a0f1edc4ffe9159fbaa5d Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 11:49:57 -0400 Subject: [PATCH 20/26] test against py38,37,36 per django 3.0 --- .travis.yml | 4 ++-- tox.ini | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 56636d6..b45d99b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,14 +2,14 @@ language: python cache: pip matrix: include: - - env: TOX_ENV=py35 - python: 3.5 - env: TOX_ENV=py36 python: 3.6 - env: TOX_ENV=py37 python: 3.7 dist: bionic sudo: true + - env: TOX_ENV=py38 + python: 3.8 install: - "pip install -r requirements.txt -r dev-requirements.txt tox tox-docker" diff --git a/tox.ini b/tox.ini index e572008..4ab2e62 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ [tox] envlist = - {py35,py36,py37} + {py36,py37,py38} [testenv] @@ -15,9 +15,9 @@ deps = -r{toxinidir}/dev-requirements.txt basepython = + py38: python3.8 py37: python3.7 py36: python3.6 - py35: python3.5 docker = redis:5.0 From 9b7b245e4b0097205d4b221cd69f1fefda06cacb Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 11:56:22 -0400 Subject: [PATCH 21/26] fixed missing import --- djcelery_model/compat.py | 4 ++++ djcelery_model/models.py | 3 ++- requirements.txt | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 djcelery_model/compat.py diff --git a/djcelery_model/compat.py b/djcelery_model/compat.py new file mode 100644 index 0000000..1729001 --- /dev/null +++ b/djcelery_model/compat.py @@ -0,0 +1,4 @@ +try: + from django.utils.encoding import python_2_unicode_compatible +except ImportError: + from six import python_2_unicode_compatible diff --git a/djcelery_model/models.py b/djcelery_model/models.py index 4447612..ec60a9f 100644 --- a/djcelery_model/models.py +++ b/djcelery_model/models.py @@ -9,7 +9,6 @@ from django.db.models import Q from django.db.models.query import QuerySet from django.contrib.contenttypes.models import ContentType -from django.utils.encoding import python_2_unicode_compatible try: # Django >= 1.7 @@ -21,6 +20,8 @@ from celery.utils import uuid from celery import signals +from .compat import python_2_unicode_compatible + class ModelTaskMetaState(object): PENDING = 0 STARTED = 1 diff --git a/requirements.txt b/requirements.txt index b546fa8..79e177e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,3 @@ django>=1.11 celery>=4.2 +six>=1.9 From b4f6e19d914eb7e2cbcb8bab9acef2c1b65396de Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 11:57:48 -0400 Subject: [PATCH 22/26] support more common case first --- djcelery_model/compat.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/djcelery_model/compat.py b/djcelery_model/compat.py index 1729001..61fa906 100644 --- a/djcelery_model/compat.py +++ b/djcelery_model/compat.py @@ -1,4 +1,4 @@ try: - from django.utils.encoding import python_2_unicode_compatible -except ImportError: from six import python_2_unicode_compatible +except ImportError: + from django.utils.encoding import python_2_unicode_compatible From ddad402226b3f9b2581929e16ed5b57ccc6a2f3f Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 11:59:27 -0400 Subject: [PATCH 23/26] removed duplicate import --- dev-requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/dev-requirements.txt b/dev-requirements.txt index 74a7afc..1e6a38c 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -18,7 +18,6 @@ readme-renderer==24.0 redis requests-toolbelt==0.9.1 requests==2.22.0 -six==1.14.0 tqdm==4.42.1 twine==3.1.1 typed-ast==1.4.1 ; implementation_name == 'cpython' and python_version < '3.8' From 2dd915c40deca9f71d748a9a4f280ae58c6074e5 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 12:02:22 -0400 Subject: [PATCH 24/26] removed py35 tests per keyring==21.1.0 (from -r dev-requirements.txt) --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 56636d6..cb5e5fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,8 +2,6 @@ language: python cache: pip matrix: include: - - env: TOX_ENV=py35 - python: 3.5 - env: TOX_ENV=py36 python: 3.6 - env: TOX_ENV=py37 From 5969e95abaaf8649e751781c013151e01f8fd6f8 Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 12:23:29 -0400 Subject: [PATCH 25/26] simplify as compat changes were less than anticipated --- djcelery_model/compat.py | 4 ---- djcelery_model/models.py | 6 +++++- 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 djcelery_model/compat.py diff --git a/djcelery_model/compat.py b/djcelery_model/compat.py deleted file mode 100644 index 61fa906..0000000 --- a/djcelery_model/compat.py +++ /dev/null @@ -1,4 +0,0 @@ -try: - from six import python_2_unicode_compatible -except ImportError: - from django.utils.encoding import python_2_unicode_compatible diff --git a/djcelery_model/models.py b/djcelery_model/models.py index ec60a9f..a68746b 100644 --- a/djcelery_model/models.py +++ b/djcelery_model/models.py @@ -10,6 +10,11 @@ from django.db.models.query import QuerySet from django.contrib.contenttypes.models import ContentType +try: + from six import python_2_unicode_compatible +except ImportError: + from django.utils.encoding import python_2_unicode_compatible + try: # Django >= 1.7 from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation @@ -20,7 +25,6 @@ from celery.utils import uuid from celery import signals -from .compat import python_2_unicode_compatible class ModelTaskMetaState(object): PENDING = 0 From edc6c20253a79fd522aa334e86a25885d290db3f Mon Sep 17 00:00:00 2001 From: Gordon Pendleton Date: Fri, 22 May 2020 12:24:25 -0400 Subject: [PATCH 26/26] removed whitespace change --- djcelery_model/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/djcelery_model/models.py b/djcelery_model/models.py index a68746b..258b9bd 100644 --- a/djcelery_model/models.py +++ b/djcelery_model/models.py @@ -25,7 +25,6 @@ from celery.utils import uuid from celery import signals - class ModelTaskMetaState(object): PENDING = 0 STARTED = 1