Commit 890919b7 authored by unknown's avatar unknown

Merge mysql.com:/home/wax/mysql/mysql-4.1

into mysql.com:/home/wax/mysql/mysql-4.1mysqltest

parents 60e90ca0 60d8ff97
......@@ -949,8 +949,11 @@ static void do_exec(struct st_query* q)
while (fgets(buf, sizeof(buf), res_file))
replace_dynstr_append_mem(ds, buf, strlen(buf));
}
#ifndef __WIN__
error= pclose(res_file);
#else
error= _pclose(res_file);
#endif
if (error != 0)
die("command \"%s\" failed", cmd);
......@@ -4516,8 +4519,7 @@ static void get_replace_column(struct st_query *q)
my_free(start, MYF(0));
}
#ifdef __NETWARE__
#if defined(__NETWARE__) || defined(__WIN__)
/*
Substitute environment variables with text.
......@@ -4608,9 +4610,13 @@ FILE *my_popen(const char *cmd, const char *mode __attribute__((unused)))
FILE *res_file;
subst_cmd= subst_env_var(cmd);
#ifndef __WIN__
res_file= popen(subst_cmd, "r0");
#else
res_file= _popen(subst_cmd, "r0");
#endif
my_free(subst_cmd, MYF(0));
return res_file;
}
#endif /* __NETWARE__ */
#endif /* __NETWARE__ or __WIN__*/
......@@ -36,6 +36,11 @@ test_SCRIPTS = mysql-test-run install_test_db
test_DATA = std_data/client-key.pem std_data/client-cert.pem std_data/cacert.pem
CLEANFILES = $(test_SCRIPTS) $(test_DATA)
INCLUDES = -I$(srcdir)/../include -I../include -I..
bin_PROGRAMS = mysql_test_run_new
mysql_test_run_new_SOURCES= mysql_test_run_new.c my_manage.c
dist-hook:
mkdir -p $(distdir)/t $(distdir)/r $(distdir)/include \
$(distdir)/std_data
......
CREATE DATABASE mysql;
CREATE DATABASE test;
USE mysql;
CREATE TABLE db (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db,User), KEY User (User)) comment='Database privileges';
INSERT INTO db VALUES ('%','test','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','Y');
CREATE TABLE host (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, PRIMARY KEY Host (Host,Db)) comment='Host privileges; Merged with database privileges';
CREATE TABLE user (Host char(60) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Password char(45) binary DEFAULT '' NOT NULL, Select_priv enum('N','Y') DEFAULT 'N' NOT NULL, Insert_priv enum('N','Y') DEFAULT 'N' NOT NULL, Update_priv enum('N','Y') DEFAULT 'N' NOT NULL, Delete_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_priv enum('N','Y') DEFAULT 'N' NOT NULL, Drop_priv enum('N','Y') DEFAULT 'N' NOT NULL, Reload_priv enum('N','Y') DEFAULT 'N' NOT NULL, Shutdown_priv enum('N','Y') DEFAULT 'N' NOT NULL, Process_priv enum('N','Y') DEFAULT 'N' NOT NULL, File_priv enum('N','Y') DEFAULT 'N' NOT NULL, Grant_priv enum('N','Y') DEFAULT 'N' NOT NULL, References_priv enum('N','Y') DEFAULT 'N' NOT NULL, Index_priv enum('N','Y') DEFAULT 'N' NOT NULL, Alter_priv enum('N','Y') DEFAULT 'N' NOT NULL, Show_db_priv enum('N','Y') DEFAULT 'N' NOT NULL, Super_priv enum('N','Y') DEFAULT 'N' NOT NULL, Create_tmp_table_priv enum('N','Y') DEFAULT 'N' NOT NULL, Lock_tables_priv enum('N','Y') DEFAULT 'N' NOT NULL, Execute_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_slave_priv enum('N','Y') DEFAULT 'N' NOT NULL, Repl_client_priv enum('N','Y') DEFAULT 'N' NOT NULL, ssl_type enum('','ANY','X509', 'SPECIFIED') DEFAULT '' NOT NULL, ssl_cipher BLOB NOT NULL, x509_issuer BLOB NOT NULL, x509_subject BLOB NOT NULL, max_questions int(11) unsigned DEFAULT 0 NOT NULL, max_updates int(11) unsigned DEFAULT 0 NOT NULL, max_connections int(11) unsigned DEFAULT 0 NOT NULL, PRIMARY KEY Host (Host,User)) comment='Users and global privileges';
INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
INSERT INTO user VALUES ('','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','','','','',0,0,0);
INSERT INTO user (host,user) values ('localhost','');
INSERT INTO user (host,user) values ('','');
CREATE TABLE func (name char(64) binary DEFAULT '' NOT NULL, ret tinyint(1) DEFAULT '0' NOT NULL, dl char(128) DEFAULT '' NOT NULL, type enum ('function','aggregate') NOT NULL, PRIMARY KEY (name)) comment='User defined functions';
CREATE TABLE tables_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(60) binary DEFAULT '' NOT NULL, Grantor char(77) DEFAULT '' NOT NULL, Timestamp timestamp(14), Table_priv set('Select','Insert','Update','Delete','Create','Drop','Grant','References','Index','Alter') DEFAULT '' NOT NULL, Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name), KEY Grantor (Grantor)) comment='Table privileges';
CREATE TABLE columns_priv (Host char(60) binary DEFAULT '' NOT NULL, Db char(64) binary DEFAULT '' NOT NULL, User char(16) binary DEFAULT '' NOT NULL, Table_name char(64) binary DEFAULT '' NOT NULL, Column_name char(64) binary DEFAULT '' NOT NULL, Timestamp timestamp(14), Column_priv set('Select','Insert','Update','References') DEFAULT '' NOT NULL, PRIMARY KEY (Host,Db,User,Table_name,Column_name)) comment='Column privileges';
/*
Copyright (c) 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 <stdio.h>
#include <errno.h>
#ifndef __WIN__
#include <dirent.h>
#endif
#include <string.h>
#ifdef __NETWARE__
#include <screen.h>
#include <proc.h>
#else
#include <sys/types.h>
#ifndef __WIN__
#include <sys/wait.h>
#include <unistd.h>
#else
#include <direct.h>
#include <stdlib.h>
#include <stdio.h>
#endif
#endif
#include <ctype.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include "my_manage.h"
#ifndef __NETWARE__
#define ASSERT assert
extern char **environ;
#endif
/******************************************************************************
macros
******************************************************************************/
/******************************************************************************
global variables
******************************************************************************/
/******************************************************************************
functions
******************************************************************************/
/******************************************************************************
init_args()
Init an argument list.
******************************************************************************/
void init_args(arg_list_t *al)
{
ASSERT(al != NULL);
al->argc = 0;
al->size = ARG_BUF;
al->argv = malloc(al->size * sizeof(char *));
ASSERT(al->argv != NULL);
return;
}
/******************************************************************************
add_arg()
Add an argument to a list.
******************************************************************************/
void add_arg(arg_list_t *al, const char *format, ...)
{
va_list ap;
char temp[PATH_MAX];
ASSERT(al != NULL);
// increase size
if (al->argc >= (int)al->size)
{
al->size += ARG_BUF;
al->argv = realloc(al->argv, al->size * sizeof(char *));
ASSERT(al->argv != NULL);
}
if (format)
{
va_start(ap, format);
vsprintf(temp, format, ap);
va_end(ap);
al->argv[al->argc] = malloc(strlen(temp)+1);
ASSERT(al->argv[al->argc] != NULL);
strcpy(al->argv[al->argc], temp);
++(al->argc);
}
else
{
al->argv[al->argc] = NULL;
}
return;
}
/******************************************************************************
free_args()
Free an argument list.
******************************************************************************/
void free_args(arg_list_t *al)
{
int i;
ASSERT(al != NULL);
for(i = 0; i < al->argc; i++)
{
ASSERT(al->argv[i] != NULL);
free(al->argv[i]);
al->argv[i] = NULL;
}
free(al->argv);
al->argc = 0;
al->argv = NULL;
return;
}
/******************************************************************************
sleep_until_file_deleted()
Sleep until the given file is no longer found.
******************************************************************************/
#ifndef __WIN__
int sleep_until_file_deleted(char *pid_file)
#else
int sleep_until_file_deleted(HANDLE pid_file)
#endif
{
int err;
#ifndef __WIN__
struct stat buf;
int i;
for(i = 0; (i < TRY_MAX) && (err = !stat(pid_file, &buf)); i++) sleep(1);
if (err != 0) err = errno;
#else
err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT);
#endif
return err;
}
/******************************************************************************
sleep_until_file_exists()
Sleep until the given file exists.
******************************************************************************/
#ifndef __WIN__
int sleep_until_file_exists(char *pid_file)
#else
int sleep_until_file_exists(HANDLE pid_file)
#endif
{
int err;
#ifndef __WIN__
struct stat buf;
int i;
for(i = 0; (i < TRY_MAX) && (err = stat(pid_file, &buf)); i++) sleep(1);
if (err != 0) err = errno;
#else
err= (WaitForSingleObject(pid_file, TRY_MAX*1000) == WAIT_TIMEOUT);
#endif
return err;
}
/******************************************************************************
wait_for_server_start()
Wait for the server on the given port to start.
******************************************************************************/
int wait_for_server_start(char *bin_dir, char *mysqladmin_file, char *user, char *password, int port,char *tmp_dir)
{
arg_list_t al;
int err, i;
char trash[PATH_MAX];
// mysqladmin file
snprintf(trash, PATH_MAX, "%s/trash.out",tmp_dir);
// args
init_args(&al);
add_arg(&al, "%s", mysqladmin_file);
add_arg(&al, "--no-defaults");
add_arg(&al, "--port=%u", port);
add_arg(&al, "--user=%s", user);
add_arg(&al, "--password=%s", password);
add_arg(&al, "--silent");
//#ifdef NOT_USED
#ifndef __NETWARE__
add_arg(&al, "-O");
add_arg(&al, "connect_timeout=10");
add_arg(&al, "-w");
#endif
add_arg(&al, "--host=localhost");
#ifndef __NETWARE__
add_arg(&al, "--protocol=tcp");
#endif
add_arg(&al, "ping");
// NetWare does not support the connect timeout in the TCP/IP stack
// -- we will try the ping multiple times
#ifndef __WIN__
for(i = 0; (i < TRY_MAX)
&& (err = spawn(mysqladmin_file, &al, TRUE, NULL,
trash, NULL, NULL)); i++) sleep(1);
#else
err = spawn(mysqladmin_file, &al, TRUE, NULL,trash, NULL, NULL);
#endif
// free args
free_args(&al);
return err;
}
/******************************************************************************
spawn()
Spawn the given path with the given arguments.
******************************************************************************/
#ifdef __NETWARE__
int spawn(char *path, arg_list_t *al, int join, char *input,
char *output, char *error, char *pid_file)
{
pid_t pid;
int result = 0;
wiring_t wiring = { FD_UNUSED, FD_UNUSED, FD_UNUSED };
unsigned long flags = PROC_CURRENT_SPACE | PROC_INHERIT_CWD;
// open wiring
if (input)
wiring.infd = open(input, O_RDONLY);
if (output)
wiring.outfd = open(output, O_WRONLY | O_CREAT | O_TRUNC);
if (error)
wiring.errfd = open(error, O_WRONLY | O_CREAT | O_TRUNC);
// procve requires a NULL
add_arg(al, NULL);
// go
pid = procve(path, flags, NULL, &wiring, NULL, NULL, 0,
NULL, (const char **)al->argv);
// close wiring
if (wiring.infd != -1)
close(wiring.infd);
if (wiring.outfd != -1)
close(wiring.outfd);
if (wiring.errfd != -1)
close(wiring.errfd);
return result;
}
#elif __WIN__
int spawn(char *path, arg_list_t *al, int join, char *input,
char *output, char *error, HANDLE *pid)
{
intptr_t result;
int i;
STARTUPINFO startup_info;
PROCESS_INFORMATION process_information;
DWORD exit_code;
char win_args[1024]= "";
char command_line[1024]= "";
/*
Skip the first parameter
*/
for(i = 1; i < al->argc; i++)
{
ASSERT(al->argv[i] != NULL);
strcat(win_args,al->argv[i]);
strcat(win_args," ");
}
memset(&startup_info,0,sizeof(STARTUPINFO));
startup_info.cb = sizeof(STARTUPINFO);
if (input)
freopen(input, "rb", stdin);
if (output)
freopen(output, "wb", stdout);
if (error)
freopen(error, "wb", stderr);
result= CreateProcess(
path,
(LPSTR)&win_args,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&startup_info,
&process_information
);
if (result && process_information.hProcess)
{
if (join)
{
if (WaitForSingleObject(process_information.hProcess, mysqld_timeout) == WAIT_TIMEOUT)
{
exit_code= -1;
}
else
{
GetExitCodeProcess(process_information.hProcess, &exit_code);
}
CloseHandle(process_information.hProcess);
}
else
{
exit_code= 0;
}
if (pid != NULL)
*pid= process_information.hProcess;
}
else
{
exit_code= -1;
}
if (input)
freopen("CONIN$","rb",stdin);
if (output)
freopen("CONOUT$","wb",stdout);
if (error)
freopen("CONOUT$","wb",stderr);
return exit_code;
}
#else
int spawn(char *path, arg_list_t *al, int join, char *input,
char *output, char *error, char *pid_file)
{
pid_t pid;
int res_exec = 0;
int result = 0;
pid = fork();
if (pid == -1)
{
fprintf(stderr, "fork was't created\n");
/*
We can't create the fork...exit with error
*/
return EXIT_FAILURE;
}
if (pid > 0)
{
/*
The parent process is waiting for child process if join is not zero
*/
if (join)
{
waitpid(pid, &result, 0);
if (WIFEXITED(result) != 0)
{
result = WEXITSTATUS(result);
}
else
{
result = EXIT_FAILURE;
}
}
}
else
{
/*
Child process
*/
add_arg(al, NULL);
/*
Reassign streams
*/
if (input)
freopen(input, "r", stdin);
if (output)
freopen(output, "w", stdout);
if (error)
freopen(error, "w", stderr);
/* Spawn the process */
if ((res_exec = execve(path, al->argv, environ)) < 0)
{
exit(EXIT_FAILURE);
}
/*
Restore streams
*/
if (input)
freopen("/dev/tty", "r", stdin);
if (output)
freopen("/dev/tty", "w", stdout);
if (error)
freopen("/dev/tty", "w", stderr);
exit(0);
}
return result;
}
#endif
/******************************************************************************
stop_server()
Stop the server with the given port and pid file.
******************************************************************************/
#ifndef __WIN__
int stop_server(char *bin_dir, char *mysqladmin_file, char *user, char *password, int port,
char *pid_file,char *tmp_dir)
#else
int stop_server(char *bin_dir, char *mysqladmin_file, char *user, char *password, int port,
HANDLE pid_file,char *tmp_dir)
#endif
{
arg_list_t al;
int err = 0;
char trash[PATH_MAX];
snprintf(trash, PATH_MAX, "%s/trash.out",tmp_dir);
// args
init_args(&al);
add_arg(&al, "%s", mysqladmin_file);
add_arg(&al, "--no-defaults");
add_arg(&al, "--port=%u", port);
add_arg(&al, "--user=%s", user);
add_arg(&al, "--password=%s", password);
add_arg(&al, "-O");
add_arg(&al, "shutdown_timeout=20");
#ifndef __NETWARE__
add_arg(&al, "--protocol=tcp");
#endif
add_arg(&al, "shutdown");
// spawn
if ((err = spawn(mysqladmin_file, &al, TRUE, NULL,
trash, NULL, NULL)) == 0)
{
sleep_until_file_deleted(pid_file);
}
else
{
#ifndef __WIN__
pid_t pid = get_server_pid(pid_file);
// shutdown failed - kill server
kill_server(pid);
sleep(TRY_MAX);
// remove pid file if possible
err = remove(pid_file);
#else
TerminateProcess(pid_file,err);
#endif
}
// free args
free_args(&al);
return err;
}
/******************************************************************************
get_server_pid()
Get the VM id with the given pid file.
******************************************************************************/
#ifndef __WIN__
pid_t get_server_pid(char *pid_file)
{
char buf[PATH_MAX];
int fd, err;
char *p;
pid_t id = 0;
// discover id
fd = open(pid_file, O_RDONLY);
err = read(fd, buf, PATH_MAX);
close(fd);
if (err > 0)
{
// terminate string
if ((p = strchr(buf, '\n')) != NULL)
{
*p = '\0';
// check for a '\r'
if ((p = strchr(buf, '\r')) != NULL)
{
*p = '\0';
}
}
else
{
buf[err] = '\0';
}
id = strtol(buf, NULL, 0);
}
return id;
}
/******************************************************************************
kill_server()
Force a kill of the server with the given pid.
******************************************************************************/
void kill_server(pid_t pid)
{
if (pid > 0)
{
#if !defined(__NETWARE__)
/* Send SIGTERM to pid */
kill(pid, SIGTERM);
#else /* __NETWARE__ */
/* destroy vm */
NXVmDestroy(pid);
#endif
}
}
#endif
/******************************************************************************
del_tree()
Delete the directory and subdirectories.
******************************************************************************/
void del_tree(char *dir)
{
#ifndef __WIN__
DIR *parent = opendir(dir);
struct dirent *entry;
char temp[PATH_MAX];
if (parent == NULL)
{
return;
}
while((entry = readdir(parent)) != NULL)
{
// create long name
snprintf(temp, PATH_MAX, "%s/%s", dir, entry->d_name);
if (entry->d_name[0] == '.')
{
// Skip
}
else
if (S_ISDIR(entry->d_type))
{
// delete subdirectory
del_tree(temp);
}
else
{
// remove file
remove(temp);
}
}
// remove directory
rmdir(dir);
#else
struct _finddata_t parent;
intptr_t handle;
char temp[PATH_MAX];
char mask[PATH_MAX];
snprintf(mask,MAX_PATH,"%s/*.*",dir);
if ((handle=_findfirst(mask,&parent)) == -1L)
{
return;
}
do
{
// create long name
snprintf(temp, PATH_MAX, "%s/%s", dir, parent.name);
if (parent.name[0] == '.')
{
// Skip
}
else
if (parent.attrib & _A_SUBDIR)
{
// delete subdirectory
del_tree(temp);
}
else
{
// remove file
remove(temp);
}
} while (_findnext(handle,&parent) == 0);
_findclose(handle);
// remove directory
_rmdir(dir);
#endif
}
/******************************************************************************
removef()
******************************************************************************/
int removef(const char *format, ...)
{
#ifdef __NETWARE__
va_list ap;
char path[PATH_MAX];
va_start(ap, format);
vsnprintf(path, PATH_MAX, format, ap);
va_end(ap);
return remove(path);
#eldef __WIN__
{
va_list ap;
char path[PATH_MAX];
struct _finddata_t parent;
intptr_t handle;
char temp[PATH_MAX];
char *p;
va_start(ap, format);
vsnprintf(path, PATH_MAX, format, ap);
va_end(ap);
p = path + strlen(path);
while (*p != '\\' && *p != '/' && p > path) p--;
if ((handle=_findfirst(path,&parent)) == -1L)
{
/*
if there is not files....it's ok.
*/
return 0;
}
*p = '\0';
do
{
if (! (parent.attrib & _A_SUBDIR))
{
snprintf(temp, PATH_MAX, "%s/%s", path, parent.name);
remove(temp);
}
}while (_findnext(handle,&parent) == 0);
_findclose(handle);
}
#else
DIR *parent;
struct dirent *entry;
char temp[PATH_MAX];
va_list ap;
char path[PATH_MAX];
char *p;
/*
Get path with mask
*/
va_start(ap, format);
vsnprintf(path, PATH_MAX, format, ap);
va_end(ap);
p = path + strlen(path);
while (*p != '\\' && *p != '/' && p > path) p--;
*p = '\0';
p++;
parent = opendir(path);
if (parent == NULL)
{
return;
}
while((entry = readdir(parent)) != NULL)
{
/*
entry is not directory and entry matches with mask
*/
if (!S_ISDIR(entry->d_type) && !fnmatch(p, entry->d_name,0))
{
// create long name
snprintf(temp, PATH_MAX, "%s/%s", path, entry->d_name);
// Delete only files
remove(temp);
}
}
#endif
return 0;
}
/******************************************************************************
get_basedir()
******************************************************************************/
void get_basedir(char *argv0, char *basedir)
{
char temp[PATH_MAX];
char *p;
int position;
ASSERT(argv0 != NULL);
ASSERT(basedir != NULL);
strcpy(temp, strlwr(argv0));
while((p = strchr(temp, '\\')) != NULL) *p = '/';
if ((position = strinstr(temp, "/bin/")) != 0)
{
p = temp + position;
*p = '\0';
strcpy(basedir, temp);
}
}
#if !defined(__NETWARE__) && !defined(__WIN__)
char *strlwr(const char *s)
{
return s;
}
#endif
uint strinstr(reg1 const char *str,reg4 const char *search)
{
reg2 my_string i,j;
my_string start = (my_string) str;
skipp:
while (*str != '\0')
{
if (*str++ == *search)
{
i=(my_string) str; j= (my_string) search+1;
while (*j)
if (*i++ != *j++) goto skipp;
return ((uint) (str - start));
}
}
return (0);
}
/******************************************************************************
remove_empty_file()
******************************************************************************/
void remove_empty_file(const char *file_name)
{
struct stat file;
if (!stat(file_name,&file))
{
if (!file.st_size)
remove(file_name);
}
}
/*
Copyright (c) 2002 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
*/
#ifndef _MY_MANAGE
#define _MY_MANAGE
/******************************************************************************
includes
******************************************************************************/
#include <stdlib.h>
#ifndef __WIN__
#include <unistd.h>
#endif
#ifndef __NETWARE__
#include <string.h>
#include <my_global.h>
#include <m_string.h>
#ifndef __WIN__
#define strnicmp strncasecmp
char *strlwr(const char *s);
#else
int my_vsnprintf_(char *to, size_t n, const char* value, ...);
#endif
#endif
/******************************************************************************
macros
******************************************************************************/
#define ARG_BUF 10
#define TRY_MAX 5
#ifdef __WIN__
#define PATH_MAX _MAX_PATH
#define NAME_MAX _MAX_FNAME
#define kill(A,B) TerminateProcess((HANDLE)A,0)
#define NOT_NEED_PID 0
#define MASTER_PID 1
#define SLAVE_PID 2
#define mysqld_timeout 60000
int pid_mode;
bool run_server;
bool skip_first_param;
#define snprintf _snprintf
#define vsnprintf _vsnprintf
#endif
/******************************************************************************
structures
******************************************************************************/
typedef struct
{
int argc;
char **argv;
size_t size;
} arg_list_t;
#ifdef __WIN__
typedef int pid_t;
#endif
/******************************************************************************
global variables
******************************************************************************/
/******************************************************************************
prototypes
******************************************************************************/
void init_args(arg_list_t *);
void add_arg(arg_list_t *, const char *, ...);
void free_args(arg_list_t *);
#ifndef __WIN__
int sleep_until_file_exists(char *);
int sleep_until_file_deleted(char *);
#else
int sleep_until_file_exists(HANDLE);
int sleep_until_file_deleted(HANDLE);
#endif
int wait_for_server_start(char *, char *, char *, char *, int,char *);
#ifndef __WIN__
int spawn(char *, arg_list_t *, int, char *, char *, char *, char *);
#else
int spawn(char *, arg_list_t *, int , char *, char *, char *, HANDLE *);
#endif
#ifndef __WIN__
int stop_server(char *, char *, char *, char *, int, char *,char *);
pid_t get_server_pid(char *);
void kill_server(pid_t pid);
#else
int stop_server(char *, char *, char *, char *, int, HANDLE,char *);
#endif
void del_tree(char *);
int removef(const char *, ...);
void get_basedir(char *, char *);
void remove_empty_file(const char *file_name);
#endif /* _MY_MANAGE */
/*
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
/*
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
......@@ -355,9 +355,9 @@ t collation(t)
aus Osnabrck utf8_general_ci
SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrueck');
t collation(t)
SELECT t, collation(t),MATCH t AGAINST ('Osnabruck') FROM t1 WHERE MATCH t AGAINST ('Osnabruck');
t collation(t) MATCH t AGAINST ('Osnabruck')
aus Osnabrck utf8_general_ci 1.591139793396
SELECT t, collation(t),FORMAT(MATCH t AGAINST ('Osnabruck'),6) FROM t1 WHERE MATCH t AGAINST ('Osnabruck');
t collation(t) FORMAT(MATCH t AGAINST ('Osnabruck'),6)
aus Osnabrck utf8_general_ci 1.591140
alter table t1 modify t varchar(200) collate latin1_german2_ci not null;
Warnings:
Warning 1265 Data truncated for column 't' at row 3
......
......@@ -6,53 +6,53 @@ FULLTEXT(message)
) comment = 'original testcase by sroussey@network54.com';
INSERT INTO t1 (message) VALUES ("Testing"),("table"),("testbug"),
("steve"),("is"),("cool"),("steve is cool");
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve');
a MATCH (message) AGAINST ('steve')
4 0.90587323904037
7 0.89568990468979
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE MATCH (message) AGAINST ('steve');
a FORMAT(MATCH (message) AGAINST ('steve'),6)
4 0.905873
7 0.895690
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve');
a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
4 1
7 1
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
a MATCH (message) AGAINST ('steve')
4 0.90587323904037
7 0.89568990468979
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
a FORMAT(MATCH (message) AGAINST ('steve'),6)
4 0.905873
7 0.895690
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
4 1
7 1
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve') ORDER BY a;
a MATCH (message) AGAINST ('steve')
4 0.90587323904037
7 0.89568990468979
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE MATCH (message) AGAINST ('steve') ORDER BY a;
a FORMAT(MATCH (message) AGAINST ('steve'),6)
4 0.905873
7 0.895690
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a;
a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
4 1
7 1
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve') ORDER BY a DESC;
a MATCH (message) AGAINST ('steve')
7 0.89568990468979
4 0.90587323904037
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve') ORDER BY a DESC;
a FORMAT(MATCH (message) AGAINST ('steve'),6)
7 0.895690
4 0.905873
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a DESC;
a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
7 1
4 1
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve') ORDER BY 1;
a MATCH (message) AGAINST ('steve')
7 0.89568990468979
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve') ORDER BY 1;
a FORMAT(MATCH (message) AGAINST ('steve'),6)
7 0.895690
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY 1;
a MATCH (message) AGAINST ('steve' IN BOOLEAN MODE)
7 1
SELECT a, MATCH (message) AGAINST ('steve') as rel FROM t1 ORDER BY rel;
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) as rel FROM t1 ORDER BY rel;
a rel
1 0
2 0
3 0
5 0
6 0
7 0.89568990468979
4 0.90587323904037
1 0.000000
2 0.000000
3 0.000000
5 0.000000
6 0.000000
7 0.895690
4 0.905873
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
a rel
1 0
......
......@@ -22,14 +22,14 @@ select * from t1;
f1 f2
10 10
100000 100000
1.23457e+09 1234567890
1.23457e+9 1234567890
1e+10 10000000000
1e+15 1e+15
1e+20 1e+20
3.40282e+38 1e+50
3.40282e+38 1e+150
-10 -10
1e-05 1e-05
1e-5 1e-5
1e-10 1e-10
1e-15 1e-15
1e-20 1e-20
......
......@@ -279,7 +279,7 @@ SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabr
SET NAMES latin1;
SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrck');
SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrueck');
SELECT t, collation(t),MATCH t AGAINST ('Osnabruck') FROM t1 WHERE MATCH t AGAINST ('Osnabruck');
SELECT t, collation(t),FORMAT(MATCH t AGAINST ('Osnabruck'),6) FROM t1 WHERE MATCH t AGAINST ('Osnabruck');
#alter table t1 modify t text character set latin1 collate latin1_german2_ci not null;
alter table t1 modify t varchar(200) collate latin1_german2_ci not null;
SELECT t, collation(t) FROM t1 WHERE MATCH t AGAINST ('Osnabrck');
......
......@@ -10,25 +10,25 @@ CREATE TABLE t1 (
INSERT INTO t1 (message) VALUES ("Testing"),("table"),("testbug"),
("steve"),("is"),("cool"),("steve is cool");
# basic MATCH
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve');
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE MATCH (message) AGAINST ('steve');
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve');
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE);
# MATCH + ORDER BY (with ft-ranges)
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE MATCH (message) AGAINST ('steve') ORDER BY a;
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE MATCH (message) AGAINST ('steve') ORDER BY a;
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a;
# MATCH + ORDER BY (with normal ranges) + UNIQUE
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve') ORDER BY a DESC;
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve') ORDER BY a DESC;
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a in (2,7,4) and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY a DESC;
# MATCH + ORDER BY + UNIQUE (const_table)
SELECT a, MATCH (message) AGAINST ('steve') FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve') ORDER BY 1;
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve') ORDER BY 1;
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) FROM t1 WHERE a=7 and MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) ORDER BY 1;
# ORDER BY MATCH
SELECT a, MATCH (message) AGAINST ('steve') as rel FROM t1 ORDER BY rel;
SELECT a, FORMAT(MATCH (message) AGAINST ('steve'),6) as rel FROM t1 ORDER BY rel;
SELECT a, MATCH (message) AGAINST ('steve' IN BOOLEAN MODE) as rel FROM t1 ORDER BY rel;
drop table t1;
......
......@@ -1110,6 +1110,7 @@ show create table t2;
drop table t2;
# Test error handling
--replace_result \\ /
--error 1005
create table t2 (id int(11) not null, id2 int(11) not null, constraint t1_id_fk foreign key (id2,id) references t1 (id)) engine = innodb;
......
......@@ -99,46 +99,57 @@ create table t1(number int auto_increment primary key, original_value varchar(50
set @value= "aa";
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= "1aa";
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= "aa1";
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= "1e+1111111111a";
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= "-1e+1111111111a";
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= 1e+1111111111;
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= -1e+1111111111;
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= 1e+111;
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= -1e+111;
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= 1;
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
set @value= -1;
insert into t1 values(null,@value,@value,@value,@value,@value,@value,@value,@value,@value);
--replace_result e-0 e- e+0 e+
--query_vertical select * from t1 where number =last_insert_id()
drop table t1;
......
......@@ -6,7 +6,9 @@
drop table if exists t1;
--enable_warnings
--replace_result e-0 e- e+0 e+
SELECT 10,10.0,10.,.1e+2,100.0e-1;
--replace_result e-00 e-0
SELECT 6e-05, -6e-05, --6e-05, -6e-05+1.000000;
SELECT 1e1,1.e1,1.0e1,1e+1,1.e+1,1.0e+1,1e-1,1.e-1,1.0e-1;
......@@ -14,6 +16,7 @@ create table t1 (f1 float(24),f2 float(52));
show full columns from t1;
insert into t1 values(10,10),(1e+5,1e+5),(1234567890,1234567890),(1e+10,1e+10),(1e+15,1e+15),(1e+20,1e+20),(1e+50,1e+50),(1e+150,1e+150);
insert into t1 values(-10,-10),(1e-5,1e-5),(1e-10,1e-10),(1e-15,1e-15),(1e-20,1e-20),(1e-50,1e-50),(1e-150,1e-150);
--replace_result e-0 e- e+0 e+
select * from t1;
drop table t1;
......
......@@ -8,6 +8,7 @@ drop table if exists t1,t2;
set @`test`=1,@TEST=3,@select=2,@t5=1.23456;
select @test,@`select`,@TEST,@not_used;
set @test_int=10,@test_double=1e-10,@test_string="abcdeghi",@test_string2="abcdefghij",@select=NULL;
--replace_result e-0 e- e+0 e+
select @test_int,@test_double,@test_string,@test_string2,@select;
set @test_int="hello",@test_double="hello",@test_string="hello",@test_string2="hello";
select @test_int,@test_double,@test_string,@test_string2;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment