Django

Code

Ticket #2879 (new)

Opened 2 years ago

Last modified 3 months ago

[patch] Add live test server support to test framework

Reported by: Mikeal Rogers <mikeal@osafoundation.org> Assigned to: devin
Milestone: Component: Testing framework
Version: Keywords:
Cc: russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick, wiswaud, martin@akoha.org, simon@akoha.org, alex@gc-web.de, zodizz@gmail.com, robert.ramirez@dooplan.com Triage Stage: Accepted
Has patch: 1 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

Description

This was necessary for ticket:2867 but is useful enough on it's own to be a separate enhancement ticket.

Added module is django.test.http which contains all the code to bring up a slightly modified version of the regular django test server. The module is simple to use, you simply create a unit test that inherits from django.test.http.HttpTestCase?. That class contains setUp and tearDown methods that bring up the test server and kill it when the test is complete.

The django test server had huge issues with the in memory database, which was the test framework default. I brought this up on the dev list and saw that other had issues using the in memory database as well. I removed ':memory' from being the default database, although if TEST_DATABASE_NAME is set to ":memory:" it will still work. I modified the database cleanup code to account for both cases as well (Note: previously the cleanup code didn't account properly for regular sqlite databases, it now accounts for both).

Attachments

http_test_case.diff (4.5 kB) - added by Mikeal Rogers <mikeal@osafoundation.org> on 10/06/06 21:01:53.
path to resole this enhancement
http_test_case.2.diff (4.5 kB) - added by Mikeal Rogers <mikeal@osafoundation.org> on 10/06/06 21:10:03.
fixed comment typo and improper print statement
core-management.patch (1.9 kB) - added by Dirk Datzert <dummy@habmalnefrage.de> on 06/05/07 14:36:22.
runtestserver command for manage.py
testing.patch (1.4 kB) - added by Dirk Datzert <dummy@habmalnefrage.de> on 06/06/07 13:22:18.
testing contrib to flush database during tests
test-server-support.patch (1.9 kB) - added by Almad <bugs@almad.net> on 06/09/07 06:34:21.
All patches in one, with reverted utils.py
run_test_server_simple.py.diff (1.2 kB) - added by Denis Golomazov <denis.golomazov@gmail.com> on 11/21/07 08:46:10.
run_test_server_utils.py.diff (0.7 kB) - added by Denis Golomazov <denis.golomazov@gmail.com> on 11/21/07 08:50:39.
The second part of the patch
django_live_server.diff (8.0 kB) - added by devin on 06/27/08 17:55:14.
fixes way server handles error on startup
django_live_server_r7936.diff (8.7 kB) - added by devin on 07/16/08 21:10:34.
refactor and cleanup
django_live_server_r8458.diff (8.9 kB) - added by robertrv on 08/21/08 09:22:54.
Updated devin's patch with last changes in testing environment

Change History

10/06/06 21:01:53 changed by Mikeal Rogers <mikeal@osafoundation.org>

  • attachment http_test_case.diff added.

path to resole this enhancement

10/06/06 21:03:33 changed by Mikeal Rogers <mikeal@osafoundation.org>

  • owner changed from Mikeal Rogers to anonymous.
  • status changed from new to assigned.
  • summary changed from Add live test server support to test framework to [patch] Add live test server support to test framework.

Adding patch to subject.

10/06/06 21:04:10 changed by Mikeal Rogers <mikeal@osafoundation.org>

  • owner changed from anonymous to Mikeal Rogers.
  • status changed from assigned to new.

Whoops.

10/06/06 21:10:03 changed by Mikeal Rogers <mikeal@osafoundation.org>

  • attachment http_test_case.2.diff added.

fixed comment typo and improper print statement

10/09/06 17:03:22 changed by Mikeal Rogers <mikeal@osafoundation.org>

  • owner deleted.

Un-assigning from myself since this needs to be reviewed by a commiter.

10/16/06 19:51:39 changed by russellm

  • owner set to russellm.

01/30/07 15:22:31 changed by mir@noris.de

How does this relate to the unit test system that has evolved since then?

01/30/07 15:25:52 changed by mikeal

I haven't looked at the code base since I wrote this patch. So my short answer would be that it doesn't relate at all and probably breaks.

If the new unittest system includes support for running a live server and making real requests then this patch is obsolete.

If the new unittest system doesn't have list server support then I should probably rewrite this patch to provide the support within the new framework.

01/30/07 15:29:17 changed by mir@noris.de

Wow, Mikeal, that was a fast reply. Could you, as time permits, look whether this is still needed and put a little comment in the ticket?

01/30/07 15:32:10 changed by mir@noris.de

  • cc set to russellm.

Or perhaps Russell could take a short look, he should be able to spot it without looking ;-) I don't know the unit test so well. I'm only doing triage here.

