Category Archives: django

http://www.djangoproject.com/

Functional testing with Lettuce and Fabric

After the launch of Nebula, from which I think I’m mostly recovered, I’ve been thinking about and working on ways to allow us to accelerate development. Our team has done a fair bit of work on the Openstack Dashboard, an incubating project within OpenStack, and we have a couple of internal http based interfaces for our own pieces.

We have unit testing up and running, and like most projects a few of those tests are more “functional” or “integration” tests than actually unit tests, but really the project’s been pretty darn good about keeping those separate. As it turns out, the Junit framework is truly awesome for fast, quick tests – but when you start to step into functional testing you want just a touch more linearity to the testing. The unit test frameworks that I’ve run into (nosetests, unittest2) don’t have much in their mechanisms that allow you to set up longer, repeated sequences or flows, so it was time to look around for what else might work there. (sidenote: If you know of some mechanisms that do longer, sequential tests and are based around unittest2 or nose, I’d love it hear about it! I’ll freely admit to not having searched every corner there…)

I’ve been watching and reading quite a bit on BDD and the cucumber framework for testing applications, so I thought it was time to try it out. Of course, being more of a python geek than a ruby geek, I’d heard about Lettuce, which is either a straight up port, or incredibly headily inspired by Cucumber.

Getting started with it was incredibly easy. Everything we’re doing is working from a virtualenv (which I highly recommend for development!), so I just added lettuce to the pip-requires list and it was pretty much ready to go.

In setting up lettuce, I probably spent as much time knocking together a quick “functional_tests.py” script as anything – making it responsible for the sequence of testing. The whole point there was to make a single script that could be run, returning an exit code that meant success or failure for the whole set, so it could be plugged into our local instance of Jenkins.

The core of that fabric script is really just simple fabric commands to set up, clean, and push code to a remote node. I ended up adding a script to our local repository to start up services on the far-end for functional testing – testsetup.sh – that runs the various pieces under “screen” – which makes it super easy to see what’s happened when something goes awry.

You’ll notice at the very end of that functional test script, I invoke “lettuce” on the local machine. That takes care of running the actual test sequences. The documentation for lettuce is pretty reasonable, so I recommend walking through that tutorial for a quick understanding. The super-basic gists is that lettuce uses a DSL that you basically create as you go along, and ends up being rather highly customized to your testing setup. You put together files in a “features” directory, and they use “steps.py” in that same directory to do what’s needed. The pattern that I’ve been using (and which seemed to be implied) was to use the “world” object in lettuce as a sort of black-board to get and store data as you walk through the steps in lettuce. There’s deeper integration into Django based projects (my example was using a little Flask based application run with gunicorn).

The key to setting up the functional testing was taking advantage of the file “terrain.py“, which lettuce uses to do global setup, and setup/teardown around steps, scenarios, features, or the whole shebang. Turns out I had several options for how to reach out and walk through the remote application, so I chose to use twill, although I could clearly have used the local test_client() with Flask, or even the web_driver setup from Selenium to drive Firefox.

One of the nicer things that I found while walking through setting this up was that I could write up a feature file and run lettuce, and it gave me really pleasant “this isn’t implemented yet” output that I could use to expand steps.py. For example, I created “example.feature” in the features directory:

and then ran “lettuce” and got the following output:

As you can see, it’s basically giving you the code to add to steps.py to make this work. As I went, I found myself refactoring steps.py to use some of lettuce more advanced mechanisms – regular expressions and grouping steps together in sequences. And to make sure I don’t leave you completely in the dark about setting up and using steps.py, here’s a snippet from my growing file.

Benchmarking Celery

Before you even go there, I’ll preface this with YMMV.

This little post is to document a benchmark that I did for an internal use case, in the hopes that it’ll be helpful for others. As a benchmark, I wasn’t attempting to fully characterize the performance of a specific system – I just wanted a pole against which to measure changes in the environment or underlying infrastructure. I was curious what the performance was of Celery, using RabbitMQ. The tests I ran were pretty much straight sample code of the project (a simple “add” task) and a client making multiple requests and combining the results with the veritable python “timeit“.

