summaryrefslogtreecommitdiff
path: root/mysql-test/mysql_test_run.c
diff options
context:
space:
mode:
authorunknown <wax@mysql.com>2004-09-16 00:53:06 +0600
committerunknown <wax@mysql.com>2004-09-16 00:53:06 +0600
commit716e3a577c59e4b8a38270c02a69f0492f79c685 (patch)
tree4c49aa2bccbc1f7d9c2f7963062c4179b706334d /mysql-test/mysql_test_run.c
parentdd343eb8d046ebe57a1c346816b9b29b85aa8c07 (diff)
parent931f6da62289ae841e0ed599a787bb3c8569adc3 (diff)
downloadmariadb-git-716e3a577c59e4b8a38270c02a69f0492f79c685.tar.gz
Merge mysql.com:/home/wax/mysql/mysql-4.1
into mysql.com:/home/wax/mysql/mysql-4.1mysqltest mysql-test/t/variables.test: Auto merged
Diffstat (limited to 'mysql-test/mysql_test_run.c')
-rw-r--r--mysql-test/mysql_test_run.c1728
1 files changed, 1728 insertions, 0 deletions
diff --git a/mysql-test/mysql_test_run.c b/mysql-test/mysql_test_run.c
new file mode 100644
index 00000000000..6f388fc4a45
--- /dev/null
+++ b/mysql-test/mysql_test_run.c
@@ -0,0 +1,1728 @@
+/*
+ Copyright (c) 2002, 2003 Novell, Inc. All Rights Reserved.
+
+ This program 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; either version 2 of the License, or
+ (at your option) any later version.
+
+ 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#ifndef __WIN__
+#include <dirent.h>
+#endif
+#include <string.h>
+#ifdef __NETWARE__
+#include <screen.h>
+#include <nks/vm.h>
+#endif
+#include <ctype.h>
+#include <sys/stat.h>
+#ifndef __WIN__
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#ifdef __NETWARE__
+#include <sys/mode.h>
+#endif
+#ifdef __WIN__
+#include <Shlwapi.h>
+#include <direct.h>
+#endif
+
+#include "my_manage.h"
+
+/******************************************************************************
+
+ macros
+
+******************************************************************************/
+
+#define HEADER "TEST RESULT \n"
+#define DASH "-------------------------------------------------------\n"
+
+#define NW_TEST_SUFFIX ".nw-test"
+#define NW_RESULT_SUFFIX ".nw-result"
+#define TEST_SUFFIX ".test"
+#define RESULT_SUFFIX ".result"
+#define REJECT_SUFFIX ".reject"
+#define OUT_SUFFIX ".out"
+#define ERR_SUFFIX ".err"
+
+const char *TEST_PASS = "[ pass ]";
+const char *TEST_SKIP = "[ skip ]";
+const char *TEST_FAIL = "[ fail ]";
+const char *TEST_BAD = "[ bad ]";
+const char *TEST_IGNORE = "[ignore]";
+
+/******************************************************************************
+
+ global variables
+
+******************************************************************************/
+#ifdef __NETWARE__
+static char base_dir[PATH_MAX] = "sys:/mysql";
+#else
+static char base_dir[PATH_MAX] = "..";
+#endif
+static char db[PATH_MAX] = "test";
+static char user[PATH_MAX] = "root";
+static char password[PATH_MAX] = "";
+
+int master_port = 9306;
+int slave_port = 9307;
+
+#if !defined(__NETWARE__) && !defined(__WIN__)
+static char master_socket[PATH_MAX] = "./var/tmp/master.sock";
+static char slave_socket[PATH_MAX] = "./var/tmp/slave.sock";
+#endif
+
+// comma delimited list of tests to skip or empty string
+#ifndef __WIN__
+static char skip_test[PATH_MAX] = " lowercase_table3 , system_mysql_db_fix ";
+#else
+/*
+ The most ignore testes contain the calls of system command
+*/
+#define MAX_COUNT_TESTES 1024
+/*
+ lowercase_table3 is disabled by Gerg
+ system_mysql_db_fix is disabled by Gerg
+ sp contains a command system
+ rpl_EE_error contains a command system
+ rpl_loaddatalocal contains a command system
+ ndb_autodiscover contains a command system
+ rpl_rotate_logs contains a command system
+ repair contains a command system
+ rpl_trunc_binlog contains a command system
+ mysqldump contains a command system
+ rpl000001 makes non-exit loop...temporary skiped
+*/
+static char skip_test[PATH_MAX] = " lowercase_table3 , system_mysql_db_fix , sp , rpl_EE_error , rpl_loaddatalocal , ndb_autodiscover , rpl_rotate_logs , repair , rpl_trunc_binlog , mysqldump , rpl000001 ";
+#endif
+static char ignore_test[PATH_MAX] = "";
+
+static char bin_dir[PATH_MAX];
+static char mysql_test_dir[PATH_MAX];
+static char test_dir[PATH_MAX];
+static char mysql_tmp_dir[PATH_MAX];
+static char result_dir[PATH_MAX];
+static char master_dir[PATH_MAX];
+static char slave_dir[PATH_MAX];
+static char lang_dir[PATH_MAX];
+static char char_dir[PATH_MAX];
+
+static char mysqladmin_file[PATH_MAX];
+static char mysqld_file[PATH_MAX];
+static char mysqltest_file[PATH_MAX];
+#ifndef __WIN__
+static char master_pid[PATH_MAX];
+static char slave_pid[PATH_MAX];
+static char sh_file[PATH_MAX] = "/bin/sh";
+#else
+static HANDLE master_pid;
+static HANDLE slave_pid;
+#endif
+
+static char master_opt[PATH_MAX] = "";
+static char slave_opt[PATH_MAX] = "";
+
+static char slave_master_info[PATH_MAX] = "";
+
+static char master_init_script[PATH_MAX] = "";
+static char slave_init_script[PATH_MAX] = "";
+
+// OpenSSL
+static char ca_cert[PATH_MAX];
+static char server_cert[PATH_MAX];
+static char server_key[PATH_MAX];
+static char client_cert[PATH_MAX];
+static char client_key[PATH_MAX];
+
+int total_skip = 0;
+int total_pass = 0;
+int total_fail = 0;
+int total_test = 0;
+
+int total_ignore = 0;
+
+int use_openssl = FALSE;
+int master_running = FALSE;
+int slave_running = FALSE;
+int skip_slave = TRUE;
+int single_test = TRUE;
+
+int restarts = 0;
+
+FILE *log_fd = NULL;
+
+/******************************************************************************
+
+ functions
+
+******************************************************************************/
+
+/******************************************************************************
+
+ prototypes
+
+******************************************************************************/
+
+void report_stats();
+void install_db(char *);
+void mysql_install_db();
+void start_master();
+void start_slave();
+void mysql_start();
+void stop_slave();
+void stop_master();
+void mysql_stop();
+void mysql_restart();
+int read_option(char *, char *);
+void run_test(char *);
+void setup(char *);
+void vlog(const char *, va_list);
+void mlog(const char *, ...);
+void log_info(const char *, ...);
+void log_error(const char *, ...);
+void log_errno(const char *, ...);
+void die(const char *);
+char *str_tok(char *string, const char *delim);
+#ifndef __WIN__
+void run_init_script(const char *script_name);
+#endif
+/******************************************************************************
+
+ report_stats()
+
+ Report the gathered statistics.
+
+******************************************************************************/
+void report_stats()
+{
+ if (total_fail == 0)
+ {
+ mlog("\nAll %d test(s) were successful.\n", total_test);
+ }
+ else
+ {
+ double percent = ((double)total_pass / total_test) * 100;
+
+ mlog("\nFailed %u/%u test(s), %.02f%% successful.\n",
+ total_fail, total_test, percent);
+ mlog("\nThe .out and .err files in %s may give you some\n", result_dir);
+ mlog("hint of what when wrong.\n");
+ mlog("\nIf you want to report this error, please first read the documentation\n");
+ mlog("at: http://www.mysql.com/doc/M/y/MySQL_test_suite.html\n");
+ }
+}
+
+/******************************************************************************
+
+ install_db()
+
+ Install the a database.
+
+******************************************************************************/
+void install_db(char *datadir)
+{
+ arg_list_t al;
+ int err;
+ char input[PATH_MAX];
+ char output[PATH_MAX];
+ char error[PATH_MAX];
+
+ // input file
+#ifdef __NETWARE__
+ snprintf(input, PATH_MAX, "%s/bin/init_db.sql", base_dir);
+#else
+ snprintf(input, PATH_MAX, "%s/mysql-test/init_db.sql", base_dir);
+#endif
+ snprintf(output, PATH_MAX, "%s/install.out", datadir);
+ snprintf(error, PATH_MAX, "%s/install.err", datadir);
+
+ // args
+ init_args(&al);
+ add_arg(&al, mysqld_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--bootstrap");
+ add_arg(&al, "--skip-grant-tables");
+ add_arg(&al, "--basedir=%s", base_dir);
+ add_arg(&al, "--datadir=%s", datadir);
+ add_arg(&al, "--skip-innodb");
+ add_arg(&al, "--skip-bdb");
+#ifndef __NETWARE__
+ add_arg(&al, "--character-sets-dir=%s", char_dir);
+ add_arg(&al, "--language=%s", lang_dir);
+#endif
+
+ // spawn
+ if ((err = spawn(mysqld_file, &al, TRUE, input, output, error, NULL)) != 0)
+ {
+ die("Unable to create database.");
+ }
+
+ // free args
+ free_args(&al);
+}
+
+/******************************************************************************
+
+ mysql_install_db()
+
+ Install the test databases.
+
+******************************************************************************/
+void mysql_install_db()
+{
+ char temp[PATH_MAX];
+
+ // var directory
+ snprintf(temp, PATH_MAX, "%s/var", mysql_test_dir);
+
+ // clean up old direcotry
+ del_tree(temp);
+
+ // create var directory
+#ifndef __WIN__
+ mkdir(temp, S_IRWXU);
+ // create subdirectories
+ mlog("Creating test-suite folders...\n");
+ snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+ snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir);
+ mkdir(temp, S_IRWXU);
+#else
+ mkdir(temp);
+ // create subdirectories
+ mlog("Creating test-suite folders...\n");
+ snprintf(temp, PATH_MAX, "%s/var/run", mysql_test_dir);
+ mkdir(temp);
+ snprintf(temp, PATH_MAX, "%s/var/tmp", mysql_test_dir);
+ mkdir(temp);
+ snprintf(temp, PATH_MAX, "%s/var/master-data", mysql_test_dir);
+ mkdir(temp);
+ snprintf(temp, PATH_MAX, "%s/var/master-data/mysql", mysql_test_dir);
+ mkdir(temp);
+ snprintf(temp, PATH_MAX, "%s/var/master-data/test", mysql_test_dir);
+ mkdir(temp);
+ snprintf(temp, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
+ mkdir(temp);
+ snprintf(temp, PATH_MAX, "%s/var/slave-data/mysql", mysql_test_dir);
+ mkdir(temp);
+ snprintf(temp, PATH_MAX, "%s/var/slave-data/test", mysql_test_dir);
+ mkdir(temp);
+#endif
+
+ // install databases
+ mlog("Creating test databases for master... \n");
+ install_db(master_dir);
+ mlog("Creating test databases for slave... \n");
+ install_db(slave_dir);
+}
+
+/******************************************************************************
+
+ start_master()
+
+ Start the master server.
+
+******************************************************************************/
+void start_master()
+{
+ arg_list_t al;
+ int err;
+ char master_out[PATH_MAX];
+ char master_err[PATH_MAX];
+// char temp[PATH_MAX];
+ char temp2[PATH_MAX];
+
+ // remove old berkeley db log files that can confuse the server
+ removef("%s/log.*", master_dir);
+
+ // remove stale binary logs
+ removef("%s/var/log/*-bin.*", mysql_test_dir);
+
+ // remove stale binary logs
+ removef("%s/var/log/*.index", mysql_test_dir);
+
+ // remove master.info file
+ removef("%s/master.info", master_dir);
+
+ // remove relay files
+ removef("%s/var/log/*relay*", mysql_test_dir);
+
+ // remove relay-log.info file
+ removef("%s/relay-log.info", master_dir);
+
+ // init script
+ if (master_init_script[0] != 0)
+ {
+#ifdef __NETWARE__
+ // TODO: use the scripts
+ if (strinstr(master_init_script, "repair_part2-master.sh") != 0)
+ {
+ FILE *fp;
+
+ // create an empty index file
+ snprintf(temp, PATH_MAX, "%s/test/t1.MYI", master_dir);
+ fp = fopen(temp, "wb+");
+
+ fputs("1", fp);
+
+ fclose(fp);
+ }
+#elif !defined(__WIN__)
+ run_init_script(master_init_script);
+#endif
+ }
+
+ // redirection files
+ snprintf(master_out, PATH_MAX, "%s/var/run/master%u.out",
+ mysql_test_dir, restarts);
+ snprintf(master_err, PATH_MAX, "%s/var/run/master%u.err",
+ mysql_test_dir, restarts);
+#ifndef __WIN__
+ snprintf(temp2,PATH_MAX,"%s/var",mysql_test_dir);
+ mkdir(temp2,S_IRWXU);
+ snprintf(temp2,PATH_MAX,"%s/var/log",mysql_test_dir);
+ mkdir(temp2,S_IRWXU);
+#else
+ snprintf(temp2,PATH_MAX,"%s/var",mysql_test_dir);
+ mkdir(temp2);
+ snprintf(temp2,PATH_MAX,"%s/var/log",mysql_test_dir);
+ mkdir(temp2);
+#endif
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqld_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--log-bin=%s/var/log/master-bin",mysql_test_dir);
+ add_arg(&al, "--server-id=1");
+ add_arg(&al, "--basedir=%s", base_dir);
+ add_arg(&al, "--port=%u", master_port);
+#if !defined(__NETWARE__) && !defined(__WIN__)
+ add_arg(&al, "--socket=%s",master_socket);
+#endif
+ add_arg(&al, "--local-infile");
+ add_arg(&al, "--core");
+ add_arg(&al, "--datadir=%s", master_dir);
+#ifndef __WIN__
+ add_arg(&al, "--pid-file=%s", master_pid);
+#endif
+ add_arg(&al, "--character-sets-dir=%s", char_dir);
+ add_arg(&al, "--tmpdir=%s", mysql_tmp_dir);
+ add_arg(&al, "--language=%s", lang_dir);
+#ifdef DEBUG //only for debug builds
+ add_arg(&al, "--debug");
+#endif
+
+ if (use_openssl)
+ {
+ add_arg(&al, "--ssl-ca=%s", ca_cert);
+ add_arg(&al, "--ssl-cert=%s", server_cert);
+ add_arg(&al, "--ssl-key=%s", server_key);
+ }
+
+ // $MASTER_40_ARGS
+ add_arg(&al, "--rpl-recovery-rank=1");
+ add_arg(&al, "--init-rpl-role=master");
+
+ // $SMALL_SERVER
+ add_arg(&al, "-O");
+ add_arg(&al, "key_buffer_size=1M");
+ add_arg(&al, "-O");
+ add_arg(&al, "sort_buffer=256K");
+ add_arg(&al, "-O");
+ add_arg(&al, "max_heap_table_size=1M");
+
+ // $EXTRA_MASTER_OPT
+ if (master_opt[0] != 0)
+ {
+ char *p;
+
+ p = (char *)str_tok(master_opt, " \t");
+ if (!strstr(master_opt, "timezone"))
+ {
+ while (p)
+ {
+ add_arg(&al, "%s", p);
+ p = (char *)str_tok(NULL, " \t");
+ }
+ }
+ }
+
+ // remove the pid file if it exists
+#ifndef __WIN__
+ remove(master_pid);
+#endif
+
+ // spawn
+#ifdef __WIN__
+ if ((err= spawn(mysqld_file, &al, FALSE, NULL, master_out, master_err, &master_pid)) == 0)
+#else
+ if ((err= spawn(mysqld_file, &al, FALSE, NULL, master_out, master_err, master_pid)) == 0)
+#endif
+ {
+ sleep_until_file_exists(master_pid);
+
+ if ((err = wait_for_server_start(bin_dir, mysqladmin_file, user, password, master_port,
+ mysql_tmp_dir)) == 0)
+ {
+ master_running = TRUE;
+ }
+ else
+ {
+ log_error("The master server went down early.");
+ }
+ }
+ else
+ {
+ log_error("Unable to start master server.");
+ }
+
+ // free_args
+ free_args(&al);
+}
+
+/******************************************************************************
+
+ start_slave()
+
+ Start the slave server.
+
+******************************************************************************/
+void start_slave()
+{
+ arg_list_t al;
+ int err;
+ char slave_out[PATH_MAX];
+ char slave_err[PATH_MAX];
+
+ // skip?
+ if (skip_slave) return;
+
+ // remove stale binary logs
+ removef("%s/*-bin.*", slave_dir);
+
+ // remove stale binary logs
+ removef("%s/*.index", slave_dir);
+
+ // remove master.info file
+ removef("%s/master.info", slave_dir);
+
+ // remove relay files
+ removef("%s/var/log/*relay*", mysql_test_dir);
+
+ // remove relay-log.info file
+ removef("%s/relay-log.info", slave_dir);
+
+ // init script
+ if (slave_init_script[0] != 0)
+ {
+#ifdef __NETWARE__
+ // TODO: use the scripts
+ if (strinstr(slave_init_script, "rpl000016-slave.sh") != 0)
+ {
+ // create empty master.info file
+ snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
+ close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO));
+ }
+ else if (strinstr(slave_init_script, "rpl000017-slave.sh") != 0)
+ {
+ FILE *fp;
+
+ // create a master.info file
+ snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
+ fp = fopen(temp, "wb+");
+
+ fputs("master-bin.000001\n", fp);
+ fputs("4\n", fp);
+ fputs("127.0.0.1\n", fp);
+ fputs("replicate\n", fp);
+ fputs("aaaaaaaaaaaaaaab\n", fp);
+ fputs("9306\n", fp);
+ fputs("1\n", fp);
+ fputs("0\n", fp);
+
+ fclose(fp);
+ }
+ else if (strinstr(slave_init_script, "rpl_rotate_logs-slave.sh") != 0)
+ {
+ // create empty master.info file
+ snprintf(temp, PATH_MAX, "%s/master.info", slave_dir);
+ close(open(temp, O_WRONLY | O_CREAT,S_IRWXU|S_IRWXG|S_IRWXO));
+ }
+#elif !defined(__WIN__)
+ run_init_script(slave_init_script);
+#endif
+ }
+
+ // redirection files
+ snprintf(slave_out, PATH_MAX, "%s/var/run/slave%u.out",
+ mysql_test_dir, restarts);
+ snprintf(slave_err, PATH_MAX, "%s/var/run/slave%u.err",
+ mysql_test_dir, restarts);
+
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqld_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--log-bin=slave-bin");
+ add_arg(&al, "--relay_log=slave-relay-bin");
+ add_arg(&al, "--basedir=%s", base_dir);
+ add_arg(&al, "--port=%u", slave_port);
+#if !defined(__NETWARE__) && !defined(__WIN__)
+ add_arg(&al, "--socket=%s",slave_socket);
+#endif
+ add_arg(&al, "--datadir=%s", slave_dir);
+#ifndef __WIN__
+ add_arg(&al, "--pid-file=%s", slave_pid);
+#endif
+ add_arg(&al, "--character-sets-dir=%s", char_dir);
+ add_arg(&al, "--core");
+ add_arg(&al, "--tmpdir=%s", mysql_tmp_dir);
+ add_arg(&al, "--language=%s", lang_dir);
+
+ add_arg(&al, "--exit-info=256");
+ add_arg(&al, "--log-slave-updates");
+ add_arg(&al, "--init-rpl-role=slave");
+ add_arg(&al, "--skip-innodb");
+ add_arg(&al, "--skip-slave-start");
+ add_arg(&al, "--slave-load-tmpdir=../../var/tmp");
+
+ add_arg(&al, "--report-user=%s", user);
+ add_arg(&al, "--report-host=127.0.0.1");
+ add_arg(&al, "--report-port=%u", slave_port);
+
+ add_arg(&al, "--master-retry-count=10");
+ add_arg(&al, "-O");
+ add_arg(&al, "slave_net_timeout=10");
+#ifdef DEBUG //only for debug builds
+ add_arg(&al, "--debug");
+#endif
+
+ if (use_openssl)
+ {
+ add_arg(&al, "--ssl-ca=%s", ca_cert);
+ add_arg(&al, "--ssl-cert=%s", server_cert);
+ add_arg(&al, "--ssl-key=%s", server_key);
+ }
+
+ // slave master info
+ if (slave_master_info[0] != 0)
+ {
+ char *p;
+
+ p = (char *)str_tok(slave_master_info, " \t");
+
+ while(p)
+ {
+ add_arg(&al, "%s", p);
+
+ p = (char *)str_tok(NULL, " \t");
+ }
+ }
+ else
+ {
+ add_arg(&al, "--master-user=%s", user);
+ add_arg(&al, "--master-password=%s", password);
+ add_arg(&al, "--master-host=127.0.0.1");
+ add_arg(&al, "--master-port=%u", master_port);
+ add_arg(&al, "--master-connect-retry=1");
+ add_arg(&al, "--server-id=2");
+ add_arg(&al, "--rpl-recovery-rank=2");
+ }
+
+ // small server
+ add_arg(&al, "-O");
+ add_arg(&al, "key_buffer_size=1M");
+ add_arg(&al, "-O");
+ add_arg(&al, "sort_buffer=256K");
+ add_arg(&al, "-O");
+ add_arg(&al, "max_heap_table_size=1M");
+
+
+ // opt args
+ if (slave_opt[0] != 0)
+ {
+ char *p;
+
+ p = (char *)str_tok(slave_opt, " \t");
+
+ while(p)
+ {
+ add_arg(&al, "%s", p);
+
+ p = (char *)str_tok(NULL, " \t");
+ }
+ }
+
+ // remove the pid file if it exists
+#ifndef __WIN__
+ remove(slave_pid);
+#endif
+ // spawn
+#ifdef __WIN__
+ if ((err = spawn(mysqld_file, &al, FALSE, NULL, slave_out, slave_err, &slave_pid)) == 0)
+#else
+ if ((err = spawn(mysqld_file, &al, FALSE, NULL, slave_out, slave_err, slave_pid)) == 0)
+#endif
+ {
+ sleep_until_file_exists(slave_pid);
+
+ if ((err = wait_for_server_start(bin_dir, mysqladmin_file, user, password, slave_port,
+ mysql_tmp_dir)) == 0)
+ {
+ slave_running = TRUE;
+ }
+ else
+ {
+ log_error("The slave server went down early.");
+ }
+ }
+ else
+ {
+ log_error("Unable to start slave server.");
+ }
+
+ // free args
+ free_args(&al);
+}
+
+/******************************************************************************
+
+ mysql_start()
+
+ Start the mysql servers.
+
+******************************************************************************/
+void mysql_start()
+{
+// log_info("Starting the MySQL server(s): %u", ++restarts);
+ start_master();
+
+ start_slave();
+
+ // activate the test screen
+#ifdef __NETWARE__
+ ActivateScreen(getscreenhandle());
+#endif
+}
+
+/******************************************************************************
+
+ stop_slave()
+
+ Stop the slave server.
+
+******************************************************************************/
+void stop_slave()
+{
+ int err;
+
+ // running?
+ if (!slave_running) return;
+
+ // stop
+ if ((err = stop_server(bin_dir, mysqladmin_file, user, password, slave_port, slave_pid,
+ mysql_tmp_dir)) == 0)
+ {
+ slave_running = FALSE;
+ }
+ else
+ {
+ log_error("Unable to stop slave server.");
+ }
+}
+
+/******************************************************************************
+
+ stop_master()
+
+ Stop the master server.
+
+******************************************************************************/
+void stop_master()
+{
+ int err;
+
+ // running?
+ if (!master_running) return;
+
+ if ((err = stop_server(bin_dir, mysqladmin_file, user, password, master_port, master_pid,
+ mysql_tmp_dir)) == 0)
+ {
+ master_running = FALSE;
+ }
+ else
+ {
+ log_error("Unable to stop master server.");
+ }
+}
+
+/******************************************************************************
+
+ mysql_stop()
+
+ Stop the mysql servers.
+
+******************************************************************************/
+void mysql_stop()
+{
+
+ stop_master();
+
+ stop_slave();
+
+ // activate the test screen
+#ifdef __NETWARE__
+ ActivateScreen(getscreenhandle());
+#endif
+}
+
+/******************************************************************************
+
+ mysql_restart()
+
+ Restart the mysql servers.
+
+******************************************************************************/
+void mysql_restart()
+{
+// log_info("Restarting the MySQL server(s): %u", ++restarts);
+
+ mysql_stop();
+
+ mlog(DASH);
+
+ mysql_start();
+}
+
+/******************************************************************************
+
+ read_option()
+
+ Read the option file.
+
+******************************************************************************/
+int read_option(char *opt_file, char *opt)
+{
+ int fd, err;
+ char *p;
+ char buf[PATH_MAX];
+
+ // copy current option
+ strncpy(buf, opt, PATH_MAX);
+
+ // open options file
+ fd = open(opt_file, O_RDONLY);
+
+ err = read(fd, opt, PATH_MAX);
+
+ close(fd);
+
+ if (err > 0)
+ {
+ // terminate string
+ if ((p = strchr(opt, '\n')) != NULL)
+ {
+ *p = 0;
+
+ // check for a '\r'
+ if ((p = strchr(opt, '\r')) != NULL)
+ {
+ *p = 0;
+ }
+ }
+ else
+ {
+ opt[err] = 0;
+ }
+
+ // check for $MYSQL_TEST_DIR
+ if ((p = strstr(opt, "$MYSQL_TEST_DIR")) != NULL)
+ {
+ char temp[PATH_MAX];
+
+ *p = 0;
+
+ strcpy(temp, p + strlen("$MYSQL_TEST_DIR"));
+
+ strcat(opt, mysql_test_dir);
+
+ strcat(opt, temp);
+ }
+ // Check for double backslash and replace it with single bakslash
+ if ((p = strstr(opt, "\\\\")) != NULL)
+ {
+ /* bmove is guranteed to work byte by byte */
+ bmove(p, p+1, strlen(p+1));
+ }
+ }
+ else
+ {
+ // clear option
+ *opt = 0;
+ }
+
+ // compare current option with previous
+ return strcmp(opt, buf);
+}
+
+/******************************************************************************
+
+ run_test()
+
+ Run the given test case.
+
+******************************************************************************/
+void run_test(char *test)
+{
+ char temp[PATH_MAX];
+ const char *rstr;
+ int skip = FALSE, ignore=FALSE;
+ int restart = FALSE;
+ int flag = FALSE;
+ struct stat info;
+
+ // skip tests in the skip list
+ snprintf(temp, PATH_MAX, " %s ", test);
+ skip = (strinstr(skip_test, temp) != 0);
+ if (skip == FALSE)
+ ignore = (strinstr(ignore_test, temp) != 0);
+
+ snprintf(master_init_script, PATH_MAX, "%s/%s-master.sh", test_dir, test);
+ snprintf(slave_init_script, PATH_MAX, "%s/%s-slave.sh", test_dir, test);
+#ifdef __WIN__
+ if (! stat(master_init_script, &info))
+ skip = TRUE;
+ if (!stat(slave_init_script, &info))
+ skip = TRUE;
+#endif
+ if (ignore)
+ {
+ // show test
+ mlog("%-46s ", test);
+
+ // ignore
+ rstr = TEST_IGNORE;
+ ++total_ignore;
+ }
+ else if (!skip) // skip test?
+ {
+ char test_file[PATH_MAX];
+ char master_opt_file[PATH_MAX];
+ char slave_opt_file[PATH_MAX];
+ char slave_master_info_file[PATH_MAX];
+ char result_file[PATH_MAX];
+ char reject_file[PATH_MAX];
+ char out_file[PATH_MAX];
+ char err_file[PATH_MAX];
+ int err;
+ arg_list_t al;
+#ifdef __WIN__
+ /*
+ Clean test database
+ */
+ removef("%s/test/*.*", master_dir);
+ removef("%s/test/*.*", slave_dir);
+ removef("%s/mysqltest/*.*", master_dir);
+ removef("%s/mysqltest/*.*", slave_dir);
+
+#endif
+ // skip slave?
+ flag = skip_slave;
+ skip_slave = (strncmp(test, "rpl", 3) != 0);
+ if (flag != skip_slave) restart = TRUE;
+
+ // create files
+ snprintf(master_opt_file, PATH_MAX, "%s/%s-master.opt", test_dir, test);
+ snprintf(slave_opt_file, PATH_MAX, "%s/%s-slave.opt", test_dir, test);
+ snprintf(slave_master_info_file, PATH_MAX, "%s/%s.slave-mi", test_dir, test);
+ snprintf(reject_file, PATH_MAX, "%s/%s%s", result_dir, test, REJECT_SUFFIX);
+ snprintf(out_file, PATH_MAX, "%s/%s%s", result_dir, test, OUT_SUFFIX);
+ snprintf(err_file, PATH_MAX, "%s/%s%s", result_dir, test, ERR_SUFFIX);
+
+ // netware specific files
+ snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, NW_TEST_SUFFIX);
+ if (stat(test_file, &info))
+ {
+ snprintf(test_file, PATH_MAX, "%s/%s%s", test_dir, test, TEST_SUFFIX);
+ if (access(test_file,0))
+ {
+ printf("Invalid test name %s, %s file not found\n",test,test_file);
+ return;
+ }
+ }
+
+ snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, NW_RESULT_SUFFIX);
+ if (stat(result_file, &info))
+ {
+ snprintf(result_file, PATH_MAX, "%s/%s%s", result_dir, test, RESULT_SUFFIX);
+ }
+
+ // init scripts
+ if (stat(master_init_script, &info))
+ master_init_script[0] = 0;
+ else
+ restart = TRUE;
+
+ if (stat(slave_init_script, &info))
+ slave_init_script[0] = 0;
+ else
+ restart = TRUE;
+
+ // read options
+ if (read_option(master_opt_file, master_opt)) restart = TRUE;
+ if (read_option(slave_opt_file, slave_opt)) restart = TRUE;
+ if (read_option(slave_master_info_file, slave_master_info)) restart = TRUE;
+
+ // cleanup previous run
+ remove(reject_file);
+ remove(out_file);
+ remove(err_file);
+
+ // start or restart?
+ if (!master_running) mysql_start();
+ else if (restart) mysql_restart();
+
+ // let the system stabalize
+ sleep(1);
+
+ // show test
+ mlog("%-46s ", test);
+
+
+ // args
+ init_args(&al);
+ add_arg(&al, "%s", mysqltest_file);
+ add_arg(&al, "--no-defaults");
+ add_arg(&al, "--port=%u", master_port);
+#if !defined(__NETWARE__) && !defined(__WIN__)
+ add_arg(&al, "--socket=%s", master_socket);
+ add_arg(&al, "--tmpdir=%s", mysql_tmp_dir);
+#endif
+ add_arg(&al, "--database=%s", db);
+ add_arg(&al, "--user=%s", user);
+ add_arg(&al, "--password=%s", password);
+ add_arg(&al, "--silent");
+ add_arg(&al, "--basedir=%s/", mysql_test_dir);
+ add_arg(&al, "--host=127.0.0.1");
+ add_arg(&al, "-v");
+ add_arg(&al, "-R");
+ add_arg(&al, "%s", result_file);
+
+ if (use_openssl)
+ {
+ add_arg(&al, "--ssl-ca=%s", ca_cert);
+ add_arg(&al, "--ssl-cert=%s", client_cert);
+ add_arg(&al, "--ssl-key=%s", client_key);
+ }
+
+ // spawn
+ err = spawn(mysqltest_file, &al, TRUE, test_file, out_file, err_file, NULL);
+
+ // free args
+ free_args(&al);
+
+ remove_empty_file(out_file);
+ remove_empty_file(err_file);
+
+ if (err == 0)
+ {
+ // pass
+ rstr = TEST_PASS;
+ ++total_pass;
+
+ // increment total
+ ++total_test;
+ }
+ else if (err == 2)
+ {
+ // skip
+ rstr = TEST_SKIP;
+ ++total_skip;
+ }
+ else if (err == 1)
+ {
+ // fail
+ rstr = TEST_FAIL;
+ ++total_fail;
+
+ // increment total
+ ++total_test;
+ }
+ else
+ {
+ rstr = TEST_BAD;
+ }
+ }
+ else // early skips
+ {
+ // show test
+ mlog("%-46s ", test);
+
+ // skip
+ rstr = TEST_SKIP;
+ ++total_skip;
+ }
+
+ // result
+ mlog("%-14s\n", rstr);
+}
+
+/******************************************************************************
+
+ vlog()
+
+ Log the message.
+
+******************************************************************************/
+void vlog(const char *format, va_list ap)
+{
+ vfprintf(stdout, format, ap);
+ fflush(stdout);
+
+ if (log_fd)
+ {
+ vfprintf(log_fd, format, ap);
+ fflush(log_fd);
+ }
+}
+
+/******************************************************************************
+
+ log()
+
+ Log the message.
+
+******************************************************************************/
+void mlog(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ vlog(format, ap);
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ log_info()
+
+ Log the given information.
+
+******************************************************************************/
+void log_info(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ mlog("-- INFO : ");
+ vlog(format, ap);
+ mlog("\n");
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ log_error()
+
+ Log the given error.
+
+******************************************************************************/
+void log_error(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ mlog("-- ERROR: ");
+ vlog(format, ap);
+ mlog("\n");
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ log_errno()
+
+ Log the given error and errno.
+
+******************************************************************************/
+void log_errno(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+
+ mlog("-- ERROR: (%003u) ", errno);
+ vlog(format, ap);
+ mlog("\n");
+
+ va_end(ap);
+}
+
+/******************************************************************************
+
+ die()
+
+ Exit the application.
+
+******************************************************************************/
+void die(const char *msg)
+{
+ log_error(msg);
+#ifdef __NETWARE__
+ pressanykey();
+#endif
+ exit(-1);
+}
+
+/******************************************************************************
+
+ setup()
+
+ Setup the mysql test enviornment.
+
+******************************************************************************/
+void setup(char *file)
+{
+ char temp[PATH_MAX];
+ char file_path[PATH_MAX*2];
+ char *p;
+ int position;
+
+ // set the timezone for the timestamp test
+#ifdef __WIN__
+ _putenv( "TZ=GMT-3" );
+#else
+ setenv("TZ", "GMT-3", TRUE);
+#endif
+ // find base dir
+#ifdef __NETWARE__
+ strcpy(temp, strlwr(file));
+ while((p = strchr(temp, '\\')) != NULL) *p = '/';
+#else
+ getcwd(temp, PATH_MAX);
+ position = strlen(temp);
+ temp[position] = '/';
+ temp[position+1] = 0;
+#ifdef __WIN__
+ while((p = strchr(temp, '\\')) != NULL) *p = '/';
+#endif
+#endif
+
+ if ((position = strinstr(temp, "/mysql-test/")) != 0)
+ {
+ p = temp + position - 1;
+ *p = 0;
+ strcpy(base_dir, temp);
+ }
+
+ log_info("Currect directory: %s",base_dir);
+
+#ifdef __NETWARE__
+ // setup paths
+ snprintf(bin_dir, PATH_MAX, "%s/bin", base_dir);
+ snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir);
+ snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir);
+ snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir);
+ snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir);
+ snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir);
+ snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
+ snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir);
+ snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir);
+
+#ifdef HAVE_OPENSSL
+ use_openssl = TRUE;
+#endif // HAVE_OPENSSL
+
+ // OpenSSL paths
+ snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir);
+ snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir);
+ snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir);
+ snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir);
+ snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir);
+
+ // setup files
+ snprintf(mysqld_file, PATH_MAX, "%s/mysqld", bin_dir);
+ snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir);
+ snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
+ snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir);
+ snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir);
+#elif __WIN__
+ // setup paths
+#ifdef _DEBUG
+ snprintf(bin_dir, PATH_MAX, "%s/client_debug", base_dir);
+#else
+ snprintf(bin_dir, PATH_MAX, "%s/client_release", base_dir);
+#endif
+ snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir);
+ snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir);
+ snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir);
+ snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir);
+ snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir);
+ snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
+ snprintf(lang_dir, PATH_MAX, "%s/share/english", base_dir);
+ snprintf(char_dir, PATH_MAX, "%s/share/charsets", base_dir);
+
+#ifdef HAVE_OPENSSL
+ use_openssl = TRUE;
+#endif // HAVE_OPENSSL
+
+ // OpenSSL paths
+ snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir);
+ snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir);
+ snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir);
+ snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir);
+ snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir);
+
+ // setup files
+ snprintf(mysqld_file, PATH_MAX, "%s/mysqld.exe", bin_dir);
+ snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest.exe", bin_dir);
+ snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin.exe", bin_dir);
+#else
+ // setup paths
+ snprintf(bin_dir, PATH_MAX, "%s/client", base_dir);
+ snprintf(mysql_test_dir, PATH_MAX, "%s/mysql-test", base_dir);
+ snprintf(test_dir, PATH_MAX, "%s/t", mysql_test_dir);
+ snprintf(mysql_tmp_dir, PATH_MAX, "%s/var/tmp", mysql_test_dir);
+ snprintf(result_dir, PATH_MAX, "%s/r", mysql_test_dir);
+ snprintf(master_dir, PATH_MAX, "%s/var/master-data", mysql_test_dir);
+ snprintf(slave_dir, PATH_MAX, "%s/var/slave-data", mysql_test_dir);
+ snprintf(lang_dir, PATH_MAX, "%s/sql/share/english", base_dir);
+ snprintf(char_dir, PATH_MAX, "%s/sql/share/charsets", base_dir);
+
+#ifdef HAVE_OPENSSL
+ use_openssl = TRUE;
+#endif // HAVE_OPENSSL
+
+ // OpenSSL paths
+ snprintf(ca_cert, PATH_MAX, "%s/SSL/cacert.pem", base_dir);
+ snprintf(server_cert, PATH_MAX, "%s/SSL/server-cert.pem", base_dir);
+ snprintf(server_key, PATH_MAX, "%s/SSL/server-key.pem", base_dir);
+ snprintf(client_cert, PATH_MAX, "%s/SSL/client-cert.pem", base_dir);
+ snprintf(client_key, PATH_MAX, "%s/SSL/client-key.pem", base_dir);
+
+ // setup files
+ snprintf(mysqld_file, PATH_MAX, "%s/sql/mysqld", base_dir);
+ snprintf(mysqltest_file, PATH_MAX, "%s/mysqltest", bin_dir);
+ snprintf(mysqladmin_file, PATH_MAX, "%s/mysqladmin", bin_dir);
+ snprintf(master_pid, PATH_MAX, "%s/var/run/master.pid", mysql_test_dir);
+ snprintf(slave_pid, PATH_MAX, "%s/var/run/slave.pid", mysql_test_dir);
+
+ snprintf(master_socket,PATH_MAX, "%s/var/tmp/master.sock", mysql_test_dir);
+ snprintf(slave_socket,PATH_MAX, "%s/var/tmp/slave.sock", mysql_test_dir);
+
+#endif
+ // create log file
+ snprintf(temp, PATH_MAX, "%s/mysql-test-run.log", mysql_test_dir);
+ if ((log_fd = fopen(temp, "w+")) == NULL)
+ {
+ log_errno("Unable to create log file.");
+ }
+
+ // prepare skip test list
+ while((p = strchr(skip_test, ',')) != NULL) *p = ' ';
+ strcpy(temp, strlwr(skip_test));
+ snprintf(skip_test, PATH_MAX, " %s ", temp);
+
+ // environment
+#ifdef __NETWARE__
+ setenv("MYSQL_TEST_DIR", mysql_test_dir, 1);
+ snprintf(file_path, PATH_MAX*2, "%s/client/mysqldump --no-defaults -u root --port=%u", bin_dir, master_port);
+ setenv("MYSQL_DUMP", file_path, 1);
+ snprintf(file_path, PATH_MAX*2, "%s/client/mysqlbinlog --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir);
+ setenv("MYSQL_BINLOG", file_path, 1);
+#elif __WIN__
+ snprintf(file_path,MAX_PATH,"MYSQL_TEST_DIR=%s",mysql_test_dir);
+ _putenv(file_path);
+ snprintf(file_path, PATH_MAX*2, "MYSQL_DUMP=%s/mysqldump.exe --no-defaults -u root --port=%u", bin_dir, master_port);
+ _putenv(file_path);
+ snprintf(file_path, PATH_MAX*2, "MYSQL_BINLOG=%s/mysqlbinlog.exe --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir);
+ _putenv(file_path);
+#else
+ setenv("MYSQL_TEST_DIR", mysql_test_dir, 1);
+ snprintf(file_path, PATH_MAX*2, "%s/mysqldump --no-defaults -u root --port=%u --socket=%s", bin_dir, master_port, master_socket);
+ setenv("MYSQL_DUMP", file_path, 1);
+ snprintf(file_path, PATH_MAX*2, "%s/mysqlbinlog --no-defaults --local-load=%s", bin_dir, mysql_tmp_dir);
+ setenv("MYSQL_BINLOG", file_path, 1);
+#endif
+
+#ifndef __WIN__
+ setenv("MASTER_MYPORT", "9306", 1);
+ setenv("SLAVE_MYPORT", "9307", 1);
+ setenv("MYSQL_TCP_PORT", "3306", 1);
+#else
+ _putenv("MASTER_MYPORT=9306");
+ _putenv("SLAVE_MYPORT=9307");
+ _putenv("MYSQL_TCP_PORT=3306");
+#endif
+
+}
+
+/******************************************************************************
+
+ main()
+
+******************************************************************************/
+int main(int argc, char **argv)
+{
+ int is_ignore_list = 0;
+ // setup
+ setup(argv[0]);
+
+ /* The --ignore option is comma saperated list of test cases to skip and
+ should be very first command line option to the test suite.
+
+ The usage is now:
+ mysql_test_run --ignore=test1,test2 test3 test4
+ where test1 and test2 are test cases to ignore
+ and test3 and test4 are test cases to run.
+ */
+ if (argc >= 2 && !strnicmp(argv[1], "--ignore=", sizeof("--ignore=")-1))
+ {
+ char *temp, *token;
+ temp= strdup(strchr(argv[1],'=') + 1);
+ for (token=str_tok(temp, ","); token != NULL; token=str_tok(NULL, ","))
+ {
+ if (strlen(ignore_test) + strlen(token) + 2 <= PATH_MAX-1)
+ sprintf(ignore_test+strlen(ignore_test), " %s ", token);
+ else
+ {
+ free(temp);
+ die("ignore list too long.");
+ }
+ }
+ free(temp);
+ is_ignore_list = 1;
+ }
+ // header
+#ifndef __WIN__
+ mlog("MySQL Server %s, for %s (%s)\n\n", VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+#else
+ mlog("MySQL Server ---, for %s (%s)\n\n", SYSTEM_TYPE, MACHINE_TYPE);
+#endif
+
+ mlog("Initializing Tests...\n");
+
+ // install test databases
+ mysql_install_db();
+
+ mlog("Starting Tests...\n");
+
+ mlog("\n");
+ mlog(HEADER);
+ mlog(DASH);
+
+ if ( argc > 1 + is_ignore_list )
+ {
+ int i;
+
+ // single test
+ single_test = TRUE;
+
+ for (i = 1 + is_ignore_list; i < argc; i++)
+ {
+ // run given test
+ run_test(argv[i]);
+ }
+ }
+ else
+ {
+ // run all tests
+#ifndef __WIN__
+ struct dirent **namelist;
+ int i,n;
+ char test[NAME_MAX];
+ char *p;
+ int position;
+
+ n = scandir(test_dir, &namelist, 0, alphasort);
+ if (n < 0)
+ die("Unable to open tests directory.");
+ else
+ {
+ for (i = 0; i < n; i++)
+ {
+ strcpy(test, strlwr(namelist[i]->d_name));
+ // find the test suffix
+ if ((position = strinstr(test, TEST_SUFFIX)) != 0)
+ {
+ p = test + position - 1;
+ // null terminate at the suffix
+ *p = 0;
+ // run test
+ run_test(test);
+ }
+ free(namelist[n]);
+ }
+ free(namelist);
+ }
+#else
+ struct _finddata_t dir;
+ intptr_t handle;
+ char test[NAME_MAX];
+ char mask[PATH_MAX];
+ char *p;
+ int position;
+ char **names = 0;
+ char **testes = 0;
+ int name_index;
+ int index;
+
+ // single test
+ single_test = FALSE;
+
+ snprintf(mask,MAX_PATH,"%s/*.test",test_dir);
+
+ if ((handle=_findfirst(mask,&dir)) == -1L)
+ {
+ die("Unable to open tests directory.");
+ }
+
+ names = malloc(MAX_COUNT_TESTES*4);
+ testes = names;
+ name_index = 0;
+
+ do
+ {
+ if (!(dir.attrib & _A_SUBDIR))
+ {
+ strcpy(test, strlwr(dir.name));
+
+ // find the test suffix
+ if ((position = strinstr(test, TEST_SUFFIX)) != 0)
+ {
+ p = test + position - 1;
+ // null terminate at the suffix
+ *p = 0;
+
+ // insert test
+ *names = malloc(PATH_MAX);
+ strcpy(*names,test);
+ names++;
+ name_index++;
+ }
+ }
+ }while (_findnext(handle,&dir) == 0);
+
+ _findclose(handle);
+
+ qsort( (void *)testes, name_index, sizeof( char * ), compare );
+
+ for (index = 0; index <= name_index; index++)
+ {
+ run_test(testes[index]);
+ free(testes[index]);
+ }
+
+ free(testes);
+#endif
+ }
+
+ // stop server
+ mysql_stop();
+
+ mlog(DASH);
+ mlog("\n");
+
+ mlog("Ending Tests...\n");
+
+ // report stats
+ report_stats();
+
+ // close log
+ if (log_fd) fclose(log_fd);
+
+ // keep results up
+#ifdef __NETWARE__
+ pressanykey();
+#endif
+ return 0;
+}
+
+
+/*
+ Synopsis:
+ This function breaks the string into a sequence of tokens. The difference
+ between this function and strtok is that it respects the quoted string i.e.
+ it skips any delimiter character within the quoted part of the string.
+ It return tokens by eliminating quote character. It modifies the input string
+ passed. It will work with whitespace delimeter but may not work properly with
+ other delimeter. If the delimeter will contain any quote character, then
+ function will not tokenize and will return null string.
+ e.g. if input string is
+ --init-slave="set global max_connections=500" --skip-external-locking
+ then the output will two string i.e.
+ --init-slave=set global max_connections=500
+ --skip-external-locking
+
+Arguments:
+ string: input string
+ delim: set of delimiter character
+Output:
+ return the null terminated token of NULL.
+*/
+
+
+char *str_tok(char *string, const char *delim)
+{
+ char *token; /* current token received from strtok */
+ char *qt_token; /* token delimeted by the matching pair of quote */
+ /*
+ if there are any quote chars found in the token then this variable
+ will hold the concatenated string to return to the caller
+ */
+ char *ptr_token=NULL;
+ /* pointer to the quote character in the token from strtok */
+ char *ptr_quote=NULL;
+
+ /* See if the delimeter contains any quote character */
+ if (strchr(delim,'\'') || strchr(delim,'\"'))
+ return NULL;
+
+ /* repeate till we are getting some token from strtok */
+ while ((token = (char*)strtok(string, delim) ) != NULL)
+ {
+ /*
+ make the input string NULL so that next time onward strtok can
+ be called with NULL input string.
+ */
+ string = NULL;
+ /*
+ We don't need to remove any quote character for Windows version
+ */
+#ifndef __WIN__
+ /* check if the current token contain double quote character*/
+ if ((ptr_quote = (char*)strchr(token,'\"')) != NULL)
+ {
+ /*
+ get the matching the matching double quote in the remaining
+ input string
+ */
+ qt_token = (char*)strtok(NULL,"\"");
+ }
+ /* check if the current token contain single quote character*/
+ else if ((ptr_quote = (char*)strchr(token,'\'')) != NULL)
+ {
+ /*
+ get the matching the matching single quote in the remaining
+ input string
+ */
+ qt_token = (char*)strtok(NULL,"\'");
+ }
+#endif
+ /*
+ if the current token does not contains any quote character then
+ return to the caller.
+ */
+ if (ptr_quote == NULL)
+ {
+ /*
+ if there is any earlier token i.e. ptr_token then append the
+ current token in it and return it else return the current
+ token directly
+ */
+ return ptr_token ? strcat(ptr_token,token) : token;
+ }
+
+ /*
+ remove the quote character i.e. make NULL so that the token will
+ be devided in two part and later both part can be concatenated
+ and hence quote will be removed
+ */
+ *ptr_quote= 0;
+
+ /* check if ptr_token has been initialized or not */
+ if (ptr_token == NULL)
+ {
+ /* initialize the ptr_token with current token */
+ ptr_token= token;
+ /* copy entire string between matching pair of quote*/
+ sprintf(ptr_token+strlen(ptr_token),"%s %s", ptr_quote+1, qt_token);
+ }
+ else
+ {
+ /*
+ copy the current token and entire string between matching pair
+ of quote
+ */
+ if (qt_token == NULL)
+ {
+ sprintf(ptr_token+strlen(ptr_token),"%s%s", token, ptr_quote+1);
+ }
+ else
+ {
+ sprintf(ptr_token+strlen(ptr_token),"%s%s %s", token, ptr_quote+1,
+ qt_token );
+ }
+ }
+ }
+
+ /* return the concatenated token */
+ return ptr_token;
+}
+
+#ifndef __WIN__
+
+/*
+ Synopsis:
+ This function run scripts files on Linux and Netware
+
+Arguments:
+ script_name: name of script file
+
+Output:
+ nothing
+*/
+void run_init_script(const char *script_name)
+{
+ arg_list_t al;
+ int err;
+
+ // args
+ init_args(&al);
+ add_arg(&al, sh_file);
+ add_arg(&al, script_name);
+
+ // spawn
+ if ((err = spawn(sh_file, &al, TRUE, NULL, NULL, NULL, NULL)) != 0)
+ {
+ die("Unable to run script.");
+ }
+
+ // free args
+ free_args(&al);
+}
+#endif