Set up Askbot project in Codeship

codeship

Update:

Askbot just upgraded their Django-avatar version so we don’t have to compile PIL anymore.

Codeship is a great tool for private continuous integration system. But setting up a project that uses Askbot can be a bit troublesome, since we have to compile PIL to support avatar module in offerQA. Mainly because it is not possible to symblink /usr/include/freetype2 to /usr/include/freetype. But later I realized that pip also searches in ~/.virtualenv/include folder so things became much easier. A local_setting file is also created specifically for Codeship database and Redis. Here is my setup commands:

pip install -r requirements-dev.txt
pip install redis
# Use settings for CI
ln -s local_settings.ci local_settings.py
# Sync your DB for django projects
python manage.py syncdb --noinput
# Run migrations for your django project
python manage.py migrate --noinput

And here is my test commands:

# Running your Django tests
python manage.py test

The local_settings.ci file:

# -*- coding: utf-8 -*-
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': 'default.db',
        'USER': '',
        'PASSWORD': '',
        'HOST': '',
        'PORT': ''
    }
}
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'offerqa',
        'CACHE_TIMEOUT' : 60,
        'KEY_PREFIX': 'askbot',
    }
}

No Django log printout in Gunicorn

I found a weird problem when I tried to deploy a new project with Gunicorn this weekend. It seems Gunicorn has swallowed all Django printouts. No matter how I set up the project: change the logging settings in Django, add debug flag and set log level, I couldn’t get anything to show up.

After a couple of hours of trying and googling (!!!) I found an interesting comment in Stackoverflow, it seems Gunicorn has changed the default logging to not to print on the console in R19, but it is reverted back in R20. But if you are using R19, you can get Gunicorn to write log to console again by adding:

--log-file=-

flag to the command.

Tips for mocking in Python

Restore patching

I like mocking and patching in unittest. And you shouldn’t forget to restore all the patchings also. I would think it should be put in the TearDown() method in a unittest. But it seems that I was wrong.

From the official document:

…This method will only be called if the setUp() succeeds, regardless of the outcome of the test method…

So if there is an exception in setUp(), the patchings will not be restored. The correct way of doing it should be using the addCleanup() method.

…If setUp() fails, meaning that tearDown() is not called, then any cleanup functions added will still be called.

And example if you use patch() as function.

class MyTest(TestCase):
  def setUp(self):
    patcher = patch('package.module.Class')
    self.MockClass = patcher.start()
    self.addCleanup(patcher.stop)

Mock the base class

I am not sure if you should do that since I haven’t found too many articles on the internet. But I will put it here anyway. The base classes are defined in a class’s __bases__ attribute, but when I tried to patch it like other attribute using:

@mock.patch.object(ExtendedClass, '__bases__', (MockBaseClass,))

I got a TypeError:

TypeError: can't delete ExtendedClass.__bases__

Looks like mock module is trying to remove it before reassign it. I had struggled for a few hours before I found out another simple way to do it:

ExtendedClass.__bases__ = (MockBaseClass,)

The only drawback is that you will have to restore the base class manually afterwards.

Setup a remote development environment with Vagrant, Salt and Digitalocean

For years I have been doing web development on a lenovo S10 netbook via SSH. I like to be able to connect to it from anywhere in the world and resume my work by typing: tmux -2u attach. But it also has some issues:

  1. sometimes the connection is very slow in other countries because I have to SSH to my home router in Sweden.
  2. the laptop is getting older and the fan makes lots of noise.
  3. I cannot do system snapshot like a virtual machine.
  4. I cannot suspend/resume the system remotely like a virtual machine.

Since I have been using Vagrant and Salt for my web service, I figured I could setup a remote development environment using Salt. All of my repositories are at Github and Bitbucket anyway. As for the VPS,  I chose DigitalOcean because of their API, price and speed:) Here is the github repository for my vagrant and salt files: https://github.com/zheli/dev-environment