PIFR 2 configuration on Debian Lenny

As root, execute the following on commandline for a fresh install of Debian 5.0 Lenny. You can copy/paste most right to your terminal except in cases where you might get prompted for input (i.e. apt-get install, mysqladmin, vi, crontab).

Known bug: the php5-suhosin deb module for PHP will cause ~31 failures and ~11 exceptions.
Known bug: all three opcode caching extensions APC, eAccelerator, and xcache have a history of instability with PIFR clients. The alternative workaround to opcode caching is to mount the files directory in tmpfs, which is included as part of this configuration. The execution time difference between opcode cache and tmpfs mounting has been insignificant.

Server configuration

apt-get update
apt-get upgrade
dpkg-reconfigure locales
apt-get --no-install-recommends install build-essential mysql-server-5.0 apache2 apache2-threaded-dev php5 php5-cgi php5-cli php5-gd php5-common php-pear php5-curl php5-mysql cvs curl php5-dev libapache2-mod-php5 gawk patch htop rsync cron wget openssh-blacklist-extra
a2enmod rewrite
a2enmod expires
perl -pi -e 's/(\s+AllowOverride)\s+None$/\1 All/g' /etc/apache2/sites-available/default
perl -pi -e 's/(\s+CustomLog \/var\/log\/apache2\/access\.log combined)$/#\1/g' /etc/apache2/sites-available/default
perl -pi -e 's/(memory_limit =)\s+\d+M(.*?)$/\1 256M\2/g' /etc/php5/apache2/php.ini
perl -pi -e 's/(short_open_tag =)\s+On$/\1 Off/g' /etc/php5/apache2/php.ini
perl -pi -e 's/(expose_php =)\s+On$/\1 Off/g' /etc/php5/apache2/php.ini
perl -pi -e 's/(mysql\.allow_persistent =)\s+On$/\1 Off/g' /etc/php5/apache2/php.ini
perl -pi -e 's/(memory_limit =)\s+\d+M(.*?)$/\1 256M\2/g' /etc/php5/cli/php.ini
perl -pi -e 's/(short_open_tag =)\s+On$/\1 Off/g' /etc/php5/cli/php.ini
perl -pi -e 's/(expose_php =)\s+On$/\1 Off/g' /etc/php5/cli/php.ini
perl -pi -e 's/(mysql\.allow_persistent =)\s+On$/\1 Off/g' /etc/php5/cli/php.ini
/etc/init.d/apache2 force-reload
mysqladmin -u root -p create drupal
mysqladmin -u root -p create drupal_checkout
crontab -e

*/2 * * * * /usr/bin/wget -O - -q -t 1 http://localhost/cron.php

Drupal PIFR installation

cd /var/www
rm index.html
cvs -z6 -d :pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal checkout -r DRUPAL-6-19 drupal
cd drupal
mv * ..
mv .htaccess ..
cd ..
rmdir drupal
cd sites/all
mkdir modules
cd modules
cvs -z6 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib checkout -r DRUPAL-6--1 -d cvs_deploy contributions/modules/cvs_deploy
cvs -z6 -d:pserver:anonymous:anonymous@cvs.drupal.org:/cvs/drupal-contrib checkout -r DRUPAL-6--2-2 -d project_issue_file_review contributions/modules/project_issue_file_review
cd ../../default
cp default.settings.php settings.php
vi settings.php

$db_url = array();
$db_url['default'] = 'mysqli://username:password@localhost/drupal';
$db_url['pifr_checkout'] = 'mysqli://username:password@localhost/drupal_checkout';

mkdir files
chmod 777 files
touch files/review.log
chmod 777 files/review.log
chown www-data:www-data files/review.log
cd ../..
ln -s ./sites/default/files/checkout .

The symbolic link will be broken because PIFR should create the checkout directory on its own during the testing process.

Optimize InnoDB

Not a lot of testing has been done with variations to these additional configuration options in /etc/mysql/my.cnf. This one is simply known to work.