01/30/07 15:54:07 changed by mikeal

The testing documentation doesn't seem to have changed since I wrote this patch.

http://www.djangoproject.com/documentation/testing/

Regardless I think I could do this a little more elegantly now. I also read about support for cherrypy's wsgi when installed which I think would be important to add since that big hack to kill the server isn't necessary using the cherrypy server. Eww, and I'm raising a string instead of a proper exception in there.

I'll try to find some time this week or next to work on this.

06/05/07 14:36:22 changed by Dirk Datzert <dummy@habmalnefrage.de>

  • attachment core-management.patch added.

runtestserver command for manage.py

06/05/07 14:38:56 changed by Dirk Datzert <dummy@habmalnefrage.de>

With the core-management.patch it would be possible to start a test server like './manage.py runserver' with the command './manage.py runtestserver'. It would be setup a test-db like with './manage test' and loaded fixtures called 'initial_data' and 'test_data'.

06/06/07 13:22:18 changed by Dirk Datzert <dummy@habmalnefrage.de>

  • attachment testing.patch added.

testing contrib to flush database during tests

06/06/07 13:28:15 changed by Dirk Datzert <dummy@habmalnefrage.de>

Together with the core-management.patch it would be possible to flush a running live test server between tests.

06/06/07 16:55:02 changed by Simon G. <dev@simon.net.nz>

  • stage changed from Unreviewed to Design decision needed.

06/09/07 06:22:55 changed by Almad <bugs@almad.net>

Confirmed that it worksforme on SVN HEAD of unicode branch.

Just, changes made on django/test/utils.py by http_test_case.2.diff patch has to be reverted, as database syssetm changed meantime.

I'd be very very glad to see this patch being checked in ASAP as I'm using it on all my projects already.

06/09/07 06:34:21 changed by Almad <bugs@almad.net>

  • attachment test-server-support.patch added.

All patches in one, with reverted utils.py

08/26/07 18:23:01 changed by anonymous

  • cc changed from russellm to russellm, allandouglas@gmail.com.

09/07/07 23:58:57 changed by russellm

  • stage changed from Design decision needed to Accepted.

09/16/07 08:27:54 changed by ubernostrum

  • status changed from new to closed.
  • resolution set to fixed.

I believe this was fixed in [5912] with the addition of manage.py testserver.

09/22/07 07:39:49 changed by russellm

  • status changed from closed to reopened.
  • resolution deleted.

This is a little different to manage.py testserver. The testserver command is about getting a server that uses test data; this ticket is about starting a server during a test case so that a test case can poke AJAX-style methods, or write a view that in turn makes HTTP calls. This is needed if you are going to run Selenium-style tests, as the test case needs to interact with a live running server.

10/17/07 14:54:40 changed by bugs@almad.net

Is there a way to see this one in trunk?

Anything needs to be done, or any way how to speed it up?

(follow-up: ↓ 21 ) 10/17/07 15:02:18 changed by Mikeal Rogers <mikeal@osafoundation.org>

The patch attached to this bug won't work in the current trunk.

I can write another one but after seeing what happened to the last patch I'd like to know that someone is actually going to review it before it becomes outdated like the last one.

10/17/07 15:04:18 changed by Mikeal Rogers <mikeal@osafoundation.org>

Sorry, i was trying to apply the wrong patch.

Haven't tried the newest set.

(in reply to: ↑ 19 ) 10/18/07 00:11:30 changed by russellm

  • needs_better_patch set to 1.
  • needs_tests set to 1.
  • needs_docs set to 1.

Replying to Mikeal Rogers <mikeal@osafoundation.org>:

The patch attached to this bug won't work in the current trunk. I can write another one but after seeing what happened to the last patch I'd like to know that someone is actually going to review it before it becomes outdated like the last one.

The requirements for this patch are the same as every other patch, as documented here:

http://www.djangoproject.com/documentation/contributing/#patch-style

In short:

  1. Your patch needs to encompass a single idea. In this case, adding a TestCase? with a test server. The :memory: change is probably a reasonable change, but is unrelated to the ticket purpose. It should be logged and processed as separate issue.
  2. Your patch needs tests. A regression test that demonstrates that the new test case works is an absolute minimum. Unless a patch is trivial, or I need the feature/fix myself, or it's difficult/impossible to test the feature (e.g., testing command line options to ./manage.py), I won't even bother looking at a patch until it has tests. I'm too busy to spend my days trying to work out how other peoples code should work. A test is how you prove you are serious about using my time.
  3. Your patch needs documentation. If you have tests, documentation can wait until after an initial review - but if you don't have a test, then you're going to need to document how your feature works.
  4. (Generally required, but not so much in this case since this ticket is on my watch list) - the triage team needs to review and promote the patch.

