Jenkins/fr

From Lazarus wiki
Jump to navigationJump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

English (en) français (fr)

Généralités

Jenkins est un serveur d'intégration continue qui peut être utilisé pour construire automatiquement et tester des projets basé sur des commits vers votre gestionnaire de version.

Cet article décrit comment installer/régler Jenkins pour construire automatiquement FPC quand un commit survient dans SVN. Vous pouvez bien sûr adapter des instructions à vos propres projets.

Réglage de Jenkins

Une version possible à utiliser est Turnkey Linux Jenkins sur Debian 6.0.5 (Squeeze) ; cette article est testé avec Jenkins 1.464.

De quelques façon que vous installiez Jenkins, assurez-vous que le plugin SVN est activé.

Réglage du compilateur de ressource

Au moins les paquets Debian FPC n'installent pas un compilateur de ressource, qui est demandé dans la section ci-dessous.

# Get resource compiler, not provided by fpc 2.6 packages:
apt-get install mingw32-binutils
# symlink:
ln -s /usr/bin/i586-mingw32msvc-windres /usr/bin/windres

Réglage du pilote de base de données

Pour tester les connections de base de données/l'écriture des résultats dans les base de données, assurez-vous que les pilotes de base de données du système d'exploitation/pilotes de connexion pertinents sont installés, p.ex. :

apt-get install libfbembed2.5 firebird2.5-super firebird2.5-dev \
postgresql-client libpq-dev \
freetds-bin freetds-dev \
mysql-client libmysqlclient-dev \
libsqlite3-0 libsqlite3-dev \
unixodbc unixodbc-dev tdsodbc #adjust to taste/distribution
# we install the -dev packages so we get the correct driver names for older FPC versions (e.g. libfbclient.so.2.5 instead of libfbclient). Alternatively: symlink these or specify explicit .so names in any code using databases
#freetds should pull in unixodbc, but we specify it explicitly.
#Strangely, on Debian, we need to explicilty specify tdsodbc to get the actual FreeTDS ODBC driver!?

Réglages des travaux

Utilisez l'écran de travail par lot pour définir la source svn du tronc FPC ou la branche que vous voulez utiliser (p.ex. http://svn.freepascal.org/svn/fpc/trunk).

Définissez 'Use svn update as much as possible'.

La scrutation (polling) toutes les 5 minutes pourrait être un bon réglage. De manière alternative, vous pouvez définir votre propre serveur SVN et écrire un commit hook script pour cela. Cela amènera à cette entrée :

# every 20 minutes
*/20 * * * *

Tâche de fond : la construction normale & problèmes

Light bulb  Remarque: Cette section est incluse pour la complétude ; les problèmes avec le fpc.cfg global au système et le tronc courant FPC (oct. 2012) peut rendre l'utilisation de fpcup plus facile. Voir plus bas pour cela.

Réglage de FPC stable

Installez les binutils + le compilateur de ressource + FPC stable - pour quelques raison, les paquets debian ne tirent pas les dépendances requises :

apt-get install build-essential mingw32-binutils
# now make an easier name for the resource compiler; adjust to your specific version
# you could also adjust -FC<resourcecompilername> in /etc/fpc.cfg
ln -s /usr/bin/i586-mingw32msvc-windres /usr/bin/windres

#fpc would get old FPC 2.4 on this Debian Squeeze=> symptom in Jenkins build log: 
#generic.inc(2505,13) Fatal: Internal error 8
#Fatal: Compilation aborted
#make[7]: *** [system.ppu] Error 1