The code

All the code for this test (and more, I got excited…) is stashed up on Github: https://github.com/heckj/openstack-benchmarks/tree/CeleryBenchmark. Really, the parts you’re likely to be interested in is the worker class: tasks.py, the configuration: celeryconfig.py, and the actual benchmarking code: celery-benchmark.py.

And before you ask, no – the OpenStack project doesn’t currently use Celery – in fact they use Carrot right now. I’m just intending to add on more benchmarks and profile tools into this codebase around the OpenStack project in the future.

The config

The configuration was held constant – a stock Ubuntu 10.10 server with all the various dependencies installed. Since I’m sure someone will want to know about the versions:

  • rabbitmq-server 1.8.0-1ubuntu2
  • python2.6 2.6.6-5ubuntu1
  • python-amqplib 0.6.1-1
  • celery 2.2.7
  • kombu 1.1.6
  • anyjson 0.3.1

The host was a Shuttle PC, 8GB ram, Core 2 Duo processors. The host was never heavily burdened by the processing that took place (load < 1.0, no significant swaping). The benchmarking was done on the same host as RabbitMQ to remove any network latency effects.

The results

.

I was totally abusing MS Excel’s “stock graph” to show variability in the results (of which there wasn’t a hell of a lot). In the graph, the thin line represents the range (min to max) and the thicker box in the middle is standard deviation +/- the average result. The gist – the round trip time was pretty much straight up at 160ms per requests, and that sampled over 1,000,000 requests. The image above shows a portion of the sequence. The relevant code:

from benchmark.celerybench.tasks import add