(follow-up: ↓ 23 ) 10/18/07 00:33:41 changed by Mikeal Rogers <mikeal@osafoundation.org>

I originally wrote this a long time ago (at least in web years). I've learned a lot since then and have mde my way through a dozen test frameworks and developed a few myself. I took a few hours out of my day today and try to re-assess the situation.

IMHO TestCase? is not the right place for this. TestCase? can only define setup and teardown for a single unittest class, this needs to define something that can be a product of the test environment that encompasses multiple test classes and suites.

It's been a while since I monkeyed around with unittest, but having done this in the past I know it's not easy and is one of the primary reasons people don't like unittest.

I also haven't looked at the test infrastructure for django in a long time, just a quick glance shows that a lot seems to have changed, so I don't know if this is even possible.

Eventually I'm going to need to integrate windmill (http://windmill.osafoundation.org) tests in to my own django project. When that work is finished I'll send a proposal to the list to see if it would be a valued contribution, but doing this right will probably require a new collector based framework with more acutely defined setup/teardown.

In the meantime, if anyone wants to take on this work again ( adding a TestCase? with live server support ) they are more than welcome to it, you can email me personally if you have any implementation specific questions. I'm more than happy to help I'm just not up for wrangling unittest anymore.

(in reply to: ↑ 22 ) 10/27/07 13:10:07 changed by Almad <bugs@almad.net>

Replying to Mikeal Rogers <mikeal@osafoundation.org>:

I'm more than happy to help I'm just not up for wrangling unittest anymore.

Well, it's not a problem to implement nose et al via settings.TEST_RUNNER option. However, even if SeleniumTestCase? (or equivalent) is discovered, connected to selenium proxy and browser is started successfully, tests are still not usable as they cannot connect to live server :]

(IMHO biggest flaw in unittest is absence of SkipTest?...)

11/21/07 08:46:10 changed by Denis Golomazov <denis.golomazov@gmail.com>

  • attachment run_test_server_simple.py.diff added.

11/21/07 08:47:48 changed by Denis Golomazov <denis.golomazov@gmail.com>

Well, the last patch seems not to work in current trunk version. The structure of django/core has changed, and I see no obvious way of implementing the patch.

I've created my own patch which seems to do the job. At least it works for me. Probably you'll need Python 2.5 to run it and, of course, Linux (since the fork() method is not implemented in Windows, as I believe). I tested it only with SQLite and really don't know if it'll work with other backends.

The patch does a simple thing: after initializing environment and creating a test database, it forks and in child process a Django server is started. Being a child, it inherits the environment. In parent process, a test is started (which can include both Django TestCase and Selenium methods), and when it finishes the child is killed and the parent returns the result. The patch consists of two files, one for django/test/simple.py and another for django/test/utils.py.

One little thing to mention: I couldn't manage to make this idea work when I used :memory: database (which is default for SQLite in tests), thus I changed it to file. Then it worked.

Using this method you probably will not have to use testserver (see [5912]).

Any comments would be much appreciated.

11/21/07 08:50:39 changed by Denis Golomazov <denis.golomazov@gmail.com>

  • attachment run_test_server_utils.py.diff added.

The second part of the patch

11/21/07 08:58:24 changed by Denis Golomazov <denis.golomazov@gmail.com>

Sorry, but I can't figure out why diff for the first file isn't displayed.

06/12/08 13:44:58 changed by devin

  • owner changed from nobody to devin.
  • status changed from reopened to new.

I have something working that will add this functionality to TestCase?. I'll clean up my patch, write some tests, and get something here today or tomorrow.

06/13/08 18:15:55 changed by devin

  • needs_better_patch deleted.
  • needs_tests deleted.
  • needs_docs deleted.

I've added this functionality to the TestCase? class.