#get stable compiler (2.6 at time of writing); we're on a 32 bit system:
cd /root
wget http://sourceforge.net/projects/freepascal/files/Linux/2.6.0/deb/fp-compiler-2.6.0_2.6.0-0_i386.deb/download
mv download fp-compiler-2.6.0_2.6.0-0_i386.deb
wget http://sourceforge.net/projects/freepascal/files/Linux/2.6.0/deb/fp-compiler_2.6.0-0_i386.deb/download
mv download fp-compiler_2.6.0-0_i386.deb
wget http://sourceforge.net/projects/freepascal/files/Linux/2.6.0/deb/fp-units-rtl_2.6.0-0_i386.deb/download
mv download fp-units-rtl_2.6.0-0_i386.deb
wget http://sourceforge.net/projects/freepascal/files/Linux/2.6.0/deb/fp-units-rtl-2.6.0_2.6.0-0_i386.deb/download
mv download fp-units-rtl-2.6.0_2.6.0-0_i386.deb
wget http://sourceforge.net/projects/freepascal/files/Linux/2.6.0/deb/fp-units-i386-2.6.0_2.6.0-0_i386.deb/download
mv download fp-units-i386-2.6.0_2.6.0-0_i386.deb
wget http://sourceforge.net/projects/freepascal/files/Linux/2.6.0/deb/fp-units-i386_2.6.0-0_i386.deb/download
mv download fp-units-i386_2.6.0-0_i386.deb
wget http://sourceforge.net/projects/freepascal/files/Linux/2.6.0/deb/fp-utils-2.6.0_2.6.0-0_i386.deb/download
mv download fp-utils-2.6.0_2.6.0-0_i386.deb
wget http://sourceforge.net/projects/freepascal/files/Linux/2.6.0/deb/fp-utils_2.6.0-0_i386.deb/download
mv download fp-utils_2.6.0-0_i386.deb

dpkg -i fp-units-rtl-2.6.0_2.6.0-0_i386.deb
dpkg -i fp-units-rtl_2.6.0-0_i386.deb
dpkg -i fp-compiler-2.6.0_2.6.0-0_i386.deb
dpkg -i fp-utils-2.6.0_2.6.0-0_i386.deb
#no idea what the other .debs are for that we downloaded
#todo: this could be trimmed down a bit, but this seems to work

Commandes de construction de Jenkins

Comme commandes de construction dans Jenkins, vous pourriez utiliser les commandes shell :

make all

et, pour installer dans l'"espace de travail" ou au sommet de l'environnement du répertoire de construction (build directory environment) :

make install PREFIX=$WORKSPACE

Note : l'installation quelque part ailleurs pourrait être une bonne idée, veuillez vous reporter à FAQ de construction.

Make install ne génére pas un does fpc.cfg pour vous ; vous devez le faire vous-mêmes :

$WORKSPACE/bin/fpcmkcfg -o $WORKSPACE/bin/fpc.cfg

Un problème : /etc/fpc.cfg

La version stable que nous compilons en utilisant des paquets fonctionne, mais elle pose un fpc.cfg dans le répertoire /etc. Ce fpc.cfg est ramassé par défaut et il n'y a aucun moyen de le désactiver à moins que vous par exemple n'appeliez un script fpc.sh en tant que votre compilateur au lieu de l'exécutable fpc. Ce script passe les options au compilateur réel ainsi il ignore /etc/fpc.cfg.

Cela donnera des problèmes à l'exécution p.ex. la suite de test du compilateur. Ces problèmes pourront être résolus en :

  • utilisant une variable d'environnement PPC_CONFIG_PATH ou un fpc.cfg dans le répertoire d'accueil, ce qui pourrait marcher.
  • peut-être qu'une solution plus simple est de ne pas installer FPC/les sources de FPC, mais de télécharger un compilateur bootstrap. Ainsi aucun fpc.cfg et pas de problème. Le bonus est que nous le construisons de manière plus proche de la "version officielle" (qui est toujours une installation complète de la précédente version).

Pour contourner cela, vous pouvez utiliser fpcup ; voir la prochaine section.

Un problème : make clean

Le tronc actuel de FPC (octobre 2012) ne nettoie pas tous les fichiers significatifs en exécutant make clean/make distclean.

Solution : obtenir un FPC utilisant fpcup

L'outil fpcup peut télécharger et installer FPC et Lazarus à partir de rien (ne demande pas de compilateur de départ), aussi une solution pourrait être de :

  • placer fpcup dans votre espace de travail
  • modifier les étapes de construction pour appeler fpcup avec --only=fpc --fpcrevision=$SVN_REVISION

Nous aurions pu lancer fpcup pour qu'il télécharge la dernière version de SVN, mais nous perdons l'intégration avec subversion.