result = add.apply_async(args=[4, 4]_
result.get()

(As I mentioned earlier, you can see the whole code on github).

I did more tests, but I need to keep some of those to myself, as they’re testing variations of configurations for my job.

Random side notes

I hadn’t done anything in depth with Celery before. I’d heard about it from friends, and in the community in general. The author pinged me a couple of times with help as well. Overall, I found the Celery setup to be incredibly easy to use and a very straightforward API (always nice). There were lots of options available, but everything was set with very usable defaults from the start. I’m totally looking forward to using Celery in some projects, as well as taking advantage of Kombu – a drop-in/compatibility layer for Carrot.

Update:

Ask mentioned some suggestions for optimizing in twitter – seemed a good place to put them. Try:

  • CELERYD_PREFETCH_MULTIPLIER=0
  • CELERY_DISABLE_RATE_LIMITS=True
  • and BROKER_TRANSPORT=”librabbitmq” to use the pylibrabbitmq C library

jquerymobile and having design constraints

I’ve been working on this idea/project called Eyes for the past year on and off. Maybe for the past 4 to 6 months I’ve been stymied by what I want the visual representation to look like, struggling with the options of an open HTML design canvas. I’m afraid the sheer potential of anything there left me struggling – there were too many ideas of what I could do for a visual presentation and interaction, and I wasn’t able to really narrow it down all that well.

I’ve been following SproutCore for a while, sort of thinking about that as an interesting mechanism, and then more recently I saw the announcements about the jQueryMobile framework setup. Having done some iPhone and iPad development, the common metaphors of list views, tableviews, etc. felt very familiar. jQueryMobile isn’t all that to be perfectly honest, but the basic design feel is reasonably close.

I made a branch on Eyes and started laying it out – and I’ve been going gangbusters since. Laying in the constraints of the framework has really made the choices much easier to work out. Not that I haven’t run down some dead ends and had to back out, but I feel like I have better sense of how the pages flow and work together.

And best of all, I have something that I’m comfortable will work on mobile devices, while not looking like crap on a larger view.

I’m still learning the various tidbits of the framework CSS stylings, and I’m already seeing some elements where I’m going to want to dig deeper. The only real struggle I’ve had is working with Ajax based forms submissions and debugging them when I bork it up. Doing so much javascript work and debugging is still pretty unfamiliar to me. I’m ending up with a lot of print(“..”) debugging on the back end, and alert(…) debugging in the javascript itself.

All in all, I’m very pleased with the effects and results of using jQueryMobile. I do rather wish I hadn’t left my jQuery book at work for the holiday weekend though – I’m certainly not a jQuery expect, and it would have come in very handy more than once already. Thank god for excellent online documentation.

Django 1.1 Testing and Debugging

I borrowed a copy of Django 1.1 Testing and Debugging from a friend today. Spent the bus ride home from the office flipping through the pages, and I’ve got to say – it’s a pretty darned good book!

If you’re new or newish to Django development, it’s a book that I think would be good to have in your stable. Even with Django 1.2 now released, everything in the book is super relevant, and Karen Tracey has done a really wonderful job of explaining and then showing with details the soup to nuts run of how to do and deal with testing a django application … and more importantly how to debug when things go awry.

The book covers unit tests, doctests, testing through the WSGI interface with the Django unit test extensions, and even driving a website test set with twill. It’s thorough and chock full of examples and walk through goodness.

The debugging is even more detailed – going to a lot of trouble to explain tracebacks, the format of the Django error pages, how to get convenient debug data on your django project (using Django Debug Toolbar), and finally – how to even use the python debugger to step through execution. She goes to a lot of trouble to set up real-world scenarios that are slightly and subtly broken and then walk through the whole process of solving the issue with the tools at hand.

I’ll be keeping John’s copy for another day or two, and then getting my own copy to stack into the reference shelf.

Ubuntu 10.04 (Desktop)

I’ve been using Ubuntu as my distribution of choice for VM’s and server instances, and on a lark I took a swag at installing Ubuntu desktop onto a VM yesterday. I’ve got to say, it’s a pretty usable setup.

I still completely prefer the Mac, but the installation was relatively painless, the browser setup pretty good – and installing all the tidbits that I wanted to fiddle with for development was very easy.

I don’t even really know what I’ll use it for – other than something to experiment with and try out. I don’t really need another VM with a desktop interface, but I thought it would be interesting to see where it’d gone.

I recall Mark Shuttleworth (for whom I’ve a great deal of respect) making a comment earlier this year about “this is when Linux takes the desktop”. He might be right no. I recall at the time thinking, “Dude – Apple’s doing this iPad thing and you’ve better change your sights!”. Well, based on what I see in his blog with the “Unity” interface, they’re taking a pretty interesting stab at it. One of the things that I think Apple really has going for it in the tablet space is the multi-touch programming interfaces. They cooked them for several years with the iPhone, and now they’re solid and beautiful to work from a programmer’s and designer’s point of view. I don’t know what Ubuntu or any of the linux distros are doing with the interface space there, but I hope they’re paying close attention to the programming paradigms – that’s what is making the platform so damn powerful.

Now that I spent an afternoon installing it, I think I’ll probably nuke it and get back that 20GB of space, but it was fun to play with…

The darker side of Pinax

I really like the concept of Pinax, but I’m beginning to see the darker sides of the project. Here’s the fundamental issue:

Pinax does a completely kick ass job of making a combined and base project that pulls together a lot of pretty darn good re-usable django “applications” into a single project. What it doesn’t do well is manage any of the dependencies in that tree, or make it easy to use only a portion of some app. If you want to use Pinax the way Pinax is already developed, you’re rockin’. If not, you’re re-working quite a bit of code. And the worst part is that code is almost all opaque to you and hidden in the pinax framework.

The application I wanted to pull in to my basic “pinax” project was “photos” – some simple photo uploading. Yeah, cool – uses photologue under the covers. What’s not clear is that photos also has dependencies on grouping and tagging, and if you review the dependencies documentation, it looks like there’s circular dependencies embedded in there.

What I ended up doing was to take the “photos” application from the Pinax project directly, fork that, and drop it into my project. Then I had to do a shit-load of renaming and stripping because “photos” is built in to Pinax as a default – so “photos” in my app became “photo” and I was scrambling through code to remove the bindings into commenting, threaded commenting, grouping, and so forth.

I did get it working, and really all told I spent less time stripping out stuff than I would have putting it together from scratch. But the only reason I was able to do it that efficiently is because I’ve already been through the pinax project’s source, had it on my laptop, and was a fairly comfortable and competent Django programmer. Any newcomer hitting this would have been toast, and badly confused.

When I asked around the Seattle Django user’s group related to Pinax, several of them said they’d been shying away from something like Pinax because it was easier for them to simply including the good open-source django apps into their work already. At the time, I thought “Well, maybe that just makes Pinax easier and more effective for newbies into Django.” Now I’m reconsidering.

I don’t have a good answer to the problem, and I’m sure I’ll continue to use Pinax and maybe even dig deeper and see what can be done to resolve this kind of issue. I think the idea of the Pinax project is fantastic, I just wish it was a little less “tightly coupled” under the covers and provided more transparency into it’s depths.

Pinax cheat sheets

I have a few friends that I’m bringing up to speed pretty quickly on Django. The basics are going well, and I’m providing the foundations for the effort. To take advantage of all the good stuff out there, I’ve started diving deeply into Pinax, and then wrapping some automation around it with Fabric to make it really easy to work on new apps and projects.

That’s the whole reason I posted gist 284927 yesterday on setting up a remote app server for a pinax project with Fabric.

The biggest hurdle that I have with the fellows I’m bringing up to speed is them understanding what’s IN the project that I’ve already slapped down. Even a basic pinax project has a huge amount of complexity for the newer django developer – it’s pretty overwhelming. To try and mitigate that complexity, I’ve started a side project making Pinax cheat sheets. (http://github.com/heckj/pinax_cheat_sheets).

This is not intended to replace Pinax documentation, and in fact I hope that I can eventually tweak these around and put them into the pinax project. I have a huge respect for it (and I use it), so here’s a little bit of detail for contributing back.

I am very happy to take on any changes, edits, updates, etc – from others. There’s a lot of folks who’ve worked very hard to build all these components, and I’m not writing from the perspective of the creator, but of the “code spelunker”. I’m sure I’ll get some of this stuff wrong – so if you see something, please let me know.

I’d ideally love to receive contributions in the form of pull requests from GitHub. Just fork that project, make your edits, and when you’ve pushed them back up – send me a pull request. I don’t promise that I’ll include everyone’s contributions, but to be honest I don’t expect to be too darn picky.

I’ve written the cheat sheets in markdown, mostly because I know it, and secondarily because it renders nicely as HTML when viewed through GitHub.

The start of the project has the following cheat sheets up:

I have a bunch more external apps to go before I hit the internal Pinax apps. I’m working through everything that’s included in a Pinax “basic_project”.

And then the internal apps:

  • basic_profiles
  • account
  • signup_codes
  • about
  • django.contrib.admin

Using fabric to deploy a Pinax project

I spent the better part of this morning screwing around with Fabric to get even a basic deployment working correctly with Pinax. I may be doing this horrifically backwards… Since I finally nailed something that worked for me and I couldn’t find much out there on the web, I wanted to post up a result so that other folks could use/riff etc.

http://gist.github.com/284927

Please feel free to replicate/clone/use/etc whatever to your heart’s content. It’s built around deploying a Pinax 0.71 project clone that also uses South for schema migrations, and the project is housed in BitBucket.

The other fabric file I found that’s referenced frequently was a part of the inspiration here: http://gist.github.com/212366. It’s a fabfile that’s intended to provide some simple rollback and expects to be used from GitHub – and has some really nice documentation associated with it. Maybe I’ll work on mine to add some of that doc… but mostly I’m just making it available as is.

integrated project management for development

Ironically, the choices for an in-house integrated project management toolchain are, to my mind, significantly more limited than the straight up open-source market. I have been looking and watching several projects over the past months for something that I could use for my development team at work (i.e. behind a corporate firewall and not publicly available) to support a more open, transparent view of what was happening.

Trac, of course, is one I’ve used and really enjoy. Trac, however, doesn’t really support multiple projects in any integrated way – and we’ve got way more than one project. From the activity I’ve seen, it’s not about to any time soon. Variations on that theme include DrProject, and more recently Basie. They’re all interesting, but I didn’t see either DrProject or Basie as really ready for prime time and I wanted to be able to quickly grow beyond the basics. Two others that are obviously available are Redmine and Retrospectiva.

Ultimately, I’m heading down the road with Redmine for the following reasons:

  1. It’s a decent and clean user interface that has several years of polish now around it
  2. The system support plugins, and there’s several plugins that I really want to take advantage of
  3. Redmine and Trac appear to have the most active communities around them and driving them

The story cards and burn-down charts from Retrospectiva’s AgilePM addition were darned compelling. But ultimately it has a more limited set of folks focusing on that project, and I think I can achieve the same effects with plugins that are available from the Redmine community. Many of these are hosted on GitHub, and even more are in development or some middlin’ shape at the same site. And finally, I’d much rather deal with a partially implemented plugin than a partially implemented core system.

If I could host our development outside of the corporate firewall, I’d likely be looking at Bitbucket or Firefly for the work. I like Bitbucket partially because it’s all mercurial based, and I need to support some Microsoft based development. Git will work with enough effort, but I don’t want to go down the road of trying to explain all the detail needed there. I love the functionality in GitHub, and frankly think it’s a slightly better and more aggressively updated solution that BitBucket, but the git thing – while I’m happy enough with it – just sinks me otherwise because I know I’ll end up spending hours attempting to support it on a windows environment, and I just don’t want that hit. Firefly is ActiveState’s “let’s take and commercialize Trac by hosting it” – and they look like they’ve done a nice job of it. The agile methodology plugins and burn-down charts are pretty darn compelling.

It should be noted that I also took a pretty deep look at Launchpad. Even though it’s open sourced, it’s a damned complex thing to potentially integrate and build up for internal use, and its integration/collaboration features just haven’t been as compelling to me as the machinery that GitHub or Bitbucket provide. The “branch and request a pull” feature set that supports the massive branching and merging for features, bugfixes, etc. is just so much easier in Github or Bitbucket – and the wiki support to the other components is also far superior.

If you’re looking for something yourself, definitely keep an eye on the market and projects though. RIght now it’s just December 2009, and it’s clear there is a lot of effort, momentum, and a ton of good ideas that people are just begging to implement in this space. If I go to make this same decision in 6 months, there’s no guarantee that the landscape won’t have changed dramatically and a different solution would be better.

South – incredible easy migrations for Django

I’ve been hacking away at a side project for the past three or four weeks – got myself to internal milestone #2 this weekend, for which I’m really pleased. The very tail end of this milestone was deploying the code somewhere and vetting that all the basic, mostly-crappy-still bits actually worked.

Since I’ve got it deployed now onto a little dev server, I was thinking about how I was going to make this work going forward. Database migrations being one of those “how do you upgrade things?” questions when you’re doing rapid development django applications where the database model can get twiddled a bit.

The result of scanning around this afternoon from my favorite coffee shop haunt led me to South. In about 10 minutes I’d enabled and moved to south and had my application up and rolling with it. My previous experience was with Django Evolution – which wasn’t bad, but it was more work to get it into place and running.

The migrations in place, I did some model twiddling and experimented a bit to see how it all worked. I can see how if you’re not being somewhat careful, you could get into some really horrible places that no program could figure out. But basic migrations – moving forward and backward – really do an excellent job of “just working” with this framework out of the box.

The one interesting quirk I ran into – I’ve been doing tests on my codebase with:

<a href="http://nedbatchelder.com/code/coverage/">coverage</a> manage.py test

which just caught and ran the tests for everything in the application list. Figured it didn’t hurt to test the admin and auth stuff as well. When I added south, which I installed using:

 <a href="http://pypi.python.org/pypi/pip">pip</a> install south

The directory that south’s tests expect to use suddenly becomes a bit less accessible on the build server. Not a bad thing to redirect the tests to just what I’m writing, but an interesting side effect.