documentation for the filter testing harness

This commit is contained in:
Markus Makela
2014-08-15 14:11:55 +03:00
parent 7401c8b1d2
commit b04dc8e4d7
3 changed files with 214 additions and 203 deletions

View File

@ -54,11 +54,11 @@ build:$(OBJ)
$(CC) $(CFLAGS) $< -o $@ $(CC) $(CFLAGS) $< -o $@
clean: clean:
-rm -f *.o rm -f *.o
-rm -f *.so rm -f *.so
-rm -f harness rm -f harness
cleantests:clean cleantests:clean
-rm *.output rm *.output
buildtests:build buildtests:build
testall: testall:
@ -75,3 +75,6 @@ runtests:
@echo "Testing hints... " @echo "Testing hints... "
@./hint_tests.sh @./hint_tests.sh
@echo "" @echo ""
documentation:
doxygen doxygen.conf

View File

@ -1,54 +1,3 @@
/*
* This file is distributed as part of the SkySQL Gateway. 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 2013
*/
/**
* @file harness.h Test harness for independent testing of filters
*
* A test harness that feeds a GWBUF to a chain of filters and prints the results
* either into a file or to the standard output.
*
* The contents of the GWBUF and the filter parameters are either manually set through
* the command line or read from a file.
*
* Options for the configuration file 'harness.cnf'':
*
* threads Number of threads to use when routing buffers
* sessions Number of sessions
*
* Options for the command line:
*
* -c Path to the MaxScale configuration file to parse for filters
* -i Name of the input file for buffers
* -o Name of the output file for results
* -q Suppress printing to stdout
* -s Number of sessions
* -t Number of threads
* -d Routing delay
*
* @verbatim
* Revision History
*
* Date Who Description
* 01/07/14 Markus Makela Initial implementation
*
* @endverbatim
*/
#include <harness.h> #include <harness.h>
int main(int argc, char** argv){ int main(int argc, char** argv){
@ -324,9 +273,7 @@ int main(int argc, char** argv){
return 0; return 0;
} }
/**
* Frees all the loaded filters
*/
void free_filters() void free_filters()
{ {
@ -352,9 +299,6 @@ void free_filters()
} }
} }
/**
* Frees all the query buffers
*/
void free_buffers() void free_buffers()
{ {
if(instance.buffer){ if(instance.buffer){
@ -375,12 +319,7 @@ void free_buffers()
} }
} }
/**
* Converts the passed string into an operation
*
* @param tk The string to parse
* @return The operation to perform or UNDEFINED, if parsing failed
*/
operation_t user_input(char* tk) operation_t user_input(char* tk)
{ {
@ -452,9 +391,7 @@ operation_t user_input(char* tk)
return UNDEFINED; return UNDEFINED;
} }
/**
*Prints a list of available commands.
*/
void print_help() void print_help()
{ {
@ -477,13 +414,7 @@ void print_help()
} }
/**
*Opens a file for reading and/or writing with adequate permissions.
*
* @param str Path to file
* @param write Non-zero for write permissions, zero for read only.
* @return The assigned file descriptor or -1 in case an error occurred
*/
int open_file(char* str, unsigned int write) int open_file(char* str, unsigned int write)
{ {
int mode; int mode;
@ -497,12 +428,7 @@ int open_file(char* str, unsigned int write)
return open(str,mode,S_IRWXU|S_IRGRP|S_IXGRP|S_IXOTH); return open(str,mode,S_IRWXU|S_IRGRP|S_IXGRP|S_IXOTH);
} }
/**
* Reads filter parameters from the command line as name-value pairs.
*
*@param paramc The number of parameters read is assigned to this variable
*@return The newly allocated list of parameters with the last one being NULL
*/
FILTER_PARAMETER** read_params(int* paramc) FILTER_PARAMETER** read_params(int* paramc)
{ {
char buffer[256]; char buffer[256];
@ -560,12 +486,7 @@ FILTER_PARAMETER** read_params(int* paramc)
*paramc = pc; *paramc = pc;
return params; return params;
} }
/**
* Dummy endpoint for the queries of the filter chain
*
* Prints and logs the contents of the GWBUF after it has passed through all the filters.
* The packet is handled as a COM_QUERY packet and the packet header is not printed.
*/
int routeQuery(void* ins, void* session, GWBUF* queue) int routeQuery(void* ins, void* session, GWBUF* queue)
{ {
@ -649,12 +570,7 @@ int routeQuery(void* ins, void* session, GWBUF* queue)
return 1; return 1;
} }
/**
* Dummy endpoint for the replies of the filter chain
*
* Prints and logs the contents of the GWBUF after it has passed through all the filters.
* The packet is handled as a OK packet with no message and the packet header is not printed.
*/
int clientReply(void* ins, void* session, GWBUF* queue) int clientReply(void* ins, void* session, GWBUF* queue)
{ {
@ -713,10 +629,7 @@ void manual_query()
} }
/**
*Loads the file pointed by @{instance.infile}
* @return Zero if successful, non-zero if an error occurred
*/
int load_query() int load_query()
{ {
char** query_list; char** query_list;
@ -816,16 +729,7 @@ int load_query()
return 0; return 0;
} }
/**
* Handler for the INI file parser that builds a linked list
* of all the sections and their name-value pairs.
* @param user Current configuration.
* @param section Name of the section.
* @param name Name of the item.
* @param value Value of the item.
* @return Non-zero on success, zero in case parsing is finished.
* @see load_config()
*/
static int handler(void* user, const char* section, const char* name, static int handler(void* user, const char* section, const char* name,
const char* value) const char* value)
{ {
@ -886,13 +790,7 @@ static int handler(void* user, const char* section, const char* name,
return 1; return 1;
} }
/**
* Removes all non-filter modules from the configuration
*
* @param conf A pointer to a configuration struct
* @return The stripped version of the configuration
* @see load_config()
*/
CONFIG* process_config(CONFIG* conf) CONFIG* process_config(CONFIG* conf)
{ {
CONFIG* tmp; CONFIG* tmp;
@ -926,12 +824,7 @@ CONFIG* process_config(CONFIG* conf)
return head; return head;
} }
/**
* Reads a MaxScale configuration (or any INI file using MaxScale notation) file and loads only the filter modules in it.
*
* @param fname Configuration file name
* @return Non-zero on success, zero in case an error occurred.
*/
int load_config( char* fname) int load_config( char* fname)
{ {
@ -1028,17 +921,6 @@ int load_config( char* fname)
return config_ok; return config_ok;
} }
/**
* Loads a new instance of a filter and starts a new session.
* This function assumes that the filter module is already loaded.
* Passing NULL as the CONFIG parameter causes the parameters to be
* read from the command line one at a time.
*
* @param fc The FILTERCHAIN where the new instance and session are created
* @param cnf A configuration read from a file
* @return 1 on success, 0 in case an error occurred
* @see load_filter_module()
*/
int load_filter(FILTERCHAIN* fc, CONFIG* cnf) int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
{ {
FILTER_PARAMETER** fparams; FILTER_PARAMETER** fparams;
@ -1194,15 +1076,7 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
return sess_err ? 0 : 1; return sess_err ? 0 : 1;
} }
/**
* Loads the filter module and link it to the filter chain
*
* The downstream is set to point to the current head of the filter chain
*
* @param str Name of the filter module
* @return Pointer to the newly initialized FILTER_CHAIN element or NULL in case module loading failed
* @see load_filter()
*/
FILTERCHAIN* load_filter_module(char* str) FILTERCHAIN* load_filter_module(char* str)
{ {
FILTERCHAIN* flt_ptr = NULL; FILTERCHAIN* flt_ptr = NULL;
@ -1225,10 +1099,7 @@ FILTERCHAIN* load_filter_module(char* str)
return flt_ptr; return flt_ptr;
} }
/**
* Prints the current status of loaded filters and queries, number of threads
* and sessions and possible output files.
*/
void print_status() void print_status()
{ {
if(instance.head->filter){ if(instance.head->filter){
@ -1262,10 +1133,7 @@ void print_status()
} }
/**
* Initializes the indexes used while routing buffers and prints the progress
* of the routing process.
*/
void route_buffers() void route_buffers()
{ {
if(instance.buffer_count > 0){ if(instance.buffer_count > 0){
@ -1325,12 +1193,7 @@ void route_buffers()
} }
/**
* Worker function for threads.
* Routes a query buffer if there are unrouted buffers left.
*
* @param thr_num ID number of the thread
*/
void work_buffer(void* thr_num) void work_buffer(void* thr_num)
{ {
unsigned int index = instance.session_count; unsigned int index = instance.session_count;
@ -1362,14 +1225,7 @@ void work_buffer(void* thr_num)
gwbuf_free(fake_ok); gwbuf_free(fake_ok);
} }
/**
* Generates a fake packet used to emulate a response from the backend.
*
* Current implementation only works with PACKET_OK and the packet has no message.
* The caller is responsible for freeing the allocated memory by calling gwbuf_free().
* @param pkt The packet type
* @return The newly generated packet or NULL if an error occurred
*/
GWBUF* gen_packet(PACKET pkt) GWBUF* gen_packet(PACKET pkt)
{ {
unsigned int psize = 0; unsigned int psize = 0;
@ -1418,37 +1274,7 @@ GWBUF* gen_packet(PACKET pkt)
return buff; return buff;
} }
/**
* Process the command line parameters and the harness configuration file.
*
* Reads the contents of the 'harness.cnf' file and command line parameters
* and parses them. Options are interpreted accoding to the following table.
* If no command line arguments are given, interactive mode is used.
*
* By default if no input file is given or no configuration file or specific
* filters are given, but other options are, the program exits with 0.
*
* Options for the configuration file 'harness.cnf'':
*
* threads Number of threads to use when routing buffers
* sessions Number of sessions
*
* Options for the command line:
*
* -h Display this information
* -c Path to the MaxScale configuration file to parse for filters
* -i Name of the input file for buffers
* -o Name of the output file for results
* -q Suppress printing to stdout
* -t Number of threads
* -s Number of sessions
* -d Routing delay
*
* @param argc Number of arguments
* @param argv List of argument strings
* @return 1 if successful, 0 if no input file, configuration file or specific
* filters are given, but other options are, or if an error occurs.
*/
int process_opts(int argc, char** argv) int process_opts(int argc, char** argv)
{ {
int fd = open_file("harness.cnf",1), buffsize = 1024; int fd = open_file("harness.cnf",1), buffsize = 1024;

View File

@ -19,15 +19,31 @@
*/ */
/** /**
* @file harness.h Test harness for independent testing of filters * @mainpage
* Test harness for independent testing of filters
* *
* A test harness that feeds a GWBUF to a chain of filters and prints the results * A test harness that feeds a GWBUF to a chain of filters and prints the results
* either into a file or to the standard output. * either into a file or to the standard output.
* *
* The contents of the GWBUF and the filter parameters are either manually set through * The contents of the GWBUF and the filter parameters are either manually set through
* the command line or read from a file. * the command line or read from a file.
*
* @verbatim * @verbatim
* Options for the configuration file 'harness.cnf'':
*
* threads Number of threads to use when routing buffers
* sessions Number of sessions
*
* Options for the command line:
*
* -c Path to the MaxScale configuration file to parse for filters
* -i Name of the input file for buffers
* -o Name of the output file for results
* -q Suppress printing to stdout
* -s Number of sessions
* -t Number of threads
* -d Routing delay, in milliseconds
*
*
* Revision History * Revision History
* *
* Date Who Description * Date Who Description
@ -36,6 +52,7 @@
* @endverbatim * @endverbatim
*/ */
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -150,24 +167,189 @@ typedef enum
typedef packet_t PACKET; typedef packet_t PACKET;
/**
* Frees all the query buffers
*/
void free_buffers(); void free_buffers();
/**
* Frees all the loaded filters
*/
void free_filters(); void free_filters();
operation_t user_input(char*);
/**
* Converts the passed string into an operation
*
* @param tk The string to parse
* @return The operation to perform or UNDEFINED, if parsing failed
*/
operation_t user_input(char* tk);
/**
*Prints a list of available commands.
*/
void print_help(); void print_help();
/**
* Prints the current status of loaded filters and queries, number of threads
* and sessions and possible output files.
*/
void print_status(); void print_status();
/**
*Opens a file for reading and/or writing with adequate permissions.
*
* @param str Path to file
* @param write Non-zero for write permissions, zero for read only.
* @return The assigned file descriptor or -1 in case an error occurred
*/
int open_file(char* str, unsigned int write); int open_file(char* str, unsigned int write);
FILTER_PARAMETER** read_params(int*);
/**
* Reads filter parameters from the command line as name-value pairs.
*
*@param paramc The number of parameters read is assigned to this variable
*@return The newly allocated list of parameters with the last one being NULL
*/
FILTER_PARAMETER** read_params(int* paramc);
/**
* Dummy endpoint for the queries of the filter chain
*
* Prints and logs the contents of the GWBUF after it has passed through all the filters.
* The packet is handled as a COM_QUERY packet and the packet header is not printed.
*/
int routeQuery(void* instance, void* session, GWBUF* queue); int routeQuery(void* instance, void* session, GWBUF* queue);
/**
* Dummy endpoint for the replies of the filter chain
*
* Prints and logs the contents of the GWBUF after it has passed through all the filters.
* The packet is handled as a OK packet with no message and the packet header is not printed.
*/
int clientReply(void* ins, void* session, GWBUF* queue);
/**
*Manual input if a query string
*
* Reads a single query from the standard input and inserts it into a GWBUF.
*/
void manual_query(); void manual_query();
/**
*Loads the file pointed by @{instance.infile}
* @return Zero if successful, non-zero if an error occurred
*/
int load_query(); int load_query();
/**
* Handler for the INI file parser that builds a linked list
* of all the sections and their name-value pairs.
* @param user Current configuration.
* @param section Name of the section.
* @param name Name of the item.
* @param value Value of the item.
* @return Non-zero on success, zero in case parsing is finished.
* @see load_config()
*/
static int handler(void* user, const char* section, const char* name,const char* value); static int handler(void* user, const char* section, const char* name,const char* value);
CONFIG* process_config(CONFIG*);
/**
* Removes all non-filter modules from the configuration
*
* @param conf A pointer to a configuration struct
* @return The stripped version of the configuration
* @see load_config()
*/
CONFIG* process_config(CONFIG* conf);
/**
* Loads the filter module and link it to the filter chain
*
* The downstream is set to point to the current head of the filter chain
*
* @param str Name of the filter module
* @return Pointer to the newly initialized FILTER_CHAIN element or NULL in case module loading failed
* @see load_filter()
*/
FILTERCHAIN* load_filter_module(char* str); FILTERCHAIN* load_filter_module(char* str);
int load_filter(FILTERCHAIN*, CONFIG*);
/**
* Loads a new instance of a filter and starts a new session.
* This function assumes that the filter module is already loaded.
* Passing NULL as the CONFIG parameter causes the parameters to be
* read from the command line one at a time.
*
* @param fc The FILTERCHAIN where the new instance and session are created
* @param cnf A configuration read from a file
* @return 1 on success, 0 in case an error occurred
* @see load_filter_module()
*/
int load_filter(FILTERCHAIN* fc, CONFIG* cnf);
/**
* Reads a MaxScale configuration (or any INI file using MaxScale notation) file and loads only the filter modules in it.
*
* @param fname Configuration file name
* @return Non-zero on success, zero in case an error occurred.
*/
int load_config(char* fname); int load_config(char* fname);
/**
* Initializes the indexes used while routing buffers and prints the progress
* of the routing process.
*/
void route_buffers(); void route_buffers();
void work_buffer(void*);
GWBUF* gen_packet(PACKET); /**
* Worker function for threads.
* Routes a query buffer if there are unrouted buffers left.
*
* @param thr_num ID number of the thread
*/
void work_buffer(void* thr_num);
/**
* Generates a fake packet used to emulate a response from the backend.
*
* Current implementation only works with PACKET_OK and the packet has no message.
* The caller is responsible for freeing the allocated memory by calling gwbuf_free().
* @param pkt The packet type
* @return The newly generated packet or NULL if an error occurred
*/
GWBUF* gen_packet(PACKET pkt);
/**
* Process the command line parameters and the harness configuration file.
*
* Reads the contents of the 'harness.cnf' file and command line parameters
* and parses them. Options are interpreted accoding to the following table.
* If no command line arguments are given, interactive mode is used.
*
* By default if no input file is given or no configuration file or specific
* filters are given, but other options are, the program exits with 0.
*
* Options for the configuration file 'harness.cnf'':
*
* threads Number of threads to use when routing buffers
* sessions Number of sessions
*
* Options for the command line:
*
* -h Display this information
* -c Path to the MaxScale configuration file to parse for filters
* -i Name of the input file for buffers
* -o Name of the output file for results
* -q Suppress printing to stdout
* -t Number of threads
* -s Number of sessions
* -d Routing delay
*
* @param argc Number of arguments
* @param argv List of argument strings
* @return 1 if successful, 0 if no input file, configuration file or specific
* filters are given, but other options are, or if an error occurs.
*/
int process_opts(int argc, char** argv); int process_opts(int argc, char** argv);
#endif #endif