#innodb_log_file_size = 32M
#innodb_log_group_home_dir = /var/lib/mysql
#innodb_data_home_dir = /var/lib/mysql
#innodb_data_file_path = ibdata1:100M:autoextend
#innodb_log_files_in_group = 2
#innodb_log_buffer_size = 1M
# This should match your number of CPUs
innodb_thread_concurrency = 4
# If you have lots of RAM, you can increase the innodb_buffer_pool_size
innodb_buffer_pool_size = 256M
innodb_additional_mem_pool_size = 10M
innodb_file_per_table = 1
innodb_file_io_threads = 1
innodb_max_dirty_pages_pct = 70

Using a RAM disk

Backup then either replace /etc/init.d/mysql with the attached version or use the patch to run the MySQL databases and checkout directory from RAM in tmpfs. Make sure the result init.d mysql script is still chmod 755. As of November 13, 2009, it takes about 71MB of space in /var/lib/mysql to run a basic test of Drupal 7 core, so keep that in mind if you change the tmpfs allocations provided in the setup patches.

Then execute the following so you can keep your Drupal configuration as long as you do clean starts and stops of MySQL.

mkdir /var/lib/.mysql
chown -R mysql:mysql /var/lib/.mysql
mkdir /var/www/sites/default/.files
touch /var/www/sites/default/.files/remove_me_later.txt
chown -R www-data:www-data /var/www/sites/default/.files
/etc/init.d/mysql stop
cd /var/lib/.mysql
cd /var/lib/mysql
rm -r *
cd /var/lib
/etc/init.d/mysql start
rm /var/www/sites/default/.files/remove_me_later.txt

Once you are in a final configured state, you might also want to create a /var/lib/.mysql.bak directory for storing a working copy of your database files. There are cases where mysql could fail to start, then it could copy nothing from the empty /var/lib/mysql directory to the stateful /var/lib/.mysql copy.



Interface configuration

  1. Get an account on the master server or have someone add your client test server and provide you an API key.
  2. If you create the account yourself on the master server, in your master server account, at user/#/pifr, add a client of type Test on the master and copy the key to the client at admin/pifr/configuration.
  3. On the client, enable CVS Deploy, PIFR, PIFR Client, Assertion, and Simpletest modules.
  4. At admin/pifr/configuration on the client, add the API key and master server URL. The other client defaults are OK. For maximum performance, set concurrency to at least the number of CPU cores available for testing on the server. If unsure, check the output of htop, which was installed as part of the recommended deb packages.
  5. Make sure all the command line tools have output at admin/pifr/client on the client.
  6. Toggle the state on the client so it is enabled at admin/pifr.
  7. On the master server at user/#/pifr or admin/pifr/server, enable the client in the operations field.

The next cron on the client should start a self test. If the self test succeeds, it will start testing patches from the project server. The client will list the number of test assertions it has completed for a test at admin/pifr. Note the client will run a complete cycle of patch testing twice before becoming enabled for project patch testing. The first it to make sure the client correctly catches an intentional breakage of the checkout. The second is to make sure a clean checkout has no failures or exceptions.


mysqladmin -u root -p drop drupal_checkout
mysqladmin -u root -p create drupal_checkout
rm -r /var/www/sites/default/files/checkout

I occasionally got "When requesting next test, server responded: Invalid server" errors on my client when I did have the right API key, so I altered the client xmlrpc file to include some extra debugging calls to watchdog. After many long tests, I realized my server was going beyond the default 45 minute limit set on the server to timeout a runaway test. I increased it to 200 and finally passed. If your client exceeds 20 minutes per test, it is probably undesirable as a production testing server.

Make sure your php.ini files for cli and apache have the following set, otherwise the client might have fatal errors that prevent it from completing all the tests.

display_errors = On
log_errors = Off
;error_log = syslog

Try mysqlreport from hackmysql.com for diagnosing speed issues with MySQL.

cd ~
wget hackmysql.com/scripts/mysqlreport
chmod +x mysqlreport
./mysqlreport --user=root --password=password