Skip to content

Commit

Permalink
Merge d5ef3b7 into 204ccf6
Browse files Browse the repository at this point in the history
  • Loading branch information
Duologic committed May 19, 2017
2 parents 204ccf6 + d5ef3b7 commit 00a069d
Show file tree
Hide file tree
Showing 28 changed files with 160 additions and 96 deletions.
26 changes: 25 additions & 1 deletion .coveragerc
Original file line number Diff line number Diff line change
@@ -1,2 +1,26 @@
[run]
omit = setup.py
branch = True
source = locking/
omit =
# Ignore migrations
*/migrations/*

# Ignore requirement files
requirements/*

# Ignore manage files
manage*

# Ignore admin files
locking/*/admin.py

# Ignore test_project file
test_project/*
[report]
exclude_lines=
pragma: no cover
def __repr__
def __iter__
def __str__
def __unicode__
fail_under = 99
9 changes: 9 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[flake8]
; We use a line length of 120 instead of pep8's default 79
max-line-length = 120
; Files not checked:
; - migrations: most of these are autogenerated and don't need a check
; - manage: these are autogenerated and don't need a check
exclude = *migrations,manage.py
; Cyclomatic complexity check with mccabe.
max-complexity = 20
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
*.py[co]

# Packages
*.egg
*.egg-info
*.egg*
dist
build
eggs
Expand All @@ -26,4 +25,6 @@ coverage.xml
#Mr Developer
.mr.developer.cfg

/.eggs/
# Virtualenvs
.venv*
.cache/
19 changes: 19 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
language: python
env:
- DJANGO='>=1.8,<1.9'
- DJANGO='>=1.9,<1.10'
- DJANGO='>=1.10,<1.11'
- DJANGO='>=1.11,<1.12'
python:
- "2.7"
- "3.6"
install:
- pip install -e .
- pip install -r requirements/requirements_test.txt
- pip install "Django${DJANGO}"
before_script:
flake8 locking/
script:
pytest -v --capture=sys --cov=locking/ locking/ --cov-report term-missing:skip-covered
after_success:
coveralls
6 changes: 6 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
Django-locking
==============

.. image:: https://coveralls.io/repos/github/vikingco/django-db-locking/badge.svg?branch=py23
:target: https://coveralls.io/github/vikingco/django-db-locking?branch=py23
.. image:: https://travis-ci.org/vikingco/django-db-locking.svg?branch=master
:target: https://travis-ci.org/vikingco/django-db-locking

Usage
-----
The simplest use is by using it as a context manager:
Expand Down
14 changes: 0 additions & 14 deletions circle.yml

This file was deleted.

6 changes: 0 additions & 6 deletions deployment/requirements_test.txt

This file was deleted.

1 change: 1 addition & 0 deletions locking/admin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import absolute_import
from django.contrib import admin

from .models import NonBlockingLock
Expand Down
1 change: 1 addition & 0 deletions locking/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from __future__ import absolute_import
from django.db import models, migrations


Expand Down
1 change: 1 addition & 0 deletions locking/migrations/0002_rename.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from __future__ import absolute_import
from django.db import migrations


Expand Down
1 change: 1 addition & 0 deletions locking/migrations/0003_optimize_queries.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from __future__ import absolute_import
from django.db import models, migrations
import datetime
from django.utils.timezone import utc
Expand Down
1 change: 1 addition & 0 deletions locking/migrations/0004_auto_20151115_0703.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from __future__ import absolute_import
from django.db import models, migrations
import uuid

Expand Down
1 change: 1 addition & 0 deletions locking/migrations/0004_auto_20160907_0942.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Generated by Django 1.9.7 on 2016-09-07 09:42
from __future__ import unicode_literals

from __future__ import absolute_import
from django.db import migrations, models


Expand Down
1 change: 1 addition & 0 deletions locking/migrations/0005_merge_20170504_1024.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Generated by Django 1.11 on 2017-05-04 10:24
from __future__ import unicode_literals

from __future__ import absolute_import
from django.db import migrations


Expand Down
1 change: 1 addition & 0 deletions locking/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import absolute_import
import uuid

from datetime import timedelta
Expand Down
1 change: 1 addition & 0 deletions locking/tasks.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from __future__ import absolute_import
from celery import shared_task

from .models import NonBlockingLock
Expand Down
25 changes: 17 additions & 8 deletions locking/tests.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
"""
Tests for the locking application
"""
from __future__ import absolute_import
import uuid

from freezegun import freeze_time

from django.contrib.auth.models import User
from django.test import TestCase

from .exceptions import AlreadyLocked, RenewalError
from .exceptions import AlreadyLocked, RenewalError, NonexistentLock, NotLocked, Expired
from .models import NonBlockingLock, _get_lock_name
from .tasks import clean_expired_locks

Expand All @@ -23,6 +24,7 @@ def test_acquire_and_release(self):
self.assertTrue(NonBlockingLock.objects.is_locked(self.user))
l.release()
self.assertTrue(not NonBlockingLock.objects.is_locked(self.user))
self.assertRaises(NotLocked, l.release, silent=False)
l2 = NonBlockingLock.objects.acquire_lock(self.user)
self.assertTrue(NonBlockingLock.objects.is_locked(self.user))
NonBlockingLock.objects.release_lock(l2.pk)
Expand Down Expand Up @@ -57,6 +59,20 @@ def test_acquire_and_renew(self):
self.assertEqual(l.pk, l2.pk)
self.assertEqual(l.expires_on, l2.expires_on)

def test_renew_expired(self):
''' Tests renew an expired lock '''
with freeze_time("2015-01-01 10:00"):
l = NonBlockingLock.objects.acquire_lock(self.user, 1)
self.assertRaises(Expired, l.renew)

def test_renew_nonexistinglock(self):
''' Tests renewing a non existent lock '''
self.assertRaises(NonexistentLock, NonBlockingLock.objects.renew_lock, uuid.uuid4())

def test_release_nonexistinglock(self):
''' Tests release a non existent lock '''
self.assertRaises(NotLocked, NonBlockingLock.objects.release_lock, uuid.uuid4())

def test_lock_twice(self):
''' Tests a double locking (lock and try to lock again) '''
l = NonBlockingLock.objects.acquire_lock(self.user)
Expand Down Expand Up @@ -85,13 +101,6 @@ def test_model(self):
self.assertEquals(l.locked_object, 'test_lock')
self.assertIsInstance(l.id, uuid.UUID)

def test_unicode(self):
''' Test the __unicode__ '''
l = NonBlockingLock.objects.acquire_lock(self.user)
str_rep = '%s' % l
self.assertNotEquals(str_rep.find('%d' % self.user.id), -1)
l.release()

def test_relock(self):
'''Test to allow lock if lock is expired'''
with freeze_time("2015-01-01 10:00"):
Expand Down
4 changes: 4 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[pytest]
DJANGO_SETTINGS_MODULE=test_project.settings
python_files = test*.py
norecursedirs = .* *.egg *.egg-info wheel dist build artifacts
1 change: 1 addition & 0 deletions requirements/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Django
23 changes: 23 additions & 0 deletions requirements/requirements_test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
celery

# freeze time
freezegun

# pytest
pytest
pytest-django

# coverage
pytest-cov
coverage
coveralls


# flake8
flake8
pep8
pyflakes
mccabe
pep8-naming
flake8-print
flake8-debugger
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[bdist_wheel]
universal = 1
51 changes: 27 additions & 24 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,30 @@
from setuptools import setup, find_packages
from setuptools.command.test import test as SetuptoolsTestCommand
from pip.req import parse_requirements
from pip.download import PipSession
import locking

from os import path

class RunTestsCommand(SetuptoolsTestCommand):
def initialize_options(self):
SetuptoolsTestCommand.initialize_options(self)
self.test_suite = "override"

def finalize_options(self):
SetuptoolsTestCommand.finalize_options(self)
self.test_suite = None
# Lists of requirements and dependency links which are needed during runtime, testing and setup
install_requires = []
tests_require = []
dependency_links = []

def run(self):
SetuptoolsTestCommand.run(self)
self.with_project_on_sys_path(self.run_tests)
# Inject requirements from requirements.txt into setup.py
requirements_file = parse_requirements(path.join('requirements', 'requirements.txt'), session=PipSession())
for req in requirements_file:
install_requires.append(str(req.req))
if req.link:
dependency_links.append(str(req.link))

def run_tests(self):
import os
import subprocess
import sys
# Inject test requirements from requirements_test.txt into setup.py
requirements_test_file = parse_requirements(path.join('requirements', 'requirements_test.txt'), session=PipSession())
for req in requirements_test_file:
tests_require.append(str(req.req))
if req.link:
dependency_links.append(str(req.link))

env = os.environ.copy()
env["PYTHONPATH"] = os.pathsep.join(sys.path)

cmd = [sys.executable, 'test_project/manage.py', 'test']
errno = subprocess.call(cmd, env=env)

raise SystemExit(errno)

setup(
name="django-db-locking",
Expand All @@ -39,11 +36,17 @@ def run_tests(self):
author='VikingCo',
author_email='operations@unleashed.be',
packages=find_packages('.'),
cmdclass={'test': RunTestsCommand},
tests_require=['django', 'freezegun', 'celery'],
include_package_data=True,
install_requires=install_requires,
extras_require = {'celery': ["celery"] },
tests_require=tests_require,
dependency_links=dependency_links,
classifiers=[
'Intended Audience :: Developers',
'Programming Language :: Python',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.6',
'Operating System :: OS Independent',
'Environment :: Web Environment',
'Framework :: Django',
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions test_project/manage.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python
from __future__ import absolute_import
import os
import sys

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"""

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
from __future__ import absolute_import
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Expand Down
1 change: 1 addition & 0 deletions test_project/test_project/urls.py → test_project/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
1. Add an import: from blog import urls as blog_urls
2. Add a URL to urlpatterns: url(r'^blog/', include(blog_urls))
"""
from __future__ import absolute_import
from django.conf.urls import include, url
from django.contrib import admin

Expand Down
1 change: 1 addition & 0 deletions test_project/test_project/wsgi.py → test_project/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
https://docs.djangoproject.com/en/1.8/howto/deployment/wsgi/
"""

from __future__ import absolute_import
import os

from django.core.wsgi import get_wsgi_application
Expand Down

0 comments on commit 00a069d

Please sign in to comment.