Suppose you're doing it wrong: you're using MySQL and your test suite is slow very slow. MySQL is very slow at DDL statements so creating/clearing/loading that test database all the time is going to be very slow.
People have worked out some solutions like:
Using TRUNCATE instead of DROP/CREATE and/or other tricks [1].
Fine tunning mysql ... just for development?!? [2], [3].
Use sqlite in :memory: - very bad idea, lots of subtle bugs won't be catched in the test suite.
And finally there's one solution that doesn't have the code trade-offs but it's a pain to get it set up: MySQL running on ramdisk (known as tmpfs). I've seen some solutions [4], [5], [6], none worked on Ubuntu (12.04) very well for me thus I've cooked up my own version.
It's largely based on [6] but with cleanup code in case you already ran it and added the missing database setup part (you might want to edit the passwords and database names).
#!/bin/bash -xEei=$1if[ -z "$i"];thenecho"Missing argument: instance number."exit1fiport=$[3306+$i]pid=`cat "/var/run/mysqld/mysqld$i.pid"||true`if[ -n "$pid"];thenkill -9 $pidwhilekill -0 $pid;do
sleep 0.5
donefi
umount -l "/var/lib/mysql$i"||true
rm -rf "/var/lib/mysql$i"
mkdir "/var/lib/mysql$i"
mount -t tmpfs -o size=400M tmpfs "/var/lib/mysql$i"
chown -R mysql.mysql "/var/lib/mysql$i"
mkdir -p "/var/log/mysql$i"
chown -R mysql.mysql "/var/log/mysql$i"
rm -rf "/etc/mysql$i"
cp -R /etc/mysql/ "/etc/mysql$i"cd"/etc/mysql$i/"
sed -i "s/3306/$port/g" my.cnf
sed -i "s/mysqld.sock/mysqld$i.sock/g" my.cnf
sed -i "s/mysqld.pid/mysqld$i.pid/g" my.cnf
sed -i "s/var\/lib\/mysql/var\/lib\/mysql$i/g" my.cnf
sed -i "s/var\/log\/mysql/var\/log\/mysql$i/g" my.cnf
if[ ! -f /etc/apparmor.d/disable/usr.sbin.mysqld ];then
touch /etc/apparmor.d/disable/usr.sbin.mysqld
service apparmor reload
fi
mysql_install_db --user=mysql --datadir="/var/lib/mysql$i"pass=`perl -e 'print map{("a".."z","A".."Z",0..9)[int(rand(62))]}(1..16)'`;
mysqld_safe --defaults-file=/etc/mysql$i/my.cnf&
sleep 3
mysqladmin -S /var/run/mysqld/mysqld$i.sock password $pass
cat <<EOF | mysql -uroot -h127.0.0.1 -P$port -p$pass USE mysql; CREATE DATABASE IF NOT EXISTS app CHARACTER SET utf8 COLLATE utf8_bin; CREATE DATABASE IF NOT EXISTS app_tests CHARACTER SET utf8 COLLATE utf8_bin; GRANT ALL ON app.* TO 'app'@'localhost' IDENTIFIED BY 'app'; GRANT ALL ON app_tests.* TO 'app'@'localhost' IDENTIFIED BY 'app'; GRANT ALL ON *.* TO 'root'@'%' IDENTIFIED BY '$pass'; FLUSH PRIVILEGES;EOF
It will run on port 3306 + instance-number. Also, you need to run it with sudo.