0 Results
exploring redis in node.js using the mocha testing framework
overview
node.js
Node is currently the cool kid of the web dev scene and is starting to take over. Node is the project that lets you run javascript on the server side in a super fast v8 based vm. Out of the gate, it is evented/async, non blocking and ridiculously fast. Javascript has a lot of haters, but it is undeniably an interesting and powerful language. The node community is thriving and mature. The tools are awesome and it is a blast to use.redis
redis is amazing. It is one of the stars of the nosql movement. It is a server that stores strings, lists, sets and hashes. If that isn't even it also lets you do publisher/subscriber to trigger events. It is a natural fit for node and if you try it, you'll like it.mocha
Mocha is the latest generation of node/js test frameworks by TJ Holowaychuk. It is fast and allows for incredibly easy asynchronous testing. It supports standard assertions as well as bdd style tests using should.setup node and mocha
This gist uses homebrew to install node. OSX has great support for node and homebrew is by far the best package manager. npm is among other things the command to install node packages. We're using the -g flag to npm to install the package globally, otherwise it would be installed for just this project. [gist id=1491206 file=setup.sh] Now, if you type "mocha" at the command line, it will execute the non existent tests in our test directory and return the results. Since we have no tests, it should look something like this:Async testing with mocha and should
The following gist is a basic asynchronous test using mocha and the should bdd style assertion library. Async tests can be challenging because you are testing things that happen at various times. We are going to set a key and make sure the callback function gets called without an error. Generally that is hard, but mocha gives us a sweet little callback called done that we can pass to our redis set command. It ensures that the callback happens successfully and no errors are passed. If you've done async testing in the pass, you will probably be amazed at how painless it is to do it like this. In the second test we are going to retrieve the key we just set and explicitly test the value in the callback. To make sure the async happens as we expect, we manually call done() after our assertions. [gist id=1491206 file=test/test_redis.js] If we didn't call done, the test would hang until it times out. When called correctly we should get a result like this. As you can see, 3 milliseconds is not bad for a couple of async tests. It definitely beats setting a clock and waiting for it to run out! Just remember to say "no" to coffee script.deploying a django app to heroku with easy static files on s3
django and s3
This project doesn't necessarily require heroku, but I've been interested in the service as an easy way to deploy apps. I really like the idea of not having to set up a server with nginx, postgres, gunicorn, etc. The convenience of deploying just by pushing from git is awesome. One issue I ran into was a problem with serving static content like css, javascript and image files from heroku. I'm sure it is just a configuration problem, but this solution of using s3 to serve those files is the way you want to go in the long run. You can clone my sample project from github.git clone git@github.com:eknuth/django-heroku-s3-bootstrap-demo.git
Django on Heroku
Heroku used to be limited to ruby apps, but it has recently become much more flexible with the addition of the cedar stack. Now it supports python 2.7 and uses pip to install modules from a standard requirements.txt file. They have also started offering a free 5mb postgresql db to go along with their current freemium offering, which is fantastic. That doesn't sound like a lot of space, but you'd be surprised how much information you can cram into 5 mb.Initial Setup
You can follow the django instructions from heroku here: http://devcenter.heroku.com/articles/django If you are using macosx, or virtualenv uses python 2.6 by default, I would suggest specifying 2.7 when you create the environment. Heroku is using 2.7 and will complain about pip installing importlib which was not included by default in python 2.6.virtualenv --no-site-packages . -p /usr/local/bin/python2.7
Open the site on heroku using the "heroku open" command and verify that you get the django welcome screen. You should have no urls configured.
Admin and Static Files
You should now have a working empty project. Let's turn on the django admin app and fire up the development server. As a side note, this config will import settings from settings_local.py, if it exists and overwrite the ones in settings.py. This local settings file is not committed to the repo and won't get deployed to heroku. Follow the instructions to install the django admin app and then run manage.py syncdb and then runserver. If everything went ok, you should be able to log in to your admin console. Now, commit and push your app to heroku. Run the manage.py commands on heroku and magically your admin console is live on the web.Twitter Bootstrap and view
Now, lets getting started with a template and a home view. We can use the totally awesome twitter bootstrap project. They have released a site/webapp html template, css and javascript package that provides everything you need to get started. It is great for those that are less inclined to design. Create a templates folder in your project root. Clone the project from github and copy hero.html from the examples directory into your new templates directory.@render_to
Now let's create a view and wire up that template to a url. Now is the time to add on a django project that will make things easier for us. I really love the render_to decorator from django-annoying. Run "pip install django-annoying", and it will be ready to go. Don't forget to save your updated requirements with a "pip freeze >requirements.txt".relative paths
Add the template dir and a little snippet of python to use relative paths. This will make life easier in the future. In the urls.py file, uncomment the following home view: url(r'^$', 'om.views.home', name='home'), And create a views.py file to grab the template and render it. Now when you open the app on your development server, you get an actual "hello world" page. Unfortunately we are missing the css file, so it is unstyled. In your root project, create a static folder and inside that create another folder named css. Copy bootstrap.css into static/css. To reference this css file, edit hero.html and change the line with bootstrap.css to this:
<link href="css/bootstrap.css" rel="stylesheet">
In order to make the STATIC_URL template tag work, we need to update STATICFILES_DIRS in settings.py to:
STATICFILES_DIRS = ( os.path.join(SITE_ROOT, 'static'),)
We also need add some template context processors with this:
TEMPLATE_CONTEXT_PROCESSORS = (
'django.contrib.messages.context_processors.messages',
'django.contrib.auth.context_processors.auth',
'django.core.context_processors.static',
)
When we open the page served from our development server, we are good to go. The page is styled and looks awesome.
Static Files on Heroku
Unfortunately when we push to heroku and open the page, we are back to the our css free look. Seems like heroku has no problem serving up the admin static files, but it has a problem finding our static directory. I'm sure it is just a matter of configuration, but honestly we really don't want to use our application server to serve up static files anyway. Images, css and javascript should all be coming out of something fast and light.Enter S3
Amazon provides an excellent service for doing just that. Amazon's web services and the simple storage system are cheap and easy to use. There is also an excellent module for using s3 with django's static files app and the collectstatic management command with s3 as a backend. django-storages makes it incredibly simple to use s3 for our static files.django-storages and boto
First we want to install the module with "pip install django-storages" and add 'storages' to your INSTALLED_APPS tuple and set your storage type with:
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
We will also need to install boto, the python module for dealing with s3. Use "pip install boto" for that.
Log in to the amazon web services management console and create a new bucket. Add the name of the bucket and your access keys to settings.py like this:
AWS_ACCESS_KEY_ID = 'ACCESS KEY'
AWS_SECRET_ACCESS_KEY = 'SECRET'
AWS_STORAGE_BUCKET_NAME = 'django-blog
set up the s3 bucket
Look at the bucket properties and grab the url for the bucket. Update your STATIC_URL setting to point to the bucket. In this case it will look like this:
STATIC_URL = 'https://s3.amazonaws.com/django-blog/'