git » nmdb » commit b5fb96f

Add scripts for automated performance testing

author Alberto Bertogli
2008-07-25 23:43:25 UTC
committer Alberto Bertogli
2008-07-25 23:47:53 UTC
parent 8d70b173ff7cbd288917087f1410d96f4dcb8c35

Add scripts for automated performance testing

This patch introduces two new scripts inside tests/perf: perf.sh and
ag.sh. They depend on being used in a git repository.

perf.sh can run the C tests with different parameters and graph the
results. The results will be named after the current git commit. A single
run takes about 9 minutes on an Intel Core 2 Duo E8400 (3.0Ghz).

ag.sh can aggregate the results of the perf.sh runs across different
commits, creating comparative graphs.

Together, they can be used to track performance regressions in the common
operations.

Signed-off-by: Alberto Bertogli <albertito@blitiri.com.ar>

.gitignore +6 -3
tests/perf/ag.sh +126 -0
tests/perf/perf.sh +211 -0

diff --git a/.gitignore b/.gitignore
index ec7d37f..1e72e7b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,10 +10,13 @@
 # *~
 /nmdb/nmdb
 /utils/nmdb-stats
-tests/c/*-*-cache
-tests/c/*-*-normal
-tests/c/*-*-sync
+/tests/c/*-*-cache
+/tests/c/*-*-normal
+/tests/c/*-*-sync
 /libnmdb/nmdb.h
 /libnmdb/libnmdb.pc
 /tags
 /bindings/python/build
+/tests/perf/out
+/tests/perf/ag-data
+/tests/perf/graph
diff --git a/tests/perf/ag.sh b/tests/perf/ag.sh
new file mode 100755
index 0000000..0ad9320
--- /dev/null
+++ b/tests/perf/ag.sh
@@ -0,0 +1,126 @@
+#!/bin/bash
+
+# Automated nmdb performance test - aggregated graphics
+# Should be ran from somewhere inside the git repository
+
+TIMES=5000	# Times parameter used for the tests
+
+set -e
+
+
+# aggregate the results prepending the version, but we need a table because
+# gnuplot doesn't like strings as values
+cd `git rev-parse --show-cdup`
+cd tests/perf/out
+mkdir -p ../ag-data
+rm -f ../ag-data/*
+
+declare -a COMMITS
+N=0
+
+for i in *; do
+	COMMITS[$N]=$i
+	for f in 2-tipc-cache.out 3-tipc-cache.out; do
+		while read L; do
+			if [ "$L" != "" ]; then
+				echo $N $L >> ../ag-data/$f
+			else
+				# preserve data set delimiters for gnuplot
+				echo >> ../ag-data/$f
+			fi
+		done < $i/$f
+	done
+	N=$[ $N + 1 ]
+done
+
+
+# write the gnuplot script
+cd `git rev-parse --show-cdup`
+cd tests/perf
+mkdir -p graph
+DST=`pwd`/graph
+
+# 2-tipc-cache (3d)
+cat > graph/ag-tmp.sh <<EOF
+#!/usr/bin/env gnuplot
+
+set terminal png size 1280,1024 enhanced
+
+set title "all versions, test 2, tipc"
+set ticslevel 0
+
+set output "$DST/3D-2-cache.png"
+set xtics axis offset -8 ( \\
+EOF
+
+N=0
+for c in ${COMMITS[@]}; do
+	echo "\"$c\" $N, \\" >> graph/ag-tmp.sh
+	N=$[ $N + 1 ]
+done
+
+cat >> graph/ag-tmp.sh <<EOF
+	"" $N)
+set xlabel "commit" offset 3
+set ylabel "key/value size"
+set zlabel "ops/seg"
+splot \
+	'ag-data/2-tipc-cache.out' using \
+		1:(\$2 * 2):($TIMES / (\$3 / 1000000.0)) \
+		with linespoints title "cache get"
+EOF
+
+# 2-tipc-cache (2d)
+cat >> graph/ag-tmp.sh <<EOF
+set output "$DST/2D-2-cache.png"
+set title "all versions, test 2, tipc"
+unset xtics
+set xtics autofreq
+set xlabel "key/value size"
+set ylabel "ops/seg"
+plot \\
+EOF
+
+for c in ${COMMITS[@]}; do
+cat >> graph/ag-tmp.sh <<EOF
+	'out/$c/2-tipc-cache.out' \\
+		using (\$1 * 2):($TIMES / (\$2 / 1000000.0)) \\
+		with linespoints title "cache get $c", \\
+EOF
+done
+
+cat >> graph/ag-tmp.sh <<EOF
+	0 notitle
+EOF
+
+# 3-tipc-cache (2d)
+cat >> graph/ag-tmp.sh <<EOF
+set output "$DST/2D-3-cache.png"
+set title "all versions, test 3, tipc"
+unset xtics
+set xtics autofreq
+set xlabel "key+value size"
+set ylabel "(get+set+del)/seg"
+plot \\
+EOF
+
+for c in ${COMMITS[@]}; do
+cat >> graph/ag-tmp.sh <<EOF
+	'out/$c/3-tipc-cache.out' \\
+		using (\$1 * 2):($TIMES / (\$2 / 1000000.0)) \\
+		with linespoints title "cache $c", \\
+EOF
+done
+
+cat >> graph/ag-tmp.sh <<EOF
+	0 notitle
+EOF
+
+chmod +x graph/ag-tmp.sh
+
+./graph/ag-tmp.sh
+rm ./graph/ag-tmp.sh
+
+cd - > /dev/null
+
+
diff --git a/tests/perf/perf.sh b/tests/perf/perf.sh
new file mode 100755
index 0000000..4824abf
--- /dev/null
+++ b/tests/perf/perf.sh
@@ -0,0 +1,211 @@
+#!/bin/bash
+
+# Automated nmdb performance test
+# Should be ran from somewhere inside the git repository
+
+COUNT=2		# How many times we should repeat the test
+TIMES=5000	# Times parameter for the tests
+
+
+set -e
+
+# set up the temporary directory, and the cleanup routine
+TMP=`mktemp -d -t nmdb-perf-test.XXXXXXXXXX` || \
+	( echo "error: Can't create tmp directory"; exit 1 )
+function atexit() {
+	server_stop
+	rm -r "$TMP"
+}
+trap atexit EXIT
+
+
+NMDBPID=
+function server_start() {
+	# launch the server
+	techo "start nmdb"
+	rm -f $TMP/database $OUTDIR/nmdb.log
+	./nmdb/nmdb -f -d $TMP/database -o $OUTDIR/nmdb.log &
+	NMDBPID=$!
+
+	# wait a bit so the clients don't try to talk too early
+	sleep 0.5
+}
+
+function server_stop() {
+	if [ "$NMDBPID" != "" ]; then
+		techo "stop nmdb"
+		kill $NMDBPID || true
+		wait $NMDBPID
+	fi
+	NMDBPID=
+}
+
+
+
+function techo() {
+	echo `date "+%H:%M:%S.%N"` "$@"
+}
+
+# helper function used to run a single test that takes the same parameters:
+# times, ksize, vsize; must be called from inside test_current
+function run_test() {
+	t1=$1
+	lcount=$2
+	ltimes=$3
+
+	for t2 in mult tipc tcp udp sctp; do
+		for t3 in cache; do
+			t="$t1-$t2-$t3"
+			techo "   " $t $@
+			rm -f $OUTDIR/$t.out
+			for i in `seq 1 $lcount`; do
+				# restart server
+				server_start
+				echo -n "      "
+				for s in 4 32 128 512 1024 \
+						`seq 2048 2048 30000`; do
+					echo $s `tests/c/$t $ltimes $s $s` \
+							>> $OUTDIR/$t.out
+					sleep 0.3
+					echo -n " $s"
+				done
+				# gnuplot splits the data sets with this empty
+				# line, otherwise we get weird graphics when
+				# $COUNT > 2
+				echo >> $OUTDIR/$t.out
+				echo
+				server_stop
+			done
+		done
+	done
+}
+
+
+# tests the current revision
+function test_current() {
+	# go to the repo root
+	cd "`git rev-parse --show-cdup`"
+
+	# create the output directory
+	OUTDIR="tests/perf/out/`git describe --always`$SUFFIX"
+	techo mkdir $OUTDIR
+	mkdir -p $OUTDIR
+
+	# record the environment
+	(
+		echo date `date --rfc-3339=seconds`
+		echo testing `git describe --always`
+		#techo using perf ${OLDCOMMIT:-`git describe --always`}
+		echo
+		uname -a
+		gcc --version | grep gcc
+		echo
+		cat /proc/cpuinfo | grep 'model name'
+		cat /proc/meminfo | grep MemTotal
+	) > $OUTDIR/environment
+
+	# build
+	techo build
+	#make BACKEND=bdb > $OUTDIR/make.out
+	# no porque asumimos en el sistema
+	#make > $OUTDIR/make.out
+	cd tests/c
+	./make.sh build > $TMP/tests-make.out
+	cd - > /dev/null
+
+	# record the vmstat output while the test runs
+	techo vmstat
+	vmstat 1 > $OUTDIR/vmstat.out &
+	VMSTATPID=$!
+
+	# wait a bit for the server to come up
+	sleep 1
+
+	# run the tests
+	techo tests
+
+	for t1 in 2 3; do
+		run_test $t1 $COUNT $TIMES
+	done
+
+	# kill everything; the "|| true" is needed to prevent the script from
+	# dying if the process are already dead
+	techo "kill vmstat ($VMSTATPID)"
+	kill -9 $VMSTATPID || true
+
+	# wait for them to die
+	wait $NMDBPID $VMSTATPID > /dev/null 2> /dev/null || true
+
+	techo done
+}
+
+
+
+function write_current_graph_scripts() {
+	SUFFIX="$1"
+	V="`git describe --always`$SUFFIX"
+
+	# go to the results dir
+	cd "`git rev-parse --show-cdup`"
+
+	mkdir -p tests/perf/graph
+	DST=`pwd`/tests/perf/graph
+
+	gnuplot <<EOF
+
+set terminal png size 1280,1024 enhanced
+
+set output "$DST/$V-2-cache.png"
+set title "$V - test 2, tipc"
+set xlabel "key+value size"
+set ylabel "ops/seg"
+plot \
+	'tests/perf/out/$V/2-tipc-cache.out' using \
+		(\$1 * 2):($TIMES / (\$2 / 1000000.0)) title "cache: get" \
+		with linespoints, \
+	'tests/perf/out/$V/2-tipc-cache.out' using \
+		(\$1 * 2):($TIMES / (\$3 / 1000000.0)) title "cache: set" \
+		with linespoints, \
+	'tests/perf/out/$V/2-tipc-cache.out' using \
+		(\$1 * 2):($TIMES / (\$4 / 1000000.0)) title "cache: del" \
+		with linespoints \
+
+set output "$DST/$V-3-cache.png"
+set title "$V - test 3, tipc"
+set xlabel "key/value size"
+set ylabel "(get+set+del)/seg"
+plot \
+	'tests/perf/out/$V/3-tipc-cache.out' using \
+		1:($TIMES / (\$2 / 1000000.0)) title "cache"
+
+EOF
+	cd - > /dev/null
+
+}
+
+
+if [ "$2" == "" ]; then
+	SUFFIX=""
+else
+	SUFFIX="-$2"
+fi
+
+case $1 in
+    ""|"help"|"-h"|"--help")
+	echo "Usage: perf.sh test|graph [suffix]"
+	echo
+	echo "Run from somewhere inside the git repository; output will"
+	echo "be put in tests/pref/out/<git commit>[-suffix]."
+	exit 1
+	;;
+    "test")
+	test_current $SUFFIX
+	;;
+    "graph")
+	write_current_graph_scripts $SUFFIX
+	;;
+    *)
+	echo "Unknown operation"
+	exit 1
+esac
+