Assurez-vous que vous avez un compilateur de ressource (vois la section d'installation du dessus). Téléchargez fpcup (la largeur, 32bit/64bit doit correspondre avec celle de la machine jenkins). Posez p.ex. fpcup_linux_x86 dans votre répertoire /usr/local/bin, ensuite :

chmod ugo+rx /usr/local/bin/fpcpup_linux_x86

(Si utilisation d'un Linux x64, le nommage peut évidemment différer)

* * * A FINIR * * *


Then set your build steps like this. Note: we could have used one big shell script, but the advantage of putting the commands in execute shell commands is that the build will stop on the first error (non-zero exit status) encountered; you'd have to build that error detection into a script.

rm --force $WORKSPACE/fpcup.log #remove any existing logs; use force to not generate error message if log does not exist

Download/install using fpcup. Note it gets the SVN URL and desired revision ID from environment variables set by the Jenkins SVN plugin. Once again, adjust if you don't use x86 Linux.

/usr/local/bin/fpcup_linux_x86 --fpcbootstrapdir=$WORKSPACE/fpcbootstrap --fpcdir=$WORKSPACE --fpcuplinkname= --fpcURL=$SVN_URL --fpcrevision=$SVN_REVISION --keeplocalchanges --lazdir=$WORKSPACE/lazarus --lazlinkname= --logfilename=$WORKSPACE/fpcup.log --noconfirm --primary-config-path=$WORKSPACE/lazarusconfig --only=fpc

Now check the fpc output in another build step. Note that fpcup uses a custom fpc.sh script to avoid problems with systemwide fpc.cfg. Once again, adjust if not on Linux x86.

$WORKSPACE/bin/i386-linux/fpc.sh -iD; $WORKSPACE/bin/i386-linux/fpc.sh -iW #get FPC version output to check if it was built correctly

The last build step runs the "compiler test suite".

cd $WORKSPACE/tests; make all TEST_FPC=$WORKSPACE/bin/i386-linux/fpc.sh #make full doesn't work, can't delete file

You could archive the test suite results using a Jenkins post-build step.

Tests FPCUnit/DBTestframework avec une sortie en base de données

If you want to run the dbtestframework tests and output the results to a separated database server, you can use the testdbwriter programs. This lets you compare runs from various revisions - which are automatically built by Jenkins.

This method of outputting test results to databases can also be used by other projects that use fpcunit tests - you'd have to use the testdbwriter listener and adjust the console runner to include that.

Though this section contains a fair amount of setup, fortunately it is once only; each job will reuse the existing configuration.

You could of course also run the normal dbtestframework code with output to plain text or XML.

Check if mercurial/hg is installed:

hg --help

if not install it, e.g.

apt-get install mercurial

Get the repository version into a fixed directory:

mkdir -p /opt/testdbwriter
cd /opt
hg clone https://bitbucket.org/reiniero/testdbwriter #will create /opt/testdbwriter
cd /opt/testdbwriter
# the following 2 steps are not necessary but show you how you can update with newest changes in the repository if needed:
hg pull #get newest changes from remote repo
hg up #adapt local version to newest changes we just downloaded

Réglage de la base de données

Now the files in this directory can be used to compile the test program with the FPC in each build. We will also need to setup our database connections.

Bases de données testées

First the databases where the tests will run on. Please create an empty database (or at least one that the test user can thrash) on each db server that you want to test, and have a username and password ready.

Then edit database.ini, used by the db test framework tests (see Databases#Running_FPC_database_tests

cd /opt/testdbwriter/dbtests2db
cp database.ini.txt database.ini #copy over template to config file
nano database.ini # or another editor.
# now set up your credentials in each section

Résultats de test de la base de données

Now the database where the results should go to.

Set up a database with the instructions pointed to in the readme.txt file (e.g. use the testdbwriter.sql for Firebird/Interbase databases and testdbwriter_postgresql.sql for PostgreSQL databases).

Now edit the ini file:

cd /opt/testdbwriter/dbtests2db
cp ../testdbwriter.ini.txt testdbwriter.ini #copy over template to config file
nano testdbwriter.ini #or another editor
# now set up your credentials in the right section, and choose your profile/database in the [Database] section

Ajout des tests à votre lot de travail Jenkin

We'll put the dbtests2db.lpr console runner and the db output writer code it needs (testdbwriter.pas) into the directory where the dbtestframework tests live so dbtests2db can pick up those tests. Then we'll compile the test suite, and run it for each database you want to test.

In your Jenkins job configuration, add an Execute shell build step to set up the test environment. Note: we copy forcing overwrites to avoid the script aborting the Jenkins job if the target exists:

cp -f /opt/testdbwriter/testdb* \
/opt/testdbwriter/dbtests2db/database.ini \
/opt/testdbwriter/dbtests2db/dbtests2db.lpr \
-t $WORKSPACE/packages/fcl-db/tests/; \
cd $WORKSPACE/packages/fcl-db/tests; \
$WORKSPACE/bin/i386-linux/fpc.sh $WORKSPACE/packages/fcl-db/tests/dbtests2db.lpr \
#copy & compile db test program using the fpc dbtestframework tests

Then for each database you want to test, add test runs. The names of the database connectors you specify as arguments must match the section names in database.ini, e.g. postgresql, mysql40, mysql41, mysql50, oracle, interbase etc.

Light bulb  Remarque: The dbtests2db program requires that the database connector is the first parameter; we also pick up the subversion revision number from the Jenkins subversion module we use. The examples below show how you can add more information to the test results database.

If you are testing multiple branches/versions of FPC (e.g. 2.6 and trunk) at the same time, you have a problem: the SVN revision number does not apply to branches but to the whole repository.

This means that the code in the FPC fixes26 branch commit 2500 may be older than the code in the FPC trunk branch 2300. Fortunately, there is a solution: we prepend the revision number passed to the executable with a value (e.g. 020701 for FPC 2.7.1, 020600 for FPC 2.6.0). This serves to preserve the relative "newness" of the various branches... and permits running regression queries on the database to show e.g. that FPC trunk has a failing test where 2.6.0 succeeded.

Light bulb  Remarque: Older versions of this instruction proposed using

--svnbranch="trunk"
which can also be done, but then you separate your testsuite hierarchies into different trees in the database. This does not allow running regression queries so easily.

Examples:

cd $WORKSPACE/packages/fcl-db/tests; \
$WORKSPACE/packages/fcl-db/tests/dbtests2db interbase --revisionid=020701$SVN_REVISION --comment="Jenkins trunk interbase"

With MySQL, as usual, the client version you installed on the Jenkins server has to match the version you specify here - in the example version 5.1:

cd $WORKSPACE/packages/fcl-db/tests; \
$WORKSPACE/packages/fcl-db/tests/dbtests2db mysql51 --revisionid=020701$SVN_REVISION --comment="Jenkins trunk mysql51"
cd $WORKSPACE/packages/fcl-db/tests; \
$WORKSPACE/packages/fcl-db/tests/dbtests2db postgresql --revisionid=020701$SVN_REVISION --comment="Jenkins trunk postgresql"
cd $WORKSPACE/packages/fcl-db/tests; \
$WORKSPACE/packages/fcl-db/tests/dbtests2db sqlite --revisionid=020701$SVN_REVISION --comment="Jenkins trunk sqlite"
cd $WORKSPACE/packages/fcl-db/tests; \
$WORKSPACE/packages/fcl-db/tests/dbtests2db bufdataset --revisionid=020701$SVN_REVISION --comment="Jenkins trunk bufdataset"
cd $WORKSPACE/packages/fcl-db/tests; \
$WORKSPACE/packages/fcl-db/tests/dbtests2db dbase4 --revisionid=020701$SVN_REVISION --comment="Jenkins trunk dbase4"

Note: with all this building and testing, your job running time may extend a bit. Please make sure you set the SVN polling interval to a big enough value to avoid building all the time.

If this works, you can see the test results on your database server, analyze regressions, test succcess percentages, etc.

Windows/Linux... construire l'esclave

You can set up other machines apart from the Jenkins server to act as "slaves": they are controlled from Jenkins and used to run jobs.

This can be useful when running a Windows build/test run from a Linux server.

See [1] for details on how to set up Windows build slaves via DCOM (note: there are other ways to set up (Windows) build slaves; please refer to the Jenkins documentation)

Améliorations

Possible enhancements:

  • run make install into a different prefix
  • run Lazarus compile
  • save dbtests2db results to XML, see if Jenkins supports that
  • add installer builders

Dépannage

Echecs de construction

Vos constructions peuvent échouer parce que l'utilisateur Jenkins exécute un shell différent sous un utilisateur différent avec un chemin d'accès différent de celui que vous attendiez.

Découvrez quel utilisateur travaille sous Jenkins

Si vous rencontrez des problèmes avec les scripts/commandes shell dans les travaux ne disposant pas d'autorisations, il est utile de connaître l'utilisateur sous lequel Jenkins s'exécute.

Essayez cette commande (ou bien sûr la documentation) :

ps aux |grep jenkins | grep -v grep | cut -d" " -f1 | uniq #perhaps only works if jenkins is running a job

Sur Debian, il donne l'utilisateur tomcat6.