The problem Mikeal mentioned with regards to in-memory databases (http://tinyurl.com/5p3g2y) was not a problem with the database, only in the attempt to access an in-memory database within a separate thread. Because of the threading, we have to special case in-memory databases.

Tests and documentation changes are included.

06/13/08 18:28:30 changed by devin

  • cc changed from russellm, allandouglas@gmail.com to russellm, allandouglas@gmail.com, dnaquin@gmail.com.

06/13/08 18:33:59 changed by ubernostrum

Could somebody clarify for me what this does that can't be handled by, or built on top of, django-admin.py/manage.py testserver? Since that's implemented as a management command, it can be called from Python code as needed, which (if this feature is still needed to address a problem with testserver) looks like it'd greatly simplify this patch.

06/13/08 18:43:32 changed by devin

Yeah, directly calling testserver would greatly simplify things. The main problem with that, however, is that testserver isn't stoppable. After running a test, I need to be able to stop the server, reload fixtures, etc.

I agree though, I'm not happy with how much code I'm repeating. Suggestions welcome.

06/15/08 03:37:30 changed by jbeigel

  • cc changed from russellm, allandouglas@gmail.com, dnaquin@gmail.com to russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel.

06/25/08 18:54:41 changed by anonymous

  • cc changed from russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel to russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com.

06/27/08 16:41:27 changed by devin

  • needs_better_patch set to 1.

I'm working on improving the way this fails when problems starting a test server are encountered. I'll have a better patch shortly.

06/27/08 17:55:14 changed by devin

  • attachment django_live_server.diff added.

fixes way server handles error on startup

06/27/08 17:55:43 changed by devin

  • needs_better_patch deleted.

07/16/08 21:10:34 changed by devin

  • attachment django_live_server_r7936.diff added.

refactor and cleanup

07/29/08 23:32:03 changed by mtredinnick

  • cc changed from russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com to russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick.

07/31/08 22:34:53 changed by wiswaud

  • cc changed from russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick to russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick, wiswaud, martin@akoha.org, simon@akoha.org.

08/03/08 23:03:51 changed by alex@gc-web.de

  • cc changed from russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick, wiswaud, martin@akoha.org, simon@akoha.org to russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick, wiswaud, martin@akoha.org, simon@akoha.org, alex@gc-web.de.

08/04/08 21:33:57 changed by devin

One thing to note about my patch, while it's on my mind:

In order to be able to stop the running test webserver, I need to set a socket timeout on waiting for requests. eg:

    def server_bind(self):
        """ Sets timeout to 1 second. """
        WSGIServer.server_bind(self)
        self.socket.settimeout(1)

But what happens when you're waiting on a request that always takes longer than 1 second? You'll continually timeout? You'll fail on a selenium wait? Decidedly something quote unquote not good.

I don't know a clean solution to this. I need some kind of timeout. Otherwise, there's no way to stop mid handle_request(). And then no way to kill the server after a test is done. It'll just hang on that handle_request(). But any timeout is subject to problems if it needs to handle a request that's going to take longer.

        # Loop until we get a stop event
        while not self._stopevent.isSet():
            httpd.handle_request()

And since there's no way to kill a python thread, there's no other way to stop this server.

We could have this timeout as a parameter and default to 1s. That way at least if people run up against the problem they can up the timeout and fix it.

08/05/08 18:30:40 changed by devin

Nevermind. The patch handles this.

That server_bind timeout is just for receiving requests. Once the server grabs a request it sets the socket for handling it to None.

            sock, address = self.socket.accept()
            sock.settimeout(None)
            return (sock, address)

So requests can take however long.

Actually. The timeout should be a lot smaller then. 0.001s working fine for me.

08/12/08 00:21:26 changed by anonymous

  • cc changed from russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick, wiswaud, martin@akoha.org, simon@akoha.org, alex@gc-web.de to russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick, wiswaud, martin@akoha.org, simon@akoha.org, alex@gc-web.de, zodizz@gmail.com.

08/14/08 01:48:18 changed by anonymous

  • cc changed from russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick, wiswaud, martin@akoha.org, simon@akoha.org, alex@gc-web.de, zodizz@gmail.com to russellm, allandouglas@gmail.com, dnaquin@gmail.com, jbeigel, andrew@disqus.com, mtredinnick, wiswaud, martin@akoha.org, simon@akoha.org, alex@gc-web.de, zodizz@gmail.com, robert.ramirez@dooplan.com.

08/21/08 09:22:54 changed by robertrv

  • attachment django_live_server_r8458.diff added.

Updated devin's patch with last changes in testing environment

09/08/08 01:17:01 changed by mikeal

I borrowed the code from the latest patch here to add Django support to windmill.

http://trac.getwindmill.com/browser/trunk/windmill/authoring/djangotest.py

It hasn't been fully documented yet but the simplest case was written up for the email list.

http://groups.google.com/group/windmill-dev/browse_thread/thread/85f23d2a0d4e99


Add/Change #2879 ([patch] Add live test server support to test framework)




Change Properties
Action