Posts tagged with “VIRTUALENV

07. 08. 2011

Jenkins, Django, virtualenv, hg

Nedávno jsem rozcházel testovací stroj pro Django projekty postavenej na Jenkinsu a jelikož informace o tomhle setupu jsou tak nějak polovičatý a navíc porozházený po internetech, rozhod’ jsem se to malinko rozepsat. Jenkins můžete s minimálním úsilím zaměnit za Hudson a Mercurial za git, Bazaar, SVN či kýhošlaka. Debian samozřejmě taky nehraje zásadní roli.

Nejdřív rozjedeme Jenkins:

echo 'deb http://pkg.jenkins-ci.org/debian binary/' >> /etc/apt/sources.list
aptitude update; aptitude install jenkins

Pokud je vše v pořádku, doinstalujeme pár pluginů. Takže nakopnout browser na http://localhost:8080/pluginManager/available a zaškrtnout:

  • Mercurial Plugin (překvapivě na Mercurial),
  • Hudson Setenv Plugin (podpora ENV proměnnejch při buildu),
  • Cobertura Plugin (coverage reporty),
  • Violations (hlášení o prasení kódu z pylint a spol.),
  • ChuckNorris Plugin (ehm) a
  • Green Balls (ano, taky vám přijde zelená kulička po úspěšným buildu lepší než modrá?)

Až dorestartujete (jo, je to v Jáááááááááávěěěěěěěěěě), šup nastavit Mercurial na http://localhost:8080/configure.

Cesty se samozřejmě můžou lišit, čili Executable zjistíte pomocí which hg a Installation directory vypreparujete z dpkg -L mercurial. To je co se týče Jenkinsu samotnýho všechno a tak jady vytvořit novej (Build a free-style software project) projekt http://localhost:8080/view/All/newJob.

Obrázek je za sto slov, takže jen telegraficky. V sekci SCM nastavit cestu k repozitáři projektu, Jenkins tak díky Poll SCM (Build trigger), bude vědět, že do větve někdo pushnul novou revizi a spustí build. Schedule si nastavte dle potřeb, syntax je ne-nepodobnej crontabu, samozřejmě se nemusíme bát použít nápovědu. Jakmile, se Jenkins dozví, že přibyla nová revize, sám si ji potáhne. (Občas se mu to ale nepovede, v takovým případě nezbejvá nic jinýho než wipenout celej workspace)

V Build Environment de fakto aktivujeme virtualenv v adresáři .env (viz níže) a volitelně do PHYTONPATH přihodíme další potřebný knihovny (tady 3rdparty pro modifikované knihovny třetích stran a ourawesomelibs kde jsou naše skvělý knihovny sdílený napříč projekty).

V sekci Build se děje většina tohole celýho mažiku. Myslím, že tady nemusím recitovat slovo od slovo, co ten skript dělá, ale kdyby to byl někdo chabrus na bash, tak pro jistotu: Zjistíme, jestli už máme vytvořený virtualenv a případně ho vytvoříme. Pak si naklonujeme nebo updateneme knihovny zmíněný výše. Nakonec použijeme pipinku na doinstalovaní knihoven, který náš projekt potřebuje. Preferuju dva soubory — jeden s knihovnama potřebnýma pro projekt a další, kde jsou knihovny potřebný pro otestování, lint, coverage a napojení na Jenkins (requirements_test). Po sestavení (updatnutí) envu se spustí samotný testy.

Po buildu si necháme ještě pěkně vymalovat code coverage (Cobertura), prohřešky naprásknutý pylintem (Violations) a hlavně taky výsledky testů (JUnit test result report). Všechno předatlovat z obrázku výše.

A to mám jako všechno přepisovat, jo? No, moc toho na psani neni, ale OK:

ENVs:

PATH=${WORKSPACE}/.env/bin:$PATH
PYTHONPATH=${WORKSPACE}/.env/LIBS/3rdparty:${WORKSPACE}/.env/LIBS/ourawesomelibs:$PYTHONPATH

Bash:

if [ -d ".env" ]; then
     echo "**> Virtualenv already exists"
else
     echo "**> Creating virtualenv"
     virtualenv .env
fi

echo "**> UPDATING LIBS"
for lib in "3rdparty" "ourawesomelibs"; do
    if [ ! -e "$WORKSPACE/.env/LIBS/" ]; then
       mkdir "$WORKSPACE/.env/LIBS/"
    fi

   cd "$WORKSPACE/.env/LIBS/"

   if [ -e "$WORKSPACE/.env/LIBS/$lib" ]; then
       cd "$WORKSPACE/.env/LIBS/$lib"
       hg pul
       hg up
    else
       hg clone ssh://chrootuser@repo.myawesomcompany.cz/home/chrootuser/repos/LIBS/$lib
    fi
done

cd "$WORKSPACE"
pip install -r requirements.pip
pip install -r requirements_test.pip
python manage.py jenkins --settings=settings.test

Počkej, počkej! A co máš teda v těch requirements_test a jak vypadá ten Django setting pro test?

Mimo obvyklejch nastavení je tady pár věcí, který je třeba nastavit kvůlivá Jenkinsu. Podotýkám, že tohle je setting importující z nějakýho base nastavení a přepisuje jen pár nastavení:

TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
#PROJECT_APPS = (,) #if defined, only defined tests will be started

#excluded apps
TEST_EXCLUDES = (    
   #django itself
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.sites',
    'django.contrib.admin',
    'django.contrib.sitemaps',
   #3rd party
    'django_extensions',
   #test stuff
    'django_nose', 'django_jenkins', 'south',
)

SOUTH_TESTS_MIGRATE = False

INSTALLED_APPS += ('django_nose', 'django_jenkins','south')

Díky TEST_EXCLUDES můžeme vyřadit některý appky, nebo konkrétní testy. Nemusíme tedy zbytečně čekat na testy origoš Django appek apod. Do INSTALLED_APPS přihodíme věci potřebný pro testování, který by nám na produkci nebo někde jinde zbytečně strašily. Pokud by nám na prázdný testovací db z nějakýho důvodu haprovaly migrace, mužeme použít SOUTH_TEST_MIGRATE.

Co se týče knihoven, requirements_test říká:

south
coverage
nose
pylint
git+git://github.com/starenka/django-jenkins.git#egg=django_jenkins
#django_jenkins

Pokud nechceš/nepotřebuješ používat EXCLUDED_TESTS, bude lepší použít originál django_jenkins. Ten (můj) fork na GitHubu má právě tuhle fičuru backportlou z django_hudson, ale negarantuju, že to budu udržovat. Ostatní je jasny, coverage na generování coverage statistik, nose jako runner a pylint na statistiky Violations.

No a to je asi víceméně všechno. Ano, dalo se toho napsat rozhodně míň. Na druhou stranu se toho dalo napsat taky o dost víc. Doufám, že i tohle někomu aspoň trochu pomůže. Kdyby nastaly nějaký komplikace, nebojte se ozvat v komentářích.

no comments yet