#!/bin/zsh # BATCH STRESS TEST FOR IMAP ---------------------- # http://imgs.xkcd.com/comics/science.jpg # # Run imaptest against a LEAP IMAP server # for a fixed period of time, and collect output. # # Author: Kali Kaneko # Date: 2014 01 26 # # To run, you need to have `imaptest` in your path. # See: # http://www.imapwiki.org/ImapTest/Installation # # For the tests, I'm using a 10MB file sample that # can be downloaded from: # http://www.dovecot.org/tmp/dovecot-crlf # # Want to contribute to benchmarking? # # 1. Create a pristine account in a bitmask provider. # # 2. Launch your bitmask client, with different flags # if you desire. # # For example to try the nosync flag in sqlite: # # LEAP_SQLITE_NOSYNC=1 bitmask --debug -N --offline -l /tmp/leap.log # # 3. Run at several points in time (ie: just after # launching the bitmask client. one minute after, # ten minutes after) # # mkdir data # cd data # ../leap_tests_imap.zsh | tee sqlite_nosync_run2.log # # 4. Submit your results to: kali at leap dot se # together with the logs of the bitmask run. # # Please provide also details about your system, and # the type of hard disk setup you are running against. # # ------------------------------------------------ # Edit these variables if you are too lazy to pass # the user and mbox as parameters. Like me. USER="test_f14@dev.bitmask.net" MBOX="~/leap/imaptest/data/dovecot-crlf" HOST="localhost" PORT="1984" # in case you have it aliased GREP="/bin/grep" IMAPTEST="imaptest" # ----------------------------------------------- # # These should be kept constant across benchmarking # runs across different machines, for comparability. DURATION=200 NUM_MSG=200 # TODO add another function, and a cli flag, to be able # to take several aggretates spaced in time, along a period # of several minutes. imaptest_cmd() { stdbuf -o0 ${IMAPTEST} user=${USER} pass=1234 host=${HOST} \ port=${PORT} mbox=${MBOX} clients=1 msgs=${NUM_MSG} \ no_pipelining 2>/dev/null } stress_imap() { mkfifo imap_pipe cat imap_pipe | tee output & imaptest_cmd >> imap_pipe } wait_and_kill() { while : do sleep $DURATION pkill -2 imaptest rm imap_pipe break done } print_results() { sleep 1 echo echo echo "AGGREGATED RESULTS" echo "----------------------" echo "\tavg\tstdev" $GREP "avg" ./output | sed -e 's/^ *//g' -e 's/ *$//g' | \ gawk ' function avg(data, count) { sum=0; for( x=0; x <= count-1; x++) { sum += data[x]; } return sum/count; } function std_dev(data, count) { sum=0; for( x=0; x <= count-1; x++) { sum += data[x]; } average = sum/count; sumsq=0; for( x=0; x <= count-1; x++) { sumsq += (data[x] - average)^2; } return sqrt(sumsq/count); } BEGIN { cnt = 0 } END { printf("LOGI:\t%04.2lf\t%04.2f\n", avg(array[1], NR), std_dev(array[1], NR)); printf("LIST:\t%04.2lf\t%04.2f\n", avg(array[2], NR), std_dev(array[2], NR)); printf("STAT:\t%04.2lf\t%04.2f\n", avg(array[3], NR), std_dev(array[3], NR)); printf("SELE:\t%04.2lf\t%04.2f\n", avg(array[4], NR), std_dev(array[4], NR)); printf("FETC:\t%04.2lf\t%04.2f\n", avg(array[5], NR), std_dev(array[5], NR)); printf("FET2:\t%04.2lf\t%04.2f\n", avg(array[6], NR), std_dev(array[6], NR)); printf("STOR:\t%04.2lf\t%04.2f\n", avg(array[7], NR), std_dev(array[7], NR)); printf("DELE:\t%04.2lf\t%04.2f\n", avg(array[8], NR), std_dev(array[8], NR)); printf("EXPU:\t%04.2lf\t%04.2f\n", avg(array[9], NR), std_dev(array[9], NR)); printf("APPE:\t%04.2lf\t%04.2f\n", avg(array[10], NR), std_dev(array[10], NR)); printf("LOGO:\t%04.2lf\t%04.2f\n", avg(array[11], NR), std_dev(array[11], NR)); print "" print "TOT samples", NR; } { it = cnt++; array[1][it] = $1; array[2][it] = $2; array[3][it] = $3; array[4][it] = $4; array[5][it] = $5; array[6][it] = $6; array[7][it] = $7; array[8][it] = $8; array[9][it] = $9; array[10][it] = $10; array[11][it] = $11; }' } { test $1 = "--help" } && { echo "Usage: $0 [user@provider] [/path/to/sample.mbox]" exit 0 } # If the first parameter is passed, take it as the user { test $1 } && { USER=$1 } # If the second parameter is passed, take it as the mbox { test $2 } && { MBOX=$2 } echo "[+] LEAP IMAP TESTS" echo "[+] Running imaptest for $DURATION seconds with $NUM_MSG messages" wait_and_kill & stress_imap print_results