-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Jon Lønne
committed
Sep 19, 2012
0 parents
commit e66fc87
Showing
16 changed files
with
537 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
dist/ | ||
*.egg-info/ | ||
*.egg/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
Copyright (c) 2012, Funkbit AS. | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without | ||
modification, are permitted provided that the following conditions are met: | ||
* Redistributions of source code must retain the above copyright | ||
notice, this list of conditions and the following disclaimer. | ||
* Redistributions in binary form must reproduce the above copyright | ||
notice, this list of conditions and the following disclaimer in the | ||
documentation and/or other materials provided with the distribution. | ||
* Neither the name of the Dokus service nor the | ||
names of its contributors may be used to endorse or promote products | ||
derived from this software without specific prior written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY FUNKBIT AS ''AS IS'' | ||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
DISCLAIMED. IN NO EVENT SHALL FUNKBIT AS BE LIABLE | ||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# django-doctor | ||
|
||
django-doctor is a Django app for checking the operational status of a Django | ||
installation. It includes checking that caching and storage is correctly | ||
set up, that email is working, etc. | ||
|
||
This is an early draft, so use it at your own risk. | ||
|
||
|
||
## Installation | ||
|
||
Install `django-doctor` (available on PyPi): | ||
|
||
pip install django-doctor | ||
|
||
Add it to `INSTALLED_APPS` in your `settings.py`: | ||
|
||
INSTALLED_APPS += ['doctor'] | ||
|
||
And add it to your root urls.py file: | ||
|
||
url(r'^doctor/', include('doctor.urls')), | ||
|
||
|
||
## Settings | ||
|
||
These are the available configurable settings, along with their default values: | ||
|
||
<table> | ||
<tr> | ||
<th align="left">Name</th> | ||
<th align="left">Default</th> | ||
<th align="left">Description</th> | ||
</tr> | ||
<tr> | ||
<td><code>DOCTOR_BASE_TEMPLATE</code></td> | ||
<td><code>'base.html'</code></td> | ||
<td>The template all the doctor templates should inherit from</td> | ||
</tr> | ||
</table> | ||
|
||
## Tests | ||
|
||
Run unit tests by running <code>python setup.py test</code> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
version_info = (0, 1, 0) | ||
__version__ = '.'.join(map(str, version_info)) |
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from django.contrib.sites.models import Site | ||
from django.core.mail import mail_admins | ||
from django.core.management.base import BaseCommand | ||
|
||
|
||
class Command(BaseCommand): | ||
""" | ||
Test the sending of email with the mail_admins command. | ||
""" | ||
|
||
help = 'Test sending of email.' | ||
|
||
def handle(self, *args, **options): | ||
|
||
verbosity = int(options.get('verbosity', 1)) | ||
|
||
message = 'This is a test mail from %(site_name)s. If you see this, mail is working :)' % { | ||
'site_name': Site.objects.get_current().name, | ||
} | ||
|
||
try: | ||
mail_admins('Test mail', message, fail_silently=False) | ||
|
||
if verbosity > 0: | ||
self.stdout.write('Mail successfully sent to admins.\n') | ||
|
||
except Exception as exc: | ||
self.stderr.write('Sending test mail failed! Exception was: %s\n' % str(exc)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
from django.conf import settings | ||
from django.core.files.base import ContentFile | ||
from django.core.files.storage import default_storage | ||
from django.core.management.base import BaseCommand | ||
|
||
|
||
class Command(BaseCommand): | ||
""" | ||
Test various file storage operations, to ensure that integrations (with ie. | ||
Amazon S3) is working properly. | ||
""" | ||
|
||
help = 'Test file storage operations.' | ||
|
||
def handle(self, *args, **options): | ||
|
||
verbosity = int(options.get('verbosity', 1)) | ||
filename = 'storage_test' | ||
|
||
if verbosity > 0: | ||
self.stdout.write('Storage used: %s\n' % settings.DEFAULT_FILE_STORAGE) | ||
|
||
# Create a file | ||
default_storage.save(filename, ContentFile('We are testing, 1 2 three.')) | ||
|
||
# Check for existence | ||
file_exists = default_storage.exists(filename) | ||
|
||
if verbosity > 0: | ||
self.stdout.write('Does newly created file exist? %s\n' % file_exists) | ||
|
||
# Read back the file | ||
f = default_storage.open(filename, 'r') | ||
file_contents = f.read() | ||
f.close() | ||
|
||
if verbosity > 0: | ||
self.stdout.write('Contents: "%s"\n' % file_contents) | ||
|
||
# Delete the file | ||
default_storage.delete(filename) | ||
file_exists = default_storage.exists(filename) | ||
|
||
if verbosity > 0: | ||
self.stdout.write('Does file exist after deletion? %s\n' % file_exists) |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
{% extends base_template %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
{% extends "doctor/base.html" %} | ||
{% load i18n %} | ||
|
||
{% block title %}{% trans 'Health checks' %} — {{ block.super }}{% endblock %} | ||
|
||
{% block content %} | ||
<h2> | ||
{% trans 'Health checks' %} | ||
</h2> | ||
|
||
<h3> | ||
{% trans 'Cache' %} | ||
</h3> | ||
|
||
<table class="table"> | ||
<tbody> | ||
{% for cache_name, info in cache.iteritems %} | ||
<tr> | ||
<td style="width: 40%;"> | ||
<h4> | ||
{{ cache_name }} | ||
</h4> | ||
|
||
{% if info.is_working %} | ||
<strong>{% trans 'Status:' %}</strong> {% trans 'OK' %}<br> | ||
<small class="muted">{{ info.message }}</small> | ||
{% else %} | ||
<div class="alert alert-error"> | ||
<h4>{% trans 'Error' %}</h4> | ||
{{ info.message }} | ||
</div> | ||
{% endif %} | ||
</td> | ||
<td> | ||
|
||
<table class="table table-bordered table-condensed"> | ||
<thead> | ||
<th>{% trans 'Setting' %}</th> | ||
<th>{% trans 'Value' %}</th> | ||
</thead> | ||
<tbody> | ||
{% for key, val in info.settings.iteritems %} | ||
<tr> | ||
<td><code>{{ key }}</code></td> | ||
<td><code>{{ val }}</code></td> | ||
</tr> | ||
{% endfor %} | ||
</tbody> | ||
</table> | ||
|
||
</td> | ||
</tr> | ||
{% endfor %} | ||
</tbody> | ||
</table> | ||
|
||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{% extends "doctor/base.html" %} | ||
{% load i18n %} | ||
|
||
{% block title %}{% trans 'Technical information' %} — {{ block.super }}{% endblock %} | ||
|
||
{% block content %} | ||
<h2> | ||
{% trans 'Technical information' %} | ||
</h2> | ||
|
||
|
||
<h3> | ||
{% trans 'Module versions' %} | ||
</h3> | ||
|
||
<table class="table table-striped table-bordered table-hover"> | ||
<thead> | ||
<tr> | ||
<th>{% trans 'Name' %}</th> | ||
<th>{% trans 'Version' %}</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{% for package, version in versions.iteritems %} | ||
<tr> | ||
<td>{{ package }}</td> | ||
<td>{{ version }}</td> | ||
</tr> | ||
{% endfor %} | ||
</tbody> | ||
</table> | ||
|
||
|
||
<h3> | ||
{% trans 'Environment' %} | ||
</h3> | ||
|
||
<pre>{% for key,val in environ.items %}{{ key }}: {{ val }}<br>{% endfor %}</pre> | ||
|
||
|
||
<h3> | ||
{% trans 'Paths' %} | ||
</h3> | ||
|
||
<pre>{% for path in paths %}{{ path }}<br>{% endfor %}</pre> | ||
|
||
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
from django.contrib.auth.models import User | ||
from django.core.urlresolvers import reverse | ||
from django.test import TestCase | ||
|
||
|
||
class DoctorAuthorizationTests(TestCase): | ||
|
||
def setUp(self): | ||
|
||
# Create active user to test with | ||
user = User(username='example_user', is_active=True) | ||
user.set_password('1234') | ||
user.save() | ||
|
||
self.user = user | ||
|
||
def testAnonymous(self): | ||
|
||
# Available for all users (for now) | ||
response = self.client.get(reverse('doctor-health-check')) | ||
self.assertEquals(response.status_code, 200) | ||
self.assertEquals(response['Content-Type'], 'text/plain') | ||
|
||
# Check non-accessable pages | ||
response = self.client.get(reverse('doctor-index')) | ||
self.assertEquals(response.status_code, 404) | ||
|
||
response = self.client.get(reverse('doctor-technical')) | ||
self.assertEquals(response.status_code, 404) | ||
|
||
response = self.client.get(reverse('doctor-server-error')) | ||
self.assertEquals(response.status_code, 404) | ||
|
||
def testNonPrivileged(self): | ||
|
||
# Sign in user | ||
self.client.login(username=self.user.username, password='1234') | ||
|
||
# Available for all users (for now) | ||
response = self.client.get(reverse('doctor-health-check')) | ||
self.assertEquals(response.status_code, 200) | ||
self.assertEquals(response['Content-Type'], 'text/plain') | ||
|
||
# Check non-accessable pages | ||
response = self.client.get(reverse('doctor-index')) | ||
self.assertEquals(response.status_code, 404) | ||
|
||
response = self.client.get(reverse('doctor-technical')) | ||
self.assertEquals(response.status_code, 404) | ||
|
||
response = self.client.get(reverse('doctor-server-error')) | ||
self.assertEquals(response.status_code, 404) | ||
|
||
|
||
class DoctorViewTests(TestCase): | ||
|
||
def setUp(self): | ||
|
||
# Create super user to test with | ||
user = User(username='example_user', is_active=True, is_superuser=True) | ||
user.set_password('1234') | ||
user.save() | ||
|
||
self.user = user | ||
|
||
def testPrivileged(self): | ||
|
||
# Sign in user | ||
self.client.login(username=self.user.username, password='1234') | ||
|
||
# Check pages | ||
response = self.client.get(reverse('doctor-index')) | ||
self.assertEquals(response.status_code, 200) | ||
self.assertTemplateUsed(response, 'doctor/index.html') | ||
|
||
response = self.client.get(reverse('doctor-health-check')) | ||
self.assertEquals(response.status_code, 200) | ||
self.assertEquals(response['Content-Type'], 'text/plain') | ||
|
||
response = self.client.get(reverse('doctor-technical')) | ||
self.assertEquals(response.status_code, 200) | ||
self.assertTemplateUsed(response, 'doctor/technical_info.html') | ||
|
||
def testForceServerError(self): | ||
|
||
# Make superuser | ||
self.user.is_superuser = True | ||
self.user.save() | ||
|
||
# Sign in user | ||
self.client.login(username=self.user.username, password='1234') | ||
|
||
with self.assertRaises(Exception): | ||
response = self.client.get(reverse('doctor-server-error')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
from django.conf.urls import patterns, include, url | ||
|
||
urlpatterns = patterns('doctor.views', | ||
|
||
url(r'^health-check/$', 'health_check', name='doctor-health-check'), | ||
url(r'^technical/$', 'technical_info', name='doctor-technical'), | ||
url(r'^server-error/$', 'force_server_error', name='doctor-server-error'), | ||
|
||
url(r'^$', 'index', name='doctor-index'), | ||
|
||
) |
Oops, something went wrong.