Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Run civicrm unit tests in a ramdisk

Using a ramdisk for unit tests

Overview

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.

One-time setup

This assumes you have unit tests already working normally.

  1. Install Imdisk - https://sourceforge.net/projects/imdisk-toolkit
  2. 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.
  3. Create a folder called Data on the drive.
  4. Give "NETWORK SERVICE" and "CREATOR OWNER" Full Control permission on the folder.
  5. Run 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.
  6. Start mysqld again: mysqld.exe --console --datadir=V:/Data
  7. In another window mysql -u root -p
    • Use the temporary password to log in.
  8. Change the password: ALTER USER root@localhost identified by '<new password>';
  9. 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.
  10. 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.
  11. GRANT SUPER ON *.* to civitestuser@localhost;
  12. 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;
  13. Exit the mysql client.
  14. mysqladmin -u root -p shutdown
  15. Run C:\windows\system32\imdisk.cpl as an administrator.
  16. Select V: and use the button at the bottom to save the ramdisk image somewhere, e.g. C:\stuff\RamdiskV.img
  17. Still in the tool, right click on the V: drive and "remove" it to dismount it.
  18. 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

  1. Open an administrator command window.
  2. 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.
  3. Run your tests.
  4. In the original administrator command window run C:\stuff\unittests.bat stop to return back to normal.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.