Ticket #2879: django_live_server_r7936.diff
File django_live_server_r7936.diff, 8.7 KB (added by , 16 years ago) |
---|
-
django/test/testcases.py
1 import re 2 import unittest 1 import re, socket, threading, unittest 3 2 from urlparse import urlsplit, urlunsplit 4 3 5 4 from django.http import QueryDict 6 5 from django.db import transaction 7 6 from django.conf import settings 8 7 from django.core import mail 8 from django.core.handlers.wsgi import WSGIHandler 9 9 from django.core.management import call_command 10 from django.core.servers import basehttp 10 11 from django.test import _doctest as doctest 11 12 from django.test.client import Client 13 from django.test.utils import create_test_db 12 14 from django.core.urlresolvers import clear_url_caches 13 15 14 16 normalize_long_ints = lambda s: re.sub(r'(?<![\w])(\d+)L(?![\w])', '\\1', s) … … 49 51 # side effects on other tests. 50 52 transaction.rollback_unless_managed() 51 53 54 class TestServerThread(threading.Thread): 55 """Thread for running a http server while tests are running.""" 56 57 def __init__(self, address, port): 58 self.address = address 59 self.port = port 60 self._stopevent = threading.Event() 61 self.started = threading.Event() 62 self.error = None 63 super(TestServerThread, self).__init__() 64 65 def run(self): 66 """Sets up test server and database and loops over handling http requests.""" 67 try: 68 handler = basehttp.AdminMediaHandler(WSGIHandler()) 69 server_address = (self.address, self.port) 70 httpd = basehttp.StoppableWSGIServer(server_address, basehttp.WSGIRequestHandler) 71 httpd.set_app(handler) 72 self.started.set() 73 except basehttp.WSGIServerException, e: 74 self.error = e 75 self.started.set() 76 return 77 78 # Must do database stuff in this new thread if database in memory. 79 from django.conf import settings 80 if settings.DATABASE_ENGINE == 'sqlite3' \ 81 and (not settings.TEST_DATABASE_NAME or settings.TEST_DATABASE_NAME == ':memory:'): 82 db_name = create_test_db(0) 83 # Import the fixture data into the test database. 84 if hasattr(self, 'fixtures'): 85 # We have to use this slightly awkward syntax due to the fact 86 # that we're using *args and **kwargs together. 87 call_command('loaddata', *self.fixtures, **{'verbosity': 0}) 88 89 # Loop until we get a stop event. 90 while not self._stopevent.isSet(): 91 httpd.handle_request() 92 93 def join(self, timeout=None): 94 """Stop the thread and wait for it to finish.""" 95 self._stopevent.set() 96 threading.Thread.join(self, timeout) 97 52 98 class TestCase(unittest.TestCase): 53 99 def _pre_setup(self): 54 100 """Performs any pre-test setup. This includes: … … 105 151 settings.ROOT_URLCONF = self._old_root_urlconf 106 152 clear_url_caches() 107 153 154 def start_test_server(self, address='localhost', port=8000): 155 """Creates a live test server object (instance of WSGIServer).""" 156 self.server_thread = TestServerThread(address, port) 157 self.server_thread.start() 158 self.server_thread.started.wait() 159 if self.server_thread.error: 160 raise self.server_thread.error 161 162 def stop_test_server(self): 163 if self.server_thread: 164 self.server_thread.join() 165 108 166 def assertRedirects(self, response, expected_url, status_code=302, 109 167 target_status_code=200, host=None): 110 168 """Asserts that a response redirected to a specific URL, and that the -
django/core/servers/basehttp.py
11 11 import mimetypes 12 12 import os 13 13 import re 14 import socket 14 15 import sys 15 16 import urllib 16 17 … … 658 659 start_response(status, headers.items()) 659 660 return output 660 661 662 class StoppableWSGIServer(WSGIServer): 663 """WSGIServer with short timeout, so that server thread can stop this server.""" 664 665 def server_bind(self): 666 """Sets timeout to 1 second.""" 667 WSGIServer.server_bind(self) 668 self.socket.settimeout(1) 669 670 def get_request(self): 671 """Checks for timeout when getting request.""" 672 try: 673 sock, address = self.socket.accept() 674 sock.settimeout(None) 675 return (sock, address) 676 except socket.timeout: 677 raise 678 661 679 def run(addr, port, wsgi_handler): 662 680 server_address = (addr, port) 663 681 httpd = WSGIServer(server_address, WSGIRequestHandler) -
tests/regressiontests/test_client_regress/models.py
7 7 from django.core.exceptions import SuspiciousOperation 8 8 import os 9 9 import sha 10 import urllib 10 11 11 12 class AssertContainsTests(TestCase): 12 13 def test_contains(self): … … 327 328 "URLconf is reverted to original value after modification in a TestCase" 328 329 url = reverse('arg_view', args=['somename']) 329 330 self.assertEquals(url, '/test_client_regress/arg_view/somename/') 331 332 class TestServerTests(TestCase): 333 334 def setUp(self): 335 self.start_test_server(address='localhost', port=8001) 336 337 def tearDown(self): 338 self.stop_test_server() 339 340 def test_server_up(self): 341 url = urllib.urlopen('http://localhost:8001') 342 self.assertEqual(url.read(), 'Django Internal Tests: 404 Error') 343 url.close() 344 345 def test_serve_page(self): 346 url = urllib.urlopen('http://localhost:8001/accounts/login') 347 # Just make sure this isn't a 404, and we've gotten something. 348 self.assertNotEqual(url.read(), 'Django Internal Tests: 404 Error') 349 url.close() -
AUTHORS
273 273 Robert Myers <myer0052@gmail.com> 274 274 Nebojša Dorđević 275 275 Doug Napoleone <doug@dougma.com> 276 Devin Naquin <dnaquin@gmail.com> 276 277 Gopal Narayanan <gopastro@gmail.com> 277 278 Fraser Nevett <mail@nevett.org> 278 279 Sam Newman <http://www.magpiebrain.com/> -
docs/testing.txt
830 830 This test case will use the contents of ``myapp.test_urls`` as the 831 831 URLconf for the duration of the test case. 832 832 833 Running tests with a live test server 834 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 835 836 **New in Django development version** 837 838 When running tests that use in-browser frameworks such as Twille_ and 839 Selenium_, it's necessary to have a running test server. Django's custom 840 ``TestCase`` class supports starting a live server for these purposes. 841 842 ``start_test_server(address='localhost', port=8000)`` 843 Starts a test server at ``address`` on ``port``. This should be done in the 844 ``setUp()`` method of a subclass of ``TestCase``. The server then can be 845 accessed at http://address:port. 846 847 ``stop_test_server()`` 848 Stops the test server that was started with ``start_test_server``. This 849 must be done before ``start_test_server`` can be called again, so this 850 should be done in the ``tearDown()`` method of a subclass of ``TestCase``. 851 852 This can be used to start a server that can then be accessed by Twill, Selenium 853 or another in-browser test framework. For example:: 854 855 from django.test.testcases import TestCase 856 from selenium import selenium 857 858 class TestLogin(TestCase): 859 fixtures = ['login_info.xml'] 860 861 def setUp(self): 862 # Start a test server and tell selenium where to find it. 863 self.start_test_server('localhost', 8000) 864 self.selenium = selenium('localhost', 4444, \ 865 '*pifirefox', 'http://localhost:8000') 866 867 def tearDown(self): 868 # Stop server and Selenium 869 self.selenium.stop() 870 self.stop_test_server() 871 872 def testLogin(self): 873 self.selenium.open('/admin/') 874 self.selenium.type('username', 'admin') 875 self.selenium.type('password', 'password') 876 self.selenium.click("//input[@value='Log in']") 877 878 .. _Twill: http://twill.idyll.org/ 879 .. _Selenium: http://www.openqa.org/selenium/ 880 833 881 Emptying the test outbox 834 882 ~~~~~~~~~~~~~~~~~~~~~~~~ 835 883