From e8ce2268e002f6010c5a530b5780ce97561632cd Mon Sep 17 00:00:00 2001 From: VilhoRaatikka Date: Fri, 7 Feb 2014 11:06:37 +0200 Subject: [PATCH] Test system for MaxScale. Every test/makefile have the following targets: cleantests - clean local and subdirectories' tests buildtests - build all local and subdirectories' tests runtests - run all local tests testall - clean, build and run local and subdirectories' tests Tests for directory random_dir are always in its subdirectory, in this case in random_dir/test . If random_dir has subdirectories with tests, random_dir/child_dir, for example, tests of child_dir can be started from random_dir/test/makefile where make -C child_dir/test is called. See MAXSCALE_HOME/test/README for further information. --- Makefile | 30 +++++ log_manager/makefile | 30 +++-- log_manager/test/makefile | 55 ++++++--- log_manager/test/testlog.c | 187 +++++++++++++++++++------------ makefile.inc | 2 +- query_classifier/makefile | 30 +++-- query_classifier/test/makefile | 61 +++++++--- query_classifier/test/testmain.c | 176 ++++++++++++++--------------- server/Makefile | 9 ++ server/core/Makefile | 12 ++ server/core/test/makefile | 46 +++++--- server/test/MaxScale_test.cnf | 117 +++++++++++++++++++ server/test/makefile | 67 +++++++++++ test/README | 65 +++++++++++ test/makefile | 63 +++++++++++ utils/makefile | 11 ++ utils/test/makefile | 30 +++++ 17 files changed, 763 insertions(+), 228 deletions(-) create mode 100644 server/test/MaxScale_test.cnf create mode 100644 server/test/makefile create mode 100644 test/README create mode 100644 test/makefile create mode 100644 utils/test/makefile diff --git a/Makefile b/Makefile index a33ecbcf0..67eb0d159 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,23 @@ # Date Who Description # 16/07/13 Mark Riddoch Initial implementation +include build_gateway.inc + DEST=$(HOME)/usr/local/skysql +# +# A special build of MaxScale is done for tests. +# HAVE_SRV carries information whether test MaxScale server +# is built already or not. +# HAVE_SRV == Y when test server is built, +# HAVE_SRV == N when not. +# It prevents unnecessary recompilation and also clean-up +# in the middle of the test. +# +HAVE_SRV := N + +.PHONY: buildtestserver + all: (cd log_manager; make) (cd query_classifier; make) @@ -40,5 +55,20 @@ install: (cd log_manager; make DEST=$(DEST) install) (cd query_classifier; make DEST=$(DEST) install) +cleantests: + $(MAKE) -C test cleantests + +buildtests: + $(MAKE) -C test buildtests + +testall: + $(MAKE) -C test HAVE_SRV=$(HAVE_SRV) testall + +buildtestserver: + $(MAKE) DEBUG=Y DYNLIB=Y DEST=$(ROOT_PATH)/server/test clean depend all install +$(eval HAVE_SRV := Y) + documentation: doxygen doxygate + + diff --git a/log_manager/makefile b/log_manager/makefile index b210570aa..b1386bbcc 100644 --- a/log_manager/makefile +++ b/log_manager/makefile @@ -4,14 +4,14 @@ include ../makefile.inc CC = gcc CPP = g++ -SRCS = log_manager.cc - -LOG_WRITER_PATH := $(shell pwd) +SRCS := log_manager.cc +UTILS_PATH := $(ROOT_PATH)/utils +CUR_DIR := $(shell pwd) makeall: clean all clean: - make -C ../utils clean + $(MAKE) -C $(UTILS_PATH) clean - $(DEL) *.o - $(DEL) *.so - $(DEL) *.so.1.0.1 @@ -20,16 +20,16 @@ clean: all: utils lib + utils: - make -C $(ROOT_PATH)/utils clean all - $(COPY) $(ROOT_PATH)/utils/skygw_utils.o ./ + $(MAKE) -C $(UTILS_PATH) clean all lib: libcomp liblink libcomp: $(CPP) -c $(CFLAGS) \ $(MYSQL_HEADERS) \ - -I../utils/ -I./ \ + -I$(UTILS_PATH) -I./ \ -fPIC ./log_manager.cc -o log_manager.o $(LDLIBS) liblink: @@ -47,7 +47,21 @@ depend: @rm -f depend $(CPP) -M $(CFLAGS) \ $(MYSQL_HEADERS) \ - -I../utils/ -I./ \ + -I$(UTILS_PATH) -I./ \ $(SRCS) > depend +cleantests: + $(MAKE) -C test cleantests + +buildtests: + $(MAKE) -C test DEBUG=Y buildtests + +runtests: + $(MAKE) -C test runtests + +testall: + $(MAKE) -C test testall + + + include depend diff --git a/log_manager/test/makefile b/log_manager/test/makefile index e356f2a03..6d37c7197 100644 --- a/log_manager/test/makefile +++ b/log_manager/test/makefile @@ -1,35 +1,64 @@ +# cleantests - clean local and subdirectories' tests +# buildtests - build all local and subdirectories' tests +# runtests - run all local tests +# testall - clean, build and run local and subdirectories' tests + include ../../build_gateway.inc include ../../makefile.inc CC = gcc CPP = g++ -TESTPATH := $(shell pwd) -LOG_MANAGER_PATH := $(ROOT_PATH)/log_manager -TESTAPP = $(TESTPATH)/testlog +TESTPATH := $(shell pwd) +TESTLOG := $(TESTPATH)/testlog.log +LOG_MANAGER_PATH:= $(ROOT_PATH)/log_manager +TESTAPP := $(TESTPATH)/testlog +UTILS_PATH := $(ROOT_PATH)/utils -runtest: makeall testall +# Use two threads by default +ifndef NTHR + NTHR=2 +endif -makeall: clean all +testall: + $(MAKE) cleantests + $(MAKE) DEBUG=Y buildtests + $(MAKE) runtests -clean: +cleantests: - $(DEL) *.o - $(DEL) testlog - $(DEL) *~ -all: testcomp testall - -testcomp: +buildtests: $(CC) $(CFLAGS) \ -L$(LOG_MANAGER_PATH) \ -Wl,-rpath,$(DEST)/lib \ -Wl,-rpath,$(LOG_MANAGER_PATH)/ \ -o testlog \ -I$(MARIADB_SRC_PATH)/include \ - -I$(LOG_MANAGER_PATH) -I$(ROOT_PATH)/utils testlog.c \ + -I$(LOG_MANAGER_PATH) -I$(UTILS_PATH) testlog.c \ -llog_manager $(LDLIBS) \ - $(LOG_MANAGER_PATH)/skygw_utils.o \ + $(UTILS_PATH)/skygw_utils.o -testall: - - $(LAUNCH_DEBUGGER) $(TESTAPP) $(BACKGR) +runtests: + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test Log Manager" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo "" >> $(TESTLOG) + @echo "Use 1 thread" >> $(TESTLOG) + @echo "" >> $(TESTLOG) + @-$(LAUNCH_DEBUGGER) $(TESTAPP) "-t 1" 2>>$(TESTLOG) + @echo "" >> $(TESTLOG) + @echo "Use 8 threads" >> $(TESTLOG) + @echo "" >> $(TESTLOG) + @-$(LAUNCH_DEBUGGER) $(TESTAPP) "-t 8" 2>>$(TESTLOG) + @echo "" >> $(TESTLOG) + @echo "Use 16 threads" >> $(TESTLOG) + @echo "" >> $(TESTLOG) + @-$(LAUNCH_DEBUGGER) $(TESTAPP) "-t 16" 2>>$(TESTLOG) + @echo "Log Manager PASSED" >> $(TESTLOG) + @echo "" >> $(TESTLOG) diff --git a/log_manager/test/testlog.c b/log_manager/test/testlog.c index 981c9a8cf..c21d30e17 100644 --- a/log_manager/test/testlog.c +++ b/log_manager/test/testlog.c @@ -37,7 +37,7 @@ typedef struct thread_st { static void* thr_run(void* data); static void* thr_run_morelog(void* data); -#define NTHR 256 +#define MAX_NTHR 256 #define NITER 100 #if 1 @@ -57,22 +57,56 @@ int main(int argc, char* argv[]) char* logstr; int i; - bool r; + bool succp; skygw_message_t* mes; simple_mutex_t* mtx; size_t nactive; - thread_t* thr[NTHR]; + thread_t** thr = NULL; time_t t; struct tm tm; + char c; + int nthr = 0; + int log_argc = 0; + char** log_argv = NULL; + while ((c = getopt(argc, argv, "t:")) != -1) + { + switch (c) { + case 't': + nthr = atoi(optarg); + break; + + default: + break; + } + } + + if (nthr <= 0) + { + fprintf(stderr, "Thread count argument is zero or " + "negative. Exiting.\n"); + err = 1; + goto return_err; + } + + thr = (thread_t*)calloc(1, nthr*sizeof(thread_t*)); + + if (thr == NULL) + { + fprintf(stderr, "Failed to allocate memory for thread " + "structure. Exiting.\n"); + err = 1; + goto return_err; + + } i = atexit(skygw_logmanager_exit); if (i != 0) { - fprintf(stderr, "Couldn't register exit function.\n"); + fprintf(stderr, "Couldn't register exit function.\n"); } - r = skygw_logmanager_init( argc, argv); - ss_dassert(r); + succp = skygw_logmanager_init( log_argc, log_argv); + ss_dassert(succp); t = time(NULL); tm = *(localtime(&t)); @@ -85,7 +119,7 @@ int main(int argc, char* argv[]) tm.tm_min, tm.tm_sec); - skygw_logmanager_init( argc, argv); + skygw_logmanager_init( log_argc, log_argv); logstr = ("First write with flush."); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -133,7 +167,7 @@ int main(int argc, char* argv[]) logstr = "Ph%dlip."; err = skygw_log_write(LOGFILE_TRACE, logstr, 1); - skygw_logmanager_init( argc, argv); + skygw_logmanager_init( log_argc, log_argv); logstr = ("A terrible error has occurred!"); err = skygw_log_write_flush(LOGFILE_ERROR, logstr); @@ -159,40 +193,40 @@ int main(int argc, char* argv[]) fprintf(stderr, "\nStarting test #1 \n"); /** 1 */ - for (i=0; imes = mes; - thr[i]->mtx = mtx; - thr[i]->nactive = &nactive; + for (i=0; imes = mes; + thr[i]->mtx = mtx; + thr[i]->nactive = &nactive; } - nactive = NTHR; + nactive = nthr; - for (i=0; itid = p; + for (i=0; itid = p; } do { - skygw_message_wait(mes); - simple_mutex_lock(mtx, true); - if (nactive > 0) { - simple_mutex_unlock(mtx); - continue; - } - break; + skygw_message_wait(mes); + simple_mutex_lock(mtx, true); + if (nactive > 0) { + simple_mutex_unlock(mtx); + continue; + } + break; } while(true); - for (i=0; itid, NULL); + for (i=0; itid, NULL); } /** This is to release memory */ skygw_logmanager_done(); simple_mutex_unlock(mtx); - for (i=0; imes = mes; - thr[i]->mtx = mtx; - thr[i]->nactive = &nactive; + for (i=0; imes = mes; + thr[i]->mtx = mtx; + thr[i]->nactive = &nactive; } - nactive = NTHR; + nactive = nthr; fprintf(stderr, "\nLaunching %d threads, each iterating %d times.", - NTHR, + nthr, NITER); - for (i=0; itid = p; + for (i=0; itid = p; } fprintf(stderr, ".. done"); @@ -225,17 +259,17 @@ int main(int argc, char* argv[]) fprintf(stderr, "\nStarting to wait threads.\n"); do { - skygw_message_wait(mes); - simple_mutex_lock(mtx, true); - if (nactive > 0) { - simple_mutex_unlock(mtx); - continue; - } - break; + skygw_message_wait(mes); + simple_mutex_lock(mtx, true); + if (nactive > 0) { + simple_mutex_unlock(mtx); + continue; + } + break; } while(true); - for (i=0; itid, NULL); + for (i=0; itid, NULL); } /** This is to release memory */ skygw_logmanager_done(); @@ -244,8 +278,8 @@ int main(int argc, char* argv[]) fprintf(stderr, "\nFreeing thread memory."); - for (i=0; imtx, true); *td->nactive -= 1; diff --git a/makefile.inc b/makefile.inc index f0bfa0316..a0615b797 100644 --- a/makefile.inc +++ b/makefile.inc @@ -10,7 +10,7 @@ # #ifdef UNIX - DEL := rm -f + DEL := rm -fr LINK := ln -s COPY := cp NOHUP := nohup diff --git a/query_classifier/makefile b/query_classifier/makefile index 9a9e52f33..efa456a01 100644 --- a/query_classifier/makefile +++ b/query_classifier/makefile @@ -4,33 +4,45 @@ include ../makefile.inc CC = gcc CPP = g++ -SRCS = query_classifier.cc - -QUERY_CLASSIFIER_PATH := $(shell pwd) +SRCS := query_classifier.cc +UTILS_PATH := $(ROOT_PATH)/utils +QUERY_CLASSIFIER_PATH := $(ROOT_PATH)/query_classifier +LOG_MANAGER_PATH := $(ROOT_PATH)/log_manager makeall: clean all clean: - make -C ../utils clean + $(MAKE) -C $(UTILS_PATH) clean - $(DEL) query_classifier.o - $(DEL) libquery_classifier.so - $(DEL) libquery_classifier.so.1.0.1 - - $(DEL) skygw_utils.o - $(DEL) *~ - $(DEL) depend all: utils lib +cleantests: + $(MAKE) -C test cleantests + +buildtests: + $(MAKE) -C test DEBUG=Y DYNLIB=Y buildtests + +runtests: + $(MAKE) -C test runtests + +testall: + $(MAKE) -C test testall + + utils: - make -C $(ROOT_PATH)/utils clean all - $(COPY) $(ROOT_PATH)/utils/skygw_utils.o ./ + $(MAKE) -C $(UTILS_PATH) clean all lib: libcomp liblink libcomp: $(CPP) -c $(CFLAGS) \ $(MYSQL_HEADERS) \ - -I$(ROOT_PATH)/log_manager/ \ + -I$(LOG_MANAGER_PATH) \ -I./ \ -fPIC ./query_classifier.cc -o query_classifier.o @@ -53,7 +65,7 @@ depend: @rm -f depend $(CPP) -M $(CFLAGS) \ $(MYSQL_HEADERS) \ - -I$(ROOT_PATH)/log_manager/ \ + -I$(LOG_MANAGER_PATH) \ -I./ \ $(SRCS) > depend diff --git a/query_classifier/test/makefile b/query_classifier/test/makefile index 69168afdc..59d3c552b 100644 --- a/query_classifier/test/makefile +++ b/query_classifier/test/makefile @@ -1,36 +1,61 @@ +# cleantests - clean local and subdirectories' tests +# buildtests - build all local and subdirectories' tests +# runtests - run all local tests +# testall - clean, build and run local and subdirectories' tests + include ../../build_gateway.inc include ../../makefile.inc CC = gcc CPP = g++ -TESTPATH := $(shell pwd) -QUERY_CLASSIFIER_PATH := $(ROOT_PATH)/query_classifier/ +TESTPATH := $(shell pwd) +TESTLOG := $(TESTPATH)/testqclass.log +QUERY_CLASSIFIER_PATH := $(ROOT_PATH)/query_classifier +LOG_MANAGER_PATH := $(ROOT_PATH)/log_manager +UTILS_PATH := $(ROOT_PATH)/utils TESTAPP = $(TESTPATH)/testmain -runtest: makeall testall +testall: + $(MAKE) cleantests + $(MAKE) DEBUG=Y DYNLIB=Y buildtests + $(MAKE) runtests -makeall: clean all - -clean: +cleantests: - $(DEL) testmain.o - $(DEL) testmain + - $(DEL) data - $(DEL) *~ -all: testcomp testall - -testcomp: +buildtests: $(CC) $(CFLAGS) \ -L$(QUERY_CLASSIFIER_PATH) \ - -L$(MARIADB_SRC_PATH)/libmysqld \ + -L$(LOG_MANAGER_PATH) \ + -L$(EMBEDDED_LIB) \ -Wl,-rpath,$(DEST)/lib \ - -Wl,-rpath,$(MARIADB_SRC_PATH)/libmysqld \ - -Wl,-rpath,$(QUERY_CLASSIFIER_PATH)/ \ + -Wl,-rpath,$(EMBEDDED_LIB) \ + -Wl,-rpath,$(LOG_MANAGER_PATH) \ + -Wl,-rpath,$(QUERY_CLASSIFIER_PATH) \ -o testmain -DSS_DEBUG \ - -I$(MARIADB_SRC_PATH)/include testmain.c \ - -lquery_classifier $(LDLIBS) $(LDMYSQL) \ - $(QUERY_CLASSIFIER_PATH)/skygw_utils.o + $(MYSQL_HEADERS) \ + -I$(QUERY_CLASSIFIER_PATH) \ + -I./ \ + -I$(UTILS_PATH) \ + testmain.c \ + $(UTILS_PATH)/skygw_utils.o \ + -lquery_classifier -lz -ldl -lssl -laio -lcrypt \ + -llog_manager \ + $(LDLIBS) $(LDMYSQL) - -testall: - - $(LAUNCH_DEBUGGER) $(TESTAPP) $(BACKGR) +runtests: + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test Query Classifier" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @ -$(LAUNCH_DEBUGGER) $(TESTAPP) $(BACKGR) 2>> $(TESTLOG) +ifeq ($?, 0) + @echo "Query Classifier PASSED" >> $(TESTLOG) +else + @echo "Query Classifier FAILED" >> $(TESTLOG) +endif diff --git a/query_classifier/test/testmain.c b/query_classifier/test/testmain.c index adbcd00c8..cfb0f6ef4 100644 --- a/query_classifier/test/testmain.c +++ b/query_classifier/test/testmain.c @@ -1,3 +1,5 @@ +#include +#include #include #include #include @@ -5,27 +7,25 @@ #include #include "../../utils/skygw_utils.h" -//#include "skygw_debug.h" - //#include "skygw_types.h" #include "../query_classifier.h" static char datadir[1024] = ""; static char mysqldir[1024] = ""; static char* server_options[] = { - "SkySQL Gateway", - "--datadir=", - "--default-storage-engine=myisam", - NULL + "SkySQL Gateway", + "--datadir=", + "--default-storage-engine=myisam", + NULL }; const int num_elements = (sizeof(server_options) / sizeof(char *)) - 1; static char* server_groups[] = { - "embedded", - "server", - "server", - NULL + "embedded", + "server", + "server", + NULL }; static void slcursor_add_case( @@ -117,12 +117,12 @@ int main(int argc, char** argv) slist_cursor_t* c; const char* q; query_test_t* qtest; - skygw_query_type_t qtype; bool succp; bool failp = true; unsigned int f = 0; int nsucc = 0; int nfail = 0; + int rc = 0; MYSQL* mysql; char* workingdir; char ddoption[1024]; @@ -178,7 +178,7 @@ int main(int argc, char** argv) query_test_init(q, QUERY_TYPE_READ, false, true)); q = "select tt1.id, tt2.id from t1 tt1, t2 tt2 where tt1.name is " - "not null and tt2.name is not null"; + "not null and tt2.name is not null"; slcursor_add_case( c, query_test_init(q, QUERY_TYPE_READ, false, false)); @@ -227,15 +227,15 @@ int main(int argc, char** argv) query_test_init(q, QUERY_TYPE_SESSION_WRITE, false, false)); q = "select * from table1 " - "where table1.field IN " - "(select * from table1a union select * from table1b) union " - "select * from table2 where table2.field = " - "(select (select f1 from table2a where table2a.f2 = table2b.f3) " - "from table2b where table2b.f1 = table2.f2) union " - "select * from table3"; - slcursor_add_case( - c, - query_test_init(q, QUERY_TYPE_READ, false, true)); + "where table1.field IN " + "(select * from table1a union select * from table1b) union " + "select * from table2 where table2.field = " + "(select (select f1 from table2a where table2a.f2 = table2b.f3) " + "from table2b where table2b.f1 = table2.f2) union " + "select * from table3"; + slcursor_add_case( + c, + query_test_init(q, QUERY_TYPE_READ, false, true)); /** RENAME TABLEs */ q = "RENAME TABLE T1 to T2"; @@ -293,7 +293,7 @@ int main(int argc, char** argv) /** Object creation statements */ q = "create procedure si (out param1 int) \nbegin select count(*) " - "into param1 from t1; \nend"; + "into param1 from t1; \nend"; slcursor_add_case( c, query_test_init(q, QUERY_TYPE_WRITE, false, true)); @@ -334,7 +334,7 @@ int main(int argc, char** argv) query_test_init(q, QUERY_TYPE_WRITE, false, true)); q = "SELECT NOW();CREATE TABLE T1 (ID INTEGER);" - "SET sql_log_bin=0;CREATE TABLE T2 (ID INTEGER)"; + "SET sql_log_bin=0;CREATE TABLE T2 (ID INTEGER)"; slcursor_add_case( c, query_test_init(q, QUERY_TYPE_WRITE, false, true)); @@ -342,7 +342,7 @@ int main(int argc, char** argv) /** Setting database makes this SESSION_WRITE */ q = "USE TEST;CREATE TABLE T1 (ID INTEGER);" - "SET sql_log_bin=0;CREATE TABLE T2 (ID INTEGER)"; + "SET sql_log_bin=0;CREATE TABLE T2 (ID INTEGER)"; slcursor_add_case( c, query_test_init(q, QUERY_TYPE_SESSION_WRITE, false, true)); @@ -356,13 +356,13 @@ int main(int argc, char** argv) fprintf(stderr, "Failed to resolve the working directory, $PWD is not " "set.\n"); - goto return_without_server; + ss_dassert(workingdir != NULL); } else if (access(workingdir, R_OK) != 0) { fprintf(stderr, "Failed to access the working directory due %d, %s\n", errno, strerror(errno)); - goto return_without_server; + ss_dassert(false); } else { char** so = server_options; snprintf(datadir, 1023, "%s/data", workingdir); @@ -373,7 +373,7 @@ int main(int argc, char** argv) if (*so == NULL) { fprintf(stderr, "Failed to find datadir option.\n"); - goto return_without_server; + ss_dassert(*so != NULL); } *so = ddoption; @@ -383,13 +383,13 @@ int main(int argc, char** argv) failp = mysql_library_init(num_elements, server_options, server_groups); if (failp) { - MYSQL* mysql = mysql_init(NULL); - ss_dassert(mysql != NULL); - fprintf(stderr, - "mysql_init failed, %d : %s\n", - mysql_errno(mysql), - mysql_error(mysql)); - goto return_without_server; + MYSQL* mysql = mysql_init(NULL); + ss_dassert(mysql != NULL); + fprintf(stderr, + "mysql_init failed, %d : %s\n", + mysql_errno(mysql), + mysql_error(mysql)); + ss_dassert(!failp); } fprintf(stderr, @@ -402,10 +402,10 @@ int main(int argc, char** argv) succp = slcursor_move_to_begin(c); while(succp) { - qtest = slcursor_get_case(c); - qtest->qt_result_type = - skygw_query_classifier_get_type(qtest->qt_query_str, f); - succp = slcursor_step_ahead(c); + qtest = slcursor_get_case(c); + qtest->qt_result_type = + skygw_query_classifier_get_type(qtest->qt_query_str, f); + succp = slcursor_step_ahead(c); } /** * Scan through test results and compare them against expected @@ -415,23 +415,23 @@ int main(int argc, char** argv) fprintf(stderr, "\nScanning through the results :\n\n"); while(succp) { - qtest = slcursor_get_case(c); + qtest = slcursor_get_case(c); - if (!query_test_types_match(qtest)) { - nfail += 1; - ss_dfprintf(stderr, - "* Failed: \"%s\" -> %s (Expected %s)\n", - query_test_get_querystr(qtest), - STRQTYPE(query_test_get_result_type(qtest)), - STRQTYPE(query_test_get_query_type(qtest))); - } else { - nsucc += 1; - ss_dfprintf(stderr, - "Succeed\t: \"%s\" -> %s\n", - query_test_get_querystr(qtest), - STRQTYPE(query_test_get_query_type(qtest))); - } - succp = slcursor_step_ahead(c); + if (!query_test_types_match(qtest)) { + nfail += 1; + ss_dfprintf(stderr, + "* Failed: \"%s\" -> %s (Expected %s)\n", + query_test_get_querystr(qtest), + STRQTYPE(query_test_get_result_type(qtest)), + STRQTYPE(query_test_get_query_type(qtest))); + } else { + nsucc += 1; + ss_dfprintf(stderr, + "Succeed\t: \"%s\" -> %s\n", + query_test_get_querystr(qtest), + STRQTYPE(query_test_get_query_type(qtest))); + } + succp = slcursor_step_ahead(c); } fprintf(stderr, "------------------------------------------\n" @@ -448,8 +448,8 @@ int main(int argc, char** argv) mysql = mysql_init(NULL); if (mysql == NULL) { - fprintf(stderr, "mysql_init failed\n"); - goto return_without_server; + fprintf(stderr, "mysql_init failed\n"); + ss_dassert(mysql != NULL); } mysql_options(mysql, @@ -468,50 +468,50 @@ int main(int argc, char** argv) CLIENT_MULTI_STATEMENTS); if (mysql == NULL) { - fprintf(stderr, "mysql_real_connect failed\n"); - goto return_with_handle; + fprintf(stderr, "mysql_real_connect failed\n"); + ss_dassert(mysql != NULL); } fprintf(stderr, "\nRe-execution of selected cases in Embedded server :\n\n"); while(succp) { - qtest = slcursor_get_case(c); + qtest = slcursor_get_case(c); - if (query_test_exec_also_in_server(qtest)) { - MYSQL_RES* results; - MYSQL_ROW record; - const char* query_str; + if (query_test_exec_also_in_server(qtest)) { + MYSQL_RES* results; + MYSQL_ROW record; + const char* query_str; - query_str = query_test_get_querystr(qtest); - failp = mysql_query(mysql, query_str); + query_str = query_test_get_querystr(qtest); + failp = mysql_query(mysql, query_str); - if (failp) { - ss_dfprintf(stderr, - "* Failed: \"%s\" -> %d : %s\n", - query_str, - mysql_errno(mysql), - mysql_error(mysql)); - } else { - ss_dfprintf(stderr, - "Succeed\t: \"%s\"\n", - query_str); - results = mysql_store_result(mysql); + if (failp) { + ss_dfprintf(stderr, + "* Failed: \"%s\" -> %d : %s\n", + query_str, + mysql_errno(mysql), + mysql_error(mysql)); + } else { + ss_dfprintf(stderr, + "Succeed\t: \"%s\"\n", + query_str); + results = mysql_store_result(mysql); - if (results != NULL) { + if (results != NULL) { - while((record = mysql_fetch_row(results))) { - while(record != NULL && *record != NULL) { - ss_dfprintf(stderr, "%s ", *record); - record++; - } - ss_dfprintf(stderr, "\n"); + while((record = mysql_fetch_row(results))) { + while(record != NULL && *record != NULL) { + ss_dfprintf(stderr, "%s ", *record); + record++; + } + ss_dfprintf(stderr, "\n"); + } + mysql_free_result(results); + } } - mysql_free_result(results); - } } - } - succp = slcursor_step_ahead(c); + succp = slcursor_step_ahead(c); } slist_done(c); @@ -525,5 +525,5 @@ return_with_handle: return_without_server: ss_dfprintf(stderr, "\n<< testmain\n"); fflush(stderr); - return 0; + return rc; } diff --git a/server/Makefile b/server/Makefile index 510c15ec6..2ac7ed2be 100644 --- a/server/Makefile +++ b/server/Makefile @@ -34,6 +34,15 @@ all: (cd modules/protocol; touch depend.mk ;make) (cd modules/monitor; touch depend.mk ;make) +cleantests: + $(MAKE) -C test cleantests + +buildtests: + $(MAKE) -C test HAVE_SRV=$(HAVE_SRV) buildtests + +testall: + $(MAKE) -C test HAVE_SRV=$(HAVE_SRV) testall + clean: (cd Documentation; rm -rf html) (cd core; touch depend.mk ; make clean) diff --git a/server/core/Makefile b/server/core/Makefile index 48b657657..226c09a62 100644 --- a/server/core/Makefile +++ b/server/core/Makefile @@ -77,6 +77,18 @@ LIBS=-L../inih/extra -linih -lssl -lstdc++ \ all: maxscale maxkeys maxpasswd +cleantests: + $(MAKE) -C test cleantests + +buildtests: + $(MAKE) -C test buildtests + +runtests: + $(MAKE) -C test runtests + +testall: + $(MAKE) -C test testall + maxscale: $(OBJ) $(CC) $(LDFLAGS) $(OBJ) $(UTILSPATH)/skygw_utils.o $(LIBS) -o $@ diff --git a/server/core/test/makefile b/server/core/test/makefile index 4706de30b..2a2856a13 100644 --- a/server/core/test/makefile +++ b/server/core/test/makefile @@ -1,32 +1,44 @@ +# cleantests - clean local and subdirectories' tests +# buildtests - build all local and subdirectories' tests +# runtests - run all local tests +# testall - clean, build and run local and subdirectories' tests + include ../../../build_gateway.inc include ../../../makefile.inc CC=cc +TESTLOG := $(shell pwd)/testhash.log -clean: +cleantests: - $(DEL) *.o - $(DEL) testhash - $(DEL) *~ -all: - $(MAKE) clean - $(MAKE) buildall - $(MAKE) runall +testall: + $(MAKE) cleantests + $(MAKE) DEBUG=Y buildtests + $(MAKE) runtests -buildall : +buildtests : $(CC) $(CFLAGS) \ -I$(ROOT_PATH)/server/include \ -I$(ROOT_PATH)/utils \ testhash.c ../hashtable.o ../atomic.o ../spinlock.o -o testhash \ -runall: - - @./testhash 0 1 - - @./testhash 10 1 - - @./testhash 1000 10 - - @./testhash 10 0 - - @./testhash 1500 17 - - @./testhash 1 1 - - @./testhash 10000 133 - - @./testhash 1000 1000 - - @./testhash 1000 100000 - +runtests: + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test MaxScale core" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @./testhash 0 1 2>> $(TESTLOG) + @./testhash 10 1 2>> $(TESTLOG) + @./testhash 1000 10 2>> $(TESTLOG) + @./testhash 10 0 2>> $(TESTLOG) + @./testhash 1500 17 2>> $(TESTLOG) + @./testhash 1 1 2>> $(TESTLOG) + @./testhash 10000 133 2>> $(TESTLOG) + @./testhash 1000 1000 2>> $(TESTLOG) + @./testhash 1000 100000 2>> $(TESTLOG) + @echo "MaxScale core PASSED" >> $(TESTLOG) + @echo "" >> $(TESTLOG) diff --git a/server/test/MaxScale_test.cnf b/server/test/MaxScale_test.cnf new file mode 100644 index 000000000..89f65b9a0 --- /dev/null +++ b/server/test/MaxScale_test.cnf @@ -0,0 +1,117 @@ +# +# Example MaxScale.cnf configuration file +# +# +# +# Number of server threads +# Valid options are: +# threads= + +[maxscale] +threads=1 + +# Define a monitor that can be used to determine the state and role of +# the servers. +# +# Valid options are: +# +# module= +# servers=,,... +# user = +# passwd= + +[MySQL Monitor] +type=monitor +module=mysqlmon +servers=server1,server2,server3 +user=maxuser +passwd=maxpwd + +# A series of service definition +# +# Valid options are: +# +# router= +# servers=,,... +# user= +# passwd= +# +# Valid router modules currently are: +# readwritesplit, readconnroute and debugcli + +[RW Split Router] +type=service +router=readwritesplit +servers=server1,server2,server3 +user=maxuser +passwd=maxpwd + +[Read Connection Router] +type=service +router=readconnroute +router_options=slave +servers=server1,server2,server3 +user=maxuser +passwd=maxpwd + +[HTTPD Router] +type=service +router=testroute +servers=server1,server2,server3 + +[Debug Interface] +type=service +router=debugcli + +# Listener definitions for the services +# +# Valid options are: +# +# service= +# protocol= +# port= + +[RW Split Listener] +type=listener +service=RW Split Router +protocol=MySQLClient +port=4006 + +[Read Connection Listener] +type=listener +service=Read Connection Router +protocol=MySQLClient +port=4008 + +[Debug Listener] +type=listener +service=Debug Interface +protocol=telnetd +port=4442 + +[HTTPD Listener] +type=listener +service=HTTPD Router +protocol=HTTPD +port=6444 + +# Definition of the servers + +[server1] +type=server +address=127.0.0.1 +port=3000 +protocol=MySQLBackend + +[server2] +type=server +address=127.0.0.1 +port=3001 +protocol=MySQLBackend + +[server3] +type=server +address=127.0.0.1 +port=3002 +protocol=MySQLBackend diff --git a/server/test/makefile b/server/test/makefile new file mode 100644 index 000000000..e05e1a975 --- /dev/null +++ b/server/test/makefile @@ -0,0 +1,67 @@ +# cleantests - clean local and subdirectories' tests +# buildtests - build all local and subdirectories' tests +# runtests - run all local tests +# testall - clean, build and run local and subdirectories' tests + +include ../../build_gateway.inc +include ../../makefile.inc + +TEST_ROOT := $(ROOT_PATH)/test +PARENT_DIR := $(ROOT_PATH)/server +CUR_DIR := $(PARENT_DIR)/test +export MAXSCALE_HOME=$(CUR_DIR)/MaxScale + +CC=cc +TESTLOG := $(CUR_DIR)/testserver.log + +ifndef $(HAVE_SRV) +HAVE_SRV := N +endif + +cleantests: + - $(DEL) *.o + - $(DEL) *~ +ifeq ($(HAVE_SRV), N) + - $(DEL) Documentation + - $(DEL) bin + - $(DEL) lib + - $(DEL) MaxScale/etc + - $(DEL) MaxScale/modules + - $(DEL) MaxScale/mysql +endif + $(MAKE) -C $(PARENT_DIR)/core cleantests + +testall: + $(MAKE) HAVE_SRV=$(HAVE_SRV) cleantests + $(MAKE) HAVE_SRV=$(HAVE_SRV) buildtests + $(MAKE) runtests + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test Server Core" >> $(TESTLOG) + $(MAKE) -C $(ROOT_PATH)/server/core testall + @echo "Query Classifier PASSED" >> $(TESTLOG) + + +buildtests: +ifeq ($(HAVE_SRV), Y) + @echo "Test server already built" +else + $(MAKE) -C $(ROOT_PATH) buildtestserver +endif + +runtests: + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test MaxScale server" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo "MAXSCALE_HOME="$(MAXSCALE_HOME) >> $(TESTLOG) + cp $(CUR_DIR)/MaxScale_test.cnf $(MAXSCALE_HOME)/etc/MaxScale.cnf + bin/maxscale 2>> $(TESTLOG) + @echo "Put your tests here" + @sleep 5 + @echo "MaxScale server PASSED" >> $(TESTLOG) + @echo "" >> $(TESTLOG) + @killall maxscale + diff --git a/test/README b/test/README new file mode 100644 index 000000000..cb0fbbda5 --- /dev/null +++ b/test/README @@ -0,0 +1,65 @@ +Source tree structure and test targets for make. In a given source directory, +MAXSCALE_HOME/server, for example, there is a test directory which includes +tests for that directory ('local tests') and targets for every subdirectory +of MAXSCALE_HOME/server. + +In the outline below, target, such as 'cleantest' includes instructions for +executing tests or make command pointing to subdirectories. If target is +followed by colon and a list of directory names ('cleantest:log_manager, +query_classifier'), the target is executed locally and in the listed +directories. + +Note : add new tests for any component as close to the actual implementation +as possible. For example, DCB tests in MAXSCALE_HOME/server/core/test instead +of MAXSCALE_HOME/server/test etc. + +MAXSCALE_HOME +| +|- log_manager cleantests, buildtests, runtests, testall +| | +| |- test cleantests, buildtests, runtests, testall +| +|- query_classifier cleantests, buildtests, runtests, testall +| | +| |- test cleantests, buildtests, runtests, testall +| +|- server cleantests, buildtests, testall +| | +| |- core cleantests, buildtests, runtests, testall +| | | +| | |- test cleantests, buildtests, runtests, testall +| | +| |- inih +| | | +| | |- test +| | +| |- modules +| | | +| | |- monitor +| | | +| | |- protocol +| | | +| | |- routing +| | | | +| | | |- readwritesplit +| | +| |- test cleantests:server/core, +| | buildtests, +| | runtests, +| | testall:server/core +| +|- test cleantests:log_manager, query_classifier, server, utils + buildtests:buildtestserver, log_manager, query_classifier, server, utils + runtests: + testall:cleantests, + buildtests, + runtests, + log_manager, + query_classifier, + server, + utils +| +|- utils cleantests, buildtests, runtests, testall +| | +| |- test cleantests, buildtests, runtests, testall +| \ No newline at end of file diff --git a/test/makefile b/test/makefile new file mode 100644 index 000000000..0919d698a --- /dev/null +++ b/test/makefile @@ -0,0 +1,63 @@ +# cleantests - clean local and subdirectories' tests +# buildtests - build all local and subdirectories' tests +# runtests - run all local tests +# testall - clean, build and run local and subdirectories' tests + +include ../build_gateway.inc +include ../makefile.inc + +export MAXSCALE_HOME=$(shell pwd)/MaxScale + +CC=cc +TESTLOG := $(shell pwd)/testmaxscale.log + +testall: + $(MAKE) cleantests + $(MAKE) buildtests + $(MAKE) runtests + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test Log Manager" >> $(TESTLOG) + $(MAKE) -C $(ROOT_PATH)/log_manager testall + @echo "Log Manager PASSED" >> $(TESTLOG) + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test Query Classifier" >> $(TESTLOG) + $(MAKE) -C $(ROOT_PATH)/query_classifier testall + @echo "Query Classifier PASSED" >> $(TESTLOG) + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test MaxScale server" >> $(TESTLOG) + $(MAKE) -C $(ROOT_PATH)/server HAVE_SRV=$(HAVE_SRV) testall + @echo "MaxScale server PASSED" >> $(TESTLOG) + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test utils" >> $(TESTLOG) + $(MAKE) -C $(ROOT_PATH)/utils testall + @echo "Utils PASSED" >> $(TESTLOG) + +cleantests: + $(DEL) *~ + $(MAKE) -C $(ROOT_PATH)/log_manager cleantests + $(MAKE) -C $(ROOT_PATH)/query_classifier cleantests + $(MAKE) -C $(ROOT_PATH)/server cleantests + $(MAKE) -C $(ROOT_PATH)/utils cleantests + +buildtests: + $(MAKE) -C $(ROOT_PATH) buildtestserver + $(MAKE) -C $(ROOT_PATH)/log_manager buildtests + $(MAKE) -C $(ROOT_PATH)/query_classifier buildtests + $(MAKE) -C $(ROOT_PATH)/server HAVE_SRV=$(HAVE_SRV) buildtests + $(MAKE) -C $(ROOT_PATH)/utils buildtests + +runtests: + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test MaxScale root" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo "Nothing to run here so far" >> $(TESTLOG) diff --git a/utils/makefile b/utils/makefile index 267d29bea..a8df09a7f 100644 --- a/utils/makefile +++ b/utils/makefile @@ -16,3 +16,14 @@ all: $(CPP) -c $(CFLAGS) \ -fPIC skygw_utils.cc -o skygw_utils.o +cleantests: + $(MAKE) -C test cleantests + +buildtests: + $(MAKE) -C test DEBUG=Y buildtests + +runtests: + $(MAKE) -C test runtests + +testall: + $(MAKE) -C test testall diff --git a/utils/test/makefile b/utils/test/makefile new file mode 100644 index 000000000..969fb7b35 --- /dev/null +++ b/utils/test/makefile @@ -0,0 +1,30 @@ +# cleantests - clean local and subdirectories' tests +# buildtests - build all local and subdirectories' tests +# runtests - run all local tests +# testall - clean, build and run local and subdirectories' tests + +include ../../build_gateway.inc +include ../../makefile.inc + +CC=cc +TESTLOG := $(shell pwd)/testutils.log + +testall: + $(MAKE) cleantests + $(MAKE) buildtests + $(MAKE) runtests + @echo "No subdirectories to test" >> $(TESTLOG) + +cleantests: + $(DEL) *~ + +buildtests: + @echo "Nothing to build here so far" >> $(TESTLOG) + +runtests: + @echo "" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo $(shell date) >> $(TESTLOG) + @echo "Test Utils" >> $(TESTLOG) + @echo "-------------------------------" >> $(TESTLOG) + @echo "Nothing to run here so far" >> $(TESTLOG)