summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorKevin Kubasik <kevin@kubasik.net>2009-06-23 07:02:54 +0000
committerKevin Kubasik <kevin@kubasik.net>2009-06-23 07:02:54 +0000
commite223716bd80ced8a2ca25ea4befc327f425c7203 (patch)
treeca94bc45308801ba77d984c51bf5fcebb5d29f1d /django
parent2fd60f00163e59bcd87350598af3029f7af5b2a3 (diff)
[gsoc2009-testing] Initial tests for the Admin views based on exisiting models and fixtures. runtest.py --windmill will activate them
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/test-improvements@11087 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
-rw-r--r--django/conf/global_settings.py2
-rw-r--r--django/core/management/commands/test_windmill.py10
-rw-r--r--django/test/test_coverage.py13
-rw-r--r--django/test/windmill_tests.py123
-rw-r--r--django/utils/module_tools/__init__.py16
5 files changed, 141 insertions, 23 deletions
diff --git a/django/conf/global_settings.py b/django/conf/global_settings.py
index 431b5208b8..eb9629990d 100644
--- a/django/conf/global_settings.py
+++ b/django/conf/global_settings.py
@@ -398,7 +398,7 @@ TEST_DATABASE_COLLATION = None
# Specify the coverage test runner
-COVERAGE_TEST_RUNNER = 'django.test.test_coverage.BaseCoverageRunner'
+COVERAGE_TEST_RUNNER = 'django.test.test_coverage.ConsoleReportCoverageRunner'
# Specify regular expressions of code blocks the coverage analyzer should
# ignore as statements (e.g. ``raise NotImplemented``).
diff --git a/django/core/management/commands/test_windmill.py b/django/core/management/commands/test_windmill.py
index d9b72f9c3e..406083c739 100644
--- a/django/core/management/commands/test_windmill.py
+++ b/django/core/management/commands/test_windmill.py
@@ -1,5 +1,6 @@
from django.core.management.base import BaseCommand
-from windmill.authoring import djangotest
+#from windmill.authoring import djangotest
+from django.test import windmill_tests as djangotest
import sys, os
from time import sleep
import types
@@ -18,7 +19,10 @@ def attempt_import(name, suffix):
s = name.split('.')
mod = __import__(s.pop(0))
for x in s+[suffix]:
- mod = getattr(mod, x)
+ try:
+ mod = getattr(mod, x)
+ except Exception, e:
+ pass
return mod
class Command(BaseCommand):
@@ -31,7 +35,7 @@ class Command(BaseCommand):
def handle(self, *labels, **options):
from windmill.conf import global_settings
- from windmill.authoring.djangotest import WindmillDjangoUnitTest
+ from django.test.windmill_tests import WindmillDjangoUnitTest
if 'ie' in labels:
global_settings.START_IE = True
sys.argv.remove('ie')
diff --git a/django/test/test_coverage.py b/django/test/test_coverage.py
index cf35795ee5..f6cf0312ac 100644
--- a/django/test/test_coverage.py
+++ b/django/test/test_coverage.py
@@ -63,6 +63,15 @@ class BaseCoverageRunner(object):
coverage_modules, getattr(settings, 'COVERAGE_MODULE_EXCLUDES', []),
getattr(settings, 'COVERAGE_PATH_EXCLUDES', []))
+
+
+ return results
+
+class ConsoleReportCoverageRunner(BaseCoverageRunner):
+
+ def run_tests(self, *args, **kwargs):
+ """docstring for run_tests"""
+ res = super(ConsoleReportCoverageRunner, self).run_tests( *args, **kwargs)
self.cov.report(self.modules.values(), show_missing=1)
if self.excludes:
@@ -77,9 +86,7 @@ class BaseCoverageRunner(object):
for e in self.errors:
print >> sys.stderr, e,
print >> sys.stdout
-
- return results
-
+ return res
class ReportingCoverageRunner(BaseCoverageRunner):
"""Runs coverage.py analysis, as well as generating detailed HTML reports."""
diff --git a/django/test/windmill_tests.py b/django/test/windmill_tests.py
new file mode 100644
index 0000000000..569f13a014
--- /dev/null
+++ b/django/test/windmill_tests.py
@@ -0,0 +1,123 @@
+
+# Code from django_live_server_r8458.diff @ http://code.djangoproject.com/ticket/2879#comment:41
+# Editing to monkey patch django rather than be in trunk
+
+import socket
+import threading
+from django.core.handlers.wsgi import WSGIHandler
+from django.core.servers import basehttp
+from django.test.testcases import call_command
+
+#from django.core.management import call_command
+
+# support both django 1.0 and 1.1
+try:
+ from django.test.testcases import TransactionTestCase as TestCase
+except ImportError:
+ from django.test.testcases import TestCase
+
+class StoppableWSGIServer(basehttp.WSGIServer):
+ """WSGIServer with short timeout, so that server thread can stop this server."""
+
+ def server_bind(self):
+ """Sets timeout to 1 second."""
+ basehttp.WSGIServer.server_bind(self)
+ self.socket.settimeout(1)
+
+ def get_request(self):
+ """Checks for timeout when getting request."""
+ try:
+ sock, address = self.socket.accept()
+ sock.settimeout(None)
+ return (sock, address)
+ except socket.timeout:
+ raise
+
+class TestServerThread(threading.Thread):
+ """Thread for running a http server while tests are running."""
+
+ def __init__(self, address, port):
+ self.address = address
+ self.port = port
+ self._stopevent = threading.Event()
+ self.started = threading.Event()
+ self.error = None
+ super(TestServerThread, self).__init__()
+
+ def run(self):
+ """Sets up test server and database and loops over handling http requests."""
+ try:
+ handler = basehttp.AdminMediaHandler(WSGIHandler())
+ httpd = None
+ while httpd is None:
+ try:
+ server_address = (self.address, self.port)
+ httpd = StoppableWSGIServer(server_address, basehttp.WSGIRequestHandler)
+ except basehttp.WSGIServerException, e:
+ if "Address already in use" in str(e):
+ self.port +=1
+ else:
+ raise e
+ httpd.set_app(handler)
+ self.started.set()
+ except basehttp.WSGIServerException, e:
+ self.error = e
+ self.started.set()
+ return
+
+ # Must do database stuff in this new thread if database in memory.
+ from django.conf import settings
+ if settings.DATABASE_ENGINE == 'sqlite3' \
+ and (not settings.TEST_DATABASE_NAME or settings.TEST_DATABASE_NAME == ':memory:'):
+ from django.db import connection
+ db_name = connection.creation.create_test_db(0)
+ # Import the fixture data into the test database.
+ if hasattr(self, 'fixtures'):
+ # We have to use this slightly awkward syntax due to the fact
+ # that we're using *args and **kwargs together.
+ call_command('loaddata', *self.fixtures, **{'verbosity': 0})
+
+ # Loop until we get a stop event.
+ while not self._stopevent.isSet():
+ httpd.handle_request()
+ httpd.server_close()
+
+ def join(self, timeout=None):
+ """Stop the thread and wait for it to finish."""
+ self._stopevent.set()
+ threading.Thread.join(self, timeout)
+
+
+def start_test_server(self, address='localhost', port=8000):
+ """Creates a live test server object (instance of WSGIServer)."""
+ self.server_thread = TestServerThread(address, port)
+ if hasattr(self, 'fixtures'):
+ self.server_thread.__setattr__('fixtures', self.fixtures)
+ self.server_thread.start()
+ self.server_thread.started.wait()
+ if self.server_thread.error:
+ raise self.server_thread.error
+
+def stop_test_server(self):
+ if self.server_thread:
+ self.server_thread.join()
+
+## New Code
+
+TestCase.start_test_server = classmethod(start_test_server)
+TestCase.stop_test_server = classmethod(stop_test_server)
+
+from windmill.authoring import unit
+
+class WindmillDjangoUnitTest(TestCase, unit.WindmillUnitTestCase):
+ test_port = 8000
+ def setUp(self):
+ self.start_test_server('localhost', self.test_port)
+ self.test_url = 'http://localhost:%d' % self.server_thread.port
+ unit.WindmillUnitTestCase.setUp(self)
+
+ def tearDown(self):
+ unit.WindmillUnitTestCase.tearDown(self)
+ self.stop_test_server()
+
+WindmillDjangoTransactionUnitTest = WindmillDjangoUnitTest
diff --git a/django/utils/module_tools/__init__.py b/django/utils/module_tools/__init__.py
index d940906d2d..976d4b5e4f 100644
--- a/django/utils/module_tools/__init__.py
+++ b/django/utils/module_tools/__init__.py
@@ -1,19 +1,3 @@
-"""
-Copyright 2009 55 Minutes (http://www.55minutes.com)
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-"""
-
from module_loader import *
from module_walker import *