Using a ramdisk for unit tests
Why do this? Tests run faster because database reloading between tests is fast.
Why not do this? If you need to keep flipping back and forth between your tests and your browser accessing your dev site or running xdebug/IDE against your dev site then this becomes awkward.
These instructions are for windows but it shouldn't be too hard to adjust for unix.
This assumes you have unit tests already working normally.
- Install Imdisk - https://sourceforge.net/projects/imdisk-toolkit
- Create a ramdisk using the Imdisk Ramdisk Configuration tool.
- 500 MB seems to work ok for me. Could probably go smaller.
- For the purposes here, don't select launch at startup. A variation of this where you run all your databases on ramdisk all the time is probably doable but you have to think about possible data loss. For headless tests in a throwaway database like I'm doing here that's not a concern. Also you'd need a lot more RAM.
- I used V: as the drive letter, so substitute below as appropriate.
- Create a folder called Data on the drive.
- Give "NETWORK SERVICE" and "CREATOR OWNER" Full Control permission on the folder.
mysqld.exe --initialize --console --datadir=V:/Data
- This will output some log info and at the end also output a temporary password which you'll need in a minute.
- For mariadb instead use
mysql_install_db --password=<desired root password> --datadir=V:/Data, and then you've already set the password so can omit step 8.
- Start mysqld again:
mysqld.exe --console --datadir=V:/Data.
- In another window
mysql -u root -p
- Use the temporary password to log in.
- Change the password:
ALTER USER root@localhost identified by '<new password>';
CREATE database civicrm_test;
- The name of the database should be the same as the one you were using before for tests, otherwise you need to reconfigure cv.
GRANT all ON civicrm_test.* TO civitestuser@localhost identified by '<password>';
- Also the name/password of the user should be the same as you were using before for tests.
GRANT SUPER ON *.* to civitestuser@localhost;
- For fun see how fast it is to load the civi database manually:
- source /path/to/civicrm/sql/civicrm.mysql;
- source /path/to/civicrm/sql/civicrm_generated.mysql;
- Exit the mysql client.
mysqladmin -u root -p shutdown
C:\windows\system32\imdisk.cplas an administrator.
- Select V: and use the button at the bottom to save the ramdisk image somewhere, e.g. C:\stuff\RamdiskV.img
- Still in the tool, right click on the V: drive and "remove" it to dismount it.
- Put the following in a unittests.bat file somewhere convenient. Adjust paths etc as needed.
@echo off if "%1"=="start" ( REM **** load preconfigured ramdisk as drive V: into physical memory **** imdisk -a -m V: -f C:\stuff\RamdiskV.img -o awe REM **** stop mysql **** net stop mysql57 REM **** start mysql pointing the data dir at our preconfigured one **** "C:\Program Files (x86)\MySQL\MySQL Server 5.7\bin\mysqld.exe" --console --datadir=V:/Data ) ELSE ( REM **** shut down mysql properly **** mysqladmin -u root -p shutdown REM **** need to wait until mysql shuts down before next step **** echo When mysql has shut down, pause REM **** remove ramdisk **** imdisk -d -m V: REM **** start up normal mysql again **** net start mysql57 )
Regular ongoing use
- Open an administrator command window.
start C:\stuff\unittests.bat start
- The first start opens a new window because you'll need the original window again to stop it later, since mysqld will be hogging the window.
- Run your tests.
- In the original administrator command window run
C:\stuff\unittests.bat stopto return back to normal.