From 3dc09dfe434092e9b239f6058630650280b48ac4 Mon Sep 17 00:00:00 2001 From: Mark Riddoch Date: Mon, 18 Aug 2014 18:26:14 +0100 Subject: [PATCH] Addition of spinlock unit test --- server/core/test/makefile | 23 +++++- server/core/test/testspinlock.c | 131 ++++++++++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 4 deletions(-) create mode 100644 server/core/test/testspinlock.c diff --git a/server/core/test/makefile b/server/core/test/makefile index d3948575d..5f82b7fef 100644 --- a/server/core/test/makefile +++ b/server/core/test/makefile @@ -10,6 +10,8 @@ include ../../../test.inc CC=cc TESTLOG := $(shell pwd)/testhash.log +TESTS=testhash testspinlock + cleantests: - $(DEL) *.o - $(DEL) testhash @@ -20,11 +22,18 @@ testall: $(MAKE) DEBUG=Y buildtests $(MAKE) runtests -buildtests : +buildtests : $(TESTS) + +testhash: testhash.c $(CC) $(CFLAGS) \ -I$(ROOT_PATH)/server/include \ -I$(ROOT_PATH)/utils \ testhash.c ../hashtable.o ../atomic.o ../spinlock.o -o testhash +testspinlock: testspinlock.c + $(CC) $(CFLAGS) \ + -I$(ROOT_PATH)/server/include \ + -I$(ROOT_PATH)/utils \ + testspinlock.c ../spinlock.o ../atomic.o ../thread.o -o testspinlock runtests: @echo "" > $(TESTLOG) @@ -34,9 +43,15 @@ runtests: @echo "-------------------------------" >> $(TESTLOG) @ -./testhash 2>> $(TESTLOG) ifeq ($?,0) - @echo "MaxScale core PASSED" >> $(TESTLOG) + @echo "MaxScale hashtable PASSED" >> $(TESTLOG) else - @echo "MaxScale core FAILED" >> $(TESTLOG) + @echo "MaxScale hashtable FAILED" >> $(TESTLOG) +endif + @ -./testspinlock 2>> $(TESTLOG) +ifeq ($?,0) + @echo "MaxScale spinlock PASSED" >> $(TESTLOG) +else + @echo "MaxScale spinlock FAILED" >> $(TESTLOG) endif @echo "" >> $(TESTLOG) - @cat $(TESTLOG) >> $(TEST_MAXSCALE_LOG) \ No newline at end of file + @cat $(TESTLOG) >> $(TEST_MAXSCALE_LOG) diff --git a/server/core/test/testspinlock.c b/server/core/test/testspinlock.c new file mode 100644 index 000000000..5d03f0e47 --- /dev/null +++ b/server/core/test/testspinlock.c @@ -0,0 +1,131 @@ +/* + * This file is distributed as part of MaxScale. It is free + * software: you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation, + * version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright SkySQL Ab 2014 + */ + +/** + * + * @verbatim + * Revision History + * + * Date Who Description + * 18/08-2014 Mark Riddoch Initial implementation + * + * @endverbatim + */ + +#include +#include +#include + +#include +#include + + +/** + * test1 spinlock_acquire_nowait tests + * + * Test that spinlock_acquire_nowait returns false if the spinlock + * is already taken. + * + * Test that spinlock_acquire_nowait returns true if the spinlock + * is not taken. + * + * Test that spinlock_acquire_nowait does hold the spinlock. + */ +static int +test1() +{ +SPINLOCK lck; + + spinlock_init(&lck); + spinlock_acquire(&lck); + if (spinlock_acquire_nowait(&lck)) + { + fprintf(stderr, "spinlock_acquire_nowait: test 1 failed.\n"); + return 1; + } + spinlock_release(&lck); + if (!spinlock_acquire_nowait(&lck)) + { + fprintf(stderr, "spinlock_acquire_nowait: test 2 failed.\n"); + return 1; + } + if (spinlock_acquire_nowait(&lck)) + { + fprintf(stderr, "spinlock_acquire_nowait: test 3 failed.\n"); + return 1; + } + spinlock_release(&lck); + + return 0; +} + +static int acquire_time; + +static void +test2_helper(void *data) +{ +SPINLOCK *lck = (SPINLOCK *)data; +unsigned long t1 = time(0); + + spinlock_acquire(lck); + acquire_time = time(0) - t1; + spinlock_release(lck); + return; +} + +/** + * Check that spinlock correctly blocks another thread whilst the spinlock + * is held. + * + * Take out a lock. + * Start a second thread to take the same lock + * sleep for 10 seconds + * release lock + * verify that second thread took at least 8 seconds to obtain the lock + */ +static int +test2() +{ +SPINLOCK lck; +void *handle; + + acquire_time = 0; + spinlock_init(&lck); + spinlock_acquire(&lck); + handle = thread_start(test2_helper, (void *)&lck); + sleep(10); + spinlock_release(&lck); + thread_wait(handle); + + if (acquire_time < 8) + { + fprintf(stderr, "spinlock: test 1 failed.\n"); + return 1; + } + return 0; +} + +main(int argc, char **argv) +{ +int result = 0; + + result += test1(); + + exit(result); +} +