diff --git a/server/modules/filter/fwfilter.c b/server/modules/filter/fwfilter.c index 2aadec959..67f12209e 100644 --- a/server/modules/filter/fwfilter.c +++ b/server/modules/filter/fwfilter.c @@ -318,12 +318,17 @@ char* strip_tags(char* str) * Parses a string that contains an IP address and converts the last octet to '%'. * This modifies the string passed as the parameter. * @param str String to parse - * @return Pointer to modified string or NULL if an error occurred + * @return Pointer to modified string or NULL if an error occurred or the string can't be made any less specific */ char* next_ip_class(char* str) { assert(str != NULL); + /**The least specific form is reached*/ + if(*str == '%'){ + return NULL; + } + char* ptr = strchr(str,'\0'); if(ptr == NULL){ @@ -346,6 +351,7 @@ char* next_ip_class(char* str) *++ptr = '%'; *++ptr = '\0'; + return str; } /** diff --git a/server/modules/filter/test/CMakeLists.txt b/server/modules/filter/test/CMakeLists.txt index 5a94170c8..6733c10cd 100644 --- a/server/modules/filter/test/CMakeLists.txt +++ b/server/modules/filter/test/CMakeLists.txt @@ -8,8 +8,9 @@ endforeach() include_directories(${CMAKE_CURRENT_SOURCE_DIR}) add_executable(harness_ui harness_ui.c harness_common.c) add_executable(harness harness_util.c harness_common.c ${CORE}) -target_link_libraries(harness_ui fullcore log_manager utils) -target_link_libraries(harness fullcore) +target_link_libraries(harness_ui fullcore log_manager utils ${EMBEDDED_LIB}) +target_link_libraries(harness fullcore ${EMBEDDED_LIB}) +file(COPY ${ERRMSG} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/fwtest.cnf.in ${CMAKE_CURRENT_BINARY_DIR}/fwtest.cnf @ONLY) add_test(TestHintfilter /bin/sh -c "MAXSCALE_HOME=\"${CMAKE_BINARY_DIR}\" ${CMAKE_CURRENT_BINARY_DIR}/harness -i ${CMAKE_CURRENT_SOURCE_DIR}/hint_testing.input -o ${CMAKE_CURRENT_BINARY_DIR}/hint_testing.output -c ${CMAKE_CURRENT_SOURCE_DIR}/hint_testing.cnf -t 1 -s 1 -e ${CMAKE_CURRENT_SOURCE_DIR}/hint_testing.expected") add_test(TestFwfilter /bin/sh -c "MAXSCALE_HOME=\"${CMAKE_BINARY_DIR}\" ${CMAKE_CURRENT_BINARY_DIR}/harness -i ${CMAKE_CURRENT_SOURCE_DIR}/fwtest.input -o ${CMAKE_CURRENT_BINARY_DIR}/fwtest.output -c ${CMAKE_CURRENT_SOURCE_DIR}/fwtest.cnf -t 1 -s 1 -e ${CMAKE_CURRENT_SOURCE_DIR}/fwtest.expected") \ No newline at end of file diff --git a/server/modules/filter/test/fwtest.cnf b/server/modules/filter/test/fwtest.cnf deleted file mode 100644 index ed27b67cd..000000000 --- a/server/modules/filter/test/fwtest.cnf +++ /dev/null @@ -1,159 +0,0 @@ -# -# 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= -# monitor_interval= - -[MySQL Monitor] -type=monitor -module=mysqlmon -servers=server1,server2,server3,server4 -user=maxuser -passwd=maxpwd - -# A series of service definition -# -# Valid options are: -# -# router= -# servers=,,... -# user= -# passwd= -# enable_root_user=<0 or 1, default is 0> -# version_string= -# -# Valid router modules currently are: -# readwritesplit, readconnroute and debugcli - - -[RW Split Router] -type=service -router=readwritesplit -servers=server1,server2,server3,server4 -max_slave_connections=90% -user=maxuser -passwd=maxpwd -#filters=MQ - -[RW Split Hint Router] -type=service -router=readwritesplit -servers=server1,server2,server3,server4 -max_slave_connections=90% -user=maxuser -passwd=maxpwd -filters=Hint - - -[Read Connection Router] -type=service -router=readconnroute -router_options=master -servers=server1 -user=maxuser -passwd=maxpwd - - -[HTTPD Router] -type=service -router=testroute -servers=server1,server2,server3 - -[Debug Interface] -type=service -router=debugcli - - -[Hint] -type=filter -module=fwfilter -rules=@CMAKE_CURRENT_BINARY_DIR@/rules - - -# Listener definitions for the services -# -# Valid options are: -# -# service= -# protocol= -# port= -# address=
-# socket= - -[RW Split Listener] -type=listener -service=RW Split Router -protocol=MySQLClient -port=4006 - -[RW Split Hint Listener] -type=listener -service=RW Split Hint Router -protocol=MySQLClient -port=4009 - -[Read Connection Listener] -type=listener -service=Read Connection Router -protocol=MySQLClient -port=4008 -#socket=/tmp/readconn.sock - -[Debug Listener] -type=listener -service=Debug Interface -protocol=telnetd -port=4442 -#address=127.0.0.1 - -[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 - -[server4] -type=server -address=127.0.0.1 -port=3003 -protocol=MySQLBackend diff --git a/server/modules/filter/test/fwtest.cnf.in b/server/modules/filter/test/fwtest.cnf.in index ef1623c8b..13a1504b9 100644 --- a/server/modules/filter/test/fwtest.cnf.in +++ b/server/modules/filter/test/fwtest.cnf.in @@ -1,159 +1,4 @@ -# -# 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= -# monitor_interval= - -[MySQL Monitor] -type=monitor -module=mysqlmon -servers=server1,server2,server3,server4 -user=maxuser -passwd=maxpwd - -# A series of service definition -# -# Valid options are: -# -# router= -# servers=,,... -# user= -# passwd= -# enable_root_user=<0 or 1, default is 0> -# version_string= -# -# Valid router modules currently are: -# readwritesplit, readconnroute and debugcli - - -[RW Split Router] -type=service -router=readwritesplit -servers=server1,server2,server3,server4 -max_slave_connections=90% -user=maxuser -passwd=maxpwd -#filters=MQ - -[RW Split Hint Router] -type=service -router=readwritesplit -servers=server1,server2,server3,server4 -max_slave_connections=90% -user=maxuser -passwd=maxpwd -filters=Hint - - -[Read Connection Router] -type=service -router=readconnroute -router_options=master -servers=server1 -user=maxuser -passwd=maxpwd - - -[HTTPD Router] -type=service -router=testroute -servers=server1,server2,server3 - -[Debug Interface] -type=service -router=debugcli - - -[Hint] +[Firewall] type=filter module=fwfilter rules=@CMAKE_CURRENT_SOURCE_DIR@/rules - - -# Listener definitions for the services -# -# Valid options are: -# -# service= -# protocol= -# port= -# address=
-# socket= - -[RW Split Listener] -type=listener -service=RW Split Router -protocol=MySQLClient -port=4006 - -[RW Split Hint Listener] -type=listener -service=RW Split Hint Router -protocol=MySQLClient -port=4009 - -[Read Connection Listener] -type=listener -service=Read Connection Router -protocol=MySQLClient -port=4008 -#socket=/tmp/readconn.sock - -[Debug Listener] -type=listener -service=Debug Interface -protocol=telnetd -port=4442 -#address=127.0.0.1 - -[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 - -[server4] -type=server -address=127.0.0.1 -port=3003 -protocol=MySQLBackend diff --git a/server/modules/filter/test/fwtest.output b/server/modules/filter/test/fwtest.output new file mode 100755 index 000000000..a6e8ee1de --- /dev/null +++ b/server/modules/filter/test/fwtest.output @@ -0,0 +1,4 @@ +select 1; +select 1; +select 1; +select 1; diff --git a/server/modules/filter/test/harness.h b/server/modules/filter/test/harness.h index ac3982d19..85713d07a 100644 --- a/server/modules/filter/test/harness.h +++ b/server/modules/filter/test/harness.h @@ -69,7 +69,9 @@ #include #include #include +#include #include + /** * A single name-value pair and a link to the next item in the * configuration. @@ -118,6 +120,7 @@ typedef struct int running; int verbose; /**Whether to print to stdout*/ int infile; /**A file where the queries are loaded from*/ + int expected; int error; char* mod_dir; /**Module directory absolute path*/ char* infile_name; @@ -174,7 +177,7 @@ typedef packet_t PACKET; /** * Initialize the static instance. */ -int harness_init(int argc,char** argv); +int harness_init(int argc,char** argv,HARNESS_INSTANCE** inst); /** * Frees all the query buffers @@ -361,4 +364,14 @@ GWBUF* gen_packet(PACKET pkt); */ int process_opts(int argc, char** argv); +/** + * Compares the contents of two files. + * This function resets the offsets of the file descriptors and leaves them in an + * undefined state. + * @param a The first file + * @param b The second file + * @return 0 if the files do not differ and 1 if they do or an error occurred. + */ +int compare_files(int a, int b); + #endif diff --git a/server/modules/filter/test/harness_common.c b/server/modules/filter/test/harness_common.c index 0a853bae0..6efa31992 100644 --- a/server/modules/filter/test/harness_common.c +++ b/server/modules/filter/test/harness_common.c @@ -1,12 +1,15 @@ #include + int dcbfun(struct dcb* dcb, GWBUF * buffer) { printf("Data was written to client DCB.\n"); return 1; } -int harness_init(int argc, char** argv){ +int harness_init(int argc, char** argv, HARNESS_INSTANCE** inst){ + + int i = 0; if(!(argc == 2 && strcmp(argv[1],"-h") == 0)){ skygw_logmanager_init(0,NULL); @@ -20,9 +23,11 @@ int harness_init(int argc, char** argv){ return 1; } + *inst = &instance; instance.running = 1; instance.infile = -1; instance.outfile = -1; + instance.expected = -1; instance.buff_ind = -1; instance.last_ind = -1; instance.sess_ind = -1; @@ -33,7 +38,10 @@ int harness_init(int argc, char** argv){ sprintf(mysqlsess->user,"dummyuser"); sprintf(mysqlsess->db,"dummydb"); dcb->func.write = dcbfun; + dcb->remote = strdup("0.0.0.0"); + dcb->user = strdup("user"); instance.session->client = (void*)dcb; + instance.session->data = (void*)mysqlsess; process_opts(argc,argv); @@ -98,15 +106,17 @@ void free_buffers() } int open_file(char* str, unsigned int write) { - int mode; + int mode,fd; if(write){ mode = O_RDWR|O_CREAT; }else{ mode = O_RDONLY; } - - return open(str,mode,S_IRWXU|S_IRGRP|S_IXGRP|S_IXOTH); + if((fd = open(str,mode,S_IRWXU|S_IRGRP|S_IXGRP|S_IXOTH)) < 0){ + printf("Error %d: %s\n",errno,strerror(errno)); + } + return fd; } @@ -622,6 +632,8 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf) { FILTER_PARAMETER** fparams = NULL; int i, paramc = -1; + int sess_err = 0; + int x; if(cnf == NULL){ fparams = read_params(¶mc); @@ -686,13 +698,16 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf) } } - int sess_err = 0; if(cnf && fc && fc->instance){ fc->filter = (FILTER*)fc->instance->createInstance(NULL,fparams); - + if(fc->filter == NULL){ + printf("Error loading filter:%s: createInstance returned NULL.\n",fc->name); + sess_err = 1; + goto error; + } for(i = 0;isession[i] = fc->instance->newSession(fc->filter, instance.session)) && @@ -760,8 +775,8 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf) } } - - int x; + error: + if(fparams){ for(x = 0;xinstance->routeQuery(instance.head->filter, + if(instance.head->instance->routeQuery(instance.head->filter, instance.head->session[index], - instance.buffer[instance.buff_ind]); + instance.buffer[instance.buff_ind]) == 0){ + if(instance.outfile > 0){ + const char* msg = "Query returned 0.\n"; + write(instance.outfile,msg,strlen(msg)); + } + } if(instance.tail->instance->clientReply){ instance.tail->instance->clientReply(instance.tail->filter, instance.tail->session[index], @@ -946,7 +966,7 @@ GWBUF* gen_packet(PACKET pkt) int process_opts(int argc, char** argv) { int fd, buffsize = 1024; - int rd,rdsz, rval; + int rd,rdsz, rval = 0; size_t fsize; char *buff = calloc(buffsize,sizeof(char)), *tok = NULL; @@ -999,10 +1019,18 @@ int process_opts(int argc, char** argv) close(fd); return 1; } + char* conf_name = NULL; - while((rd = getopt(argc,argv,"m:c:i:o:s:t:d:qh")) > 0){ + rval = 0; + + while((rd = getopt(argc,argv,"e:m:c:i:o:s:t:d:qh")) > 0){ switch(rd){ + case 'e': + instance.expected = open_file(optarg,0); + printf("Expected output is read from: %s\n",optarg); + break; + case 'o': instance.outfile = open_file(optarg,1); printf("Output is written to: %s\n",optarg); @@ -1067,6 +1095,7 @@ int process_opts(int argc, char** argv) } } printf("\n"); + if(conf_name && load_config(conf_name)){ load_query(); }else{ @@ -1075,5 +1104,30 @@ int process_opts(int argc, char** argv) free(conf_name); close(fd); + return rval; +} + +int compare_files(int a,int b) +{ + char in[4098]; + char exp[4098]; + int line = 1; + + if(a < 1 || b < 1){ + return 1; + } + + if(lseek(a,0,SEEK_SET) < 0 || + lseek(b,0,SEEK_SET) < 0){ + return 1; + } + + while(fdgets(a,in,4098) && fdgets(b,exp,4098)){ + if(strcmp(in,exp)){ + printf("The files differ at line %d:\n%s\n-------------------------------------\n%s\n",line,in,exp); + return 1; + } + line++; + } return 0; } diff --git a/server/modules/filter/test/harness_util.c b/server/modules/filter/test/harness_util.c index 705bc3c3b..04b7e1b9b 100644 --- a/server/modules/filter/test/harness_util.c +++ b/server/modules/filter/test/harness_util.c @@ -1,7 +1,37 @@ +#include +#include #include + int main(int argc,char** argv) { + + static char* server_options[] = { + "MariaDB Corporation MaxScale", + "--datadir=./", + "--language=./", + "--skip-innodb", + "--default-storage-engine=myisam", + NULL + }; + + const int num_elements = (sizeof(server_options) / sizeof(char *)) - 1; + + static char* server_groups[] = { + "embedded", + "server", + "server", + NULL + }; + + HARNESS_INSTANCE* inst; + + if(mysql_library_init(num_elements, server_options, server_groups)){ + printf("Embedded server init failed.\n"); + return 1; + } + + if(harness_init(argc,argv,&inst) || inst->error){ printf("Error: Initialization failed.\n"); skygw_log_write(LOGFILE_ERROR,"Error: Initialization failed.\n"); diff --git a/server/modules/filter/test/rules b/server/modules/filter/test/rules index 8e6c4ab3c..a75ecb666 100644 --- a/server/modules/filter/test/rules +++ b/server/modules/filter/test/rules @@ -1,3 +1,3 @@ rule union_regex deny regex '.*union.*' -rule dont_delete_everything deny no_where_clause on_operations delete|update at_times 12:00:00-18:00:00 +rule dont_delete_everything deny no_where_clause on_operations delete|update users %@% match any rules union_regex dont_delete_everything \ No newline at end of file