documentation for the filter testing harness
This commit is contained in:
@ -54,11 +54,11 @@ build:$(OBJ)
|
||||
$(CC) $(CFLAGS) $< -o $@
|
||||
|
||||
clean:
|
||||
-rm -f *.o
|
||||
-rm -f *.so
|
||||
-rm -f harness
|
||||
rm -f *.o
|
||||
rm -f *.so
|
||||
rm -f harness
|
||||
cleantests:clean
|
||||
-rm *.output
|
||||
rm *.output
|
||||
buildtests:build
|
||||
|
||||
testall:
|
||||
@ -75,3 +75,6 @@ runtests:
|
||||
@echo "Testing hints... "
|
||||
@./hint_tests.sh
|
||||
@echo ""
|
||||
|
||||
documentation:
|
||||
doxygen doxygen.conf
|
||||
|
@ -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>
|
||||
|
||||
int main(int argc, char** argv){
|
||||
@ -324,9 +273,7 @@ int main(int argc, char** argv){
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* Frees all the loaded filters
|
||||
*/
|
||||
|
||||
|
||||
void free_filters()
|
||||
{
|
||||
@ -352,9 +299,6 @@ void free_filters()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees all the query buffers
|
||||
*/
|
||||
void free_buffers()
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
||||
@ -452,9 +391,7 @@ operation_t user_input(char* tk)
|
||||
return UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
*Prints a list of available commands.
|
||||
*/
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
char buffer[256];
|
||||
@ -560,12 +486,7 @@ FILTER_PARAMETER** read_params(int* paramc)
|
||||
*paramc = pc;
|
||||
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)
|
||||
{
|
||||
|
||||
@ -649,12 +570,7 @@ int routeQuery(void* ins, void* session, GWBUF* queue)
|
||||
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)
|
||||
{
|
||||
|
||||
@ -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()
|
||||
{
|
||||
char** query_list;
|
||||
@ -816,16 +729,7 @@ int load_query()
|
||||
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,
|
||||
const char* value)
|
||||
{
|
||||
@ -886,13 +790,7 @@ static int handler(void* user, const char* section, const char* name,
|
||||
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* tmp;
|
||||
@ -926,12 +824,7 @@ CONFIG* process_config(CONFIG* conf)
|
||||
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)
|
||||
{
|
||||
@ -1028,17 +921,6 @@ int load_config( char* fname)
|
||||
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)
|
||||
{
|
||||
FILTER_PARAMETER** fparams;
|
||||
@ -1194,15 +1076,7 @@ int load_filter(FILTERCHAIN* fc, CONFIG* cnf)
|
||||
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* flt_ptr = NULL;
|
||||
@ -1225,10 +1099,7 @@ FILTERCHAIN* load_filter_module(char* str)
|
||||
return flt_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the current status of loaded filters and queries, number of threads
|
||||
* and sessions and possible output files.
|
||||
*/
|
||||
|
||||
void print_status()
|
||||
{
|
||||
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()
|
||||
{
|
||||
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)
|
||||
{
|
||||
unsigned int index = instance.session_count;
|
||||
@ -1362,14 +1225,7 @@ void work_buffer(void* thr_num)
|
||||
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)
|
||||
{
|
||||
unsigned int psize = 0;
|
||||
@ -1418,37 +1274,7 @@ GWBUF* gen_packet(PACKET pkt)
|
||||
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 fd = open_file("harness.cnf",1), buffsize = 1024;
|
||||
|
@ -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
|
||||
* 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.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* Date Who Description
|
||||
@ -36,6 +52,7 @@
|
||||
* @endverbatim
|
||||
*/
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -150,24 +167,189 @@ typedef enum
|
||||
|
||||
typedef packet_t PACKET;
|
||||
|
||||
/**
|
||||
* Frees all the query buffers
|
||||
*/
|
||||
void free_buffers();
|
||||
|
||||
/**
|
||||
* Frees all the loaded 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();
|
||||
|
||||
/**
|
||||
* Prints the current status of loaded filters and queries, number of threads
|
||||
* and sessions and possible output files.
|
||||
*/
|
||||
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);
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
*Loads the file pointed by @{instance.infile}
|
||||
* @return Zero if successful, non-zero if an error occurred
|
||||
*/
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
/**
|
||||
* Initializes the indexes used while routing buffers and prints the progress
|
||||
* of the routing process.
|
||||
*/
|
||||
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);
|
||||
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user