4581
static struct my_option my_long_options[] =
4583
{"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
4585
{"basedir", 'b', "Basedir for tests.", (char**) &opt_basedir,
4586
(char**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4587
{"character-sets-dir", OPT_CHARSETS_DIR,
4588
"Directory where character sets are.", (char**) &opt_charsets_dir,
4589
(char**) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4590
{"database", 'D', "Database to use.", (char**) &opt_db, (char**) &opt_db, 0,
4591
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4592
{"host", 'h', "Connect to host.", (char**) &opt_host, (char**) &opt_host, 0,
4593
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4594
{"include", 'i', "Include SQL before each test case.", (char**) &opt_include,
4595
(char**) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4596
{"testdir", OPT_TESTDIR, "Path to use to search for test files",
4597
(char**) &opt_testdir,
4598
(char**) &opt_testdir, 0,GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4599
{"logdir", OPT_LOG_DIR, "Directory for log files", (char**) &opt_logdir,
4600
(char**) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4601
{"mark-progress", OPT_MARK_PROGRESS,
4602
"Write linenumber and elapsed time to <testname>.progress ",
4603
(char**) &opt_mark_progress, (char**) &opt_mark_progress, 0,
4604
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4605
{"max-connect-retries", OPT_MAX_CONNECT_RETRIES,
4606
"Max number of connection attempts when connecting to server",
4607
(char**) &opt_max_connect_retries, (char**) &opt_max_connect_retries, 0,
4608
GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0},
4609
{"mysql", 'm', N_("Use MySQL Protocol."),
4610
(char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
4612
{"password", 'P', "Password to use when connecting to server.",
4613
0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
4614
{"port", 'p', "Port number to use for connection or 0 for default to, in "
4615
"order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
4616
"built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
4617
0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4618
{"quiet", 's', "Suppress all normal output.", (char**) &silent,
4619
(char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4620
{"record", 'r', "Record output of test_file into result file.",
4621
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
4622
{"result-file", 'R', "Read/Store result from/in this file.",
4623
(char**) &result_file_name, (char**) &result_file_name, 0,
4624
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4625
{"silent", 's', "Suppress all normal output. Synonym for --quiet.",
4626
(char**) &silent, (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4627
{"sleep", 'T', "Sleep always this many seconds on sleep commands.",
4628
(char**) &opt_sleep, (char**) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0,
4630
{"tail-lines", OPT_TAIL_LINES,
4631
"Number of lines of the resul to include in a failure report",
4632
(char**) &opt_tail_lines, (char**) &opt_tail_lines, 0,
4633
GET_INT, REQUIRED_ARG, 0, 0, 10000, 0, 0, 0},
4634
{"test-file", 'x', "Read test from/in this file (default stdin).",
4635
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4636
{"timer-file", 'm', "File where the timing in micro seconds is stored.",
4637
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4638
{"tmpdir", 't', "Temporary directory where sockets are put.",
4639
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4640
{"user", 'u', "User for login.", (char**) &opt_user, (char**) &opt_user, 0,
4641
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
4642
{"verbose", 'v', "Write more.", (char**) &verbose, (char**) &verbose, 0,
4643
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
4644
{"version", 'V', "Output version information and exit.",
4645
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
4646
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
4650
static void print_version(void)
4652
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,MTEST_VERSION,
4653
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
4656
static void usage(void)
4659
printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
4660
printf("Drizzle version modified by Brian, Jay, Monty Taylor, PatG and Stewart\n");
4661
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
4662
printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n");
4663
printf("Usage: %s [OPTIONS] [database] < test_file\n", internal::my_progname);
4664
my_print_help(my_long_options);
4665
printf(" --no-defaults Don't read default options from any options file.\n");
4666
my_print_variables(my_long_options);
4669
int get_one_option(int optid, const struct my_option *, char *argument)
4671
char *endchar= NULL;
4672
uint64_t temp_drizzle_port= 0;
4680
char buff[FN_REFLEN];
4681
if (!internal::test_if_hard_path(argument))
4683
sprintf(buff,"%s%s",opt_basedir,argument);
4686
internal::fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
4687
assert(cur_file == file_stack && cur_file->file == 0);
4688
if (!(cur_file->file= fopen(buff, "r")))
4690
fprintf(stderr, _("Could not open '%s' for reading: errno = %d"), buff, errno);
4691
return EXIT_ARGUMENT_INVALID;
4693
if (!(cur_file->file_name= strdup(buff)))
4695
fprintf(stderr, _("Out of memory"));
4696
return EXIT_OUT_OF_MEMORY;
4698
cur_file->lineno= 1;
4703
static char buff[FN_REFLEN];
4704
if (!internal::test_if_hard_path(argument))
4706
sprintf(buff,"%s%s",opt_basedir,argument);
4709
internal::fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
4711
unlink(timer_file); /* Ignore error, may not exist */
4715
temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
4716
/* if there is an alpha character this is not a valid port */
4717
if (strlen(endchar) != 0)
4719
fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
4720
return EXIT_ARGUMENT_INVALID;
4722
/* If the port number is > 65535 it is not a valid port
4723
This also helps with potential data loss casting unsigned long to a
4725
if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
4727
fprintf(stderr, _("Value supplied for port is not valid.\n"));
4728
return EXIT_ARGUMENT_INVALID;
4732
opt_port= (uint32_t) temp_drizzle_port;
4740
opt_pass = strdup(argument);
4741
if (opt_pass == NULL)
4743
fprintf(stderr, _("Out of memory"));
4744
return EXIT_OUT_OF_MEMORY;
4748
/* Overwriting password with 'x' */
4757
strncpy(TMPDIR, argument, sizeof(TMPDIR));
4770
static int parse_args(int argc, char **argv)
4772
internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
4775
if ((handle_options(&argc, &argv, my_long_options, get_one_option)))
4786
opt_pass= client_get_tty_password(NULL); /* purify tested */
4564
4792
Write the content of str into file
5373
static void check_retries(uint32_t in_opt_max_connect_retries)
5375
if (in_opt_max_connect_retries > 10000 || opt_max_connect_retries<1)
5377
cout << N_("Error: Invalid Value for opt_max_connect_retries");
5380
opt_max_connect_retries= in_opt_max_connect_retries;
5383
static void check_tail_lines(uint32_t in_opt_tail_lines)
5385
if (in_opt_tail_lines > 10000)
5387
cout << N_("Error: Invalid Value for opt_tail_lines");
5390
opt_tail_lines= in_opt_tail_lines;
5393
static void check_sleep(int32_t in_opt_sleep)
5395
if (in_opt_sleep < -1)
5397
cout << N_("Error: Invalid Value for opt_sleep");
5400
opt_sleep= in_opt_sleep;
5403
5567
int main(int argc, char **argv)
5407
5569
struct st_command *command;
5408
5570
bool q_send_flag= 0, abort_flag= 0;
5409
5571
uint32_t command_executed= 0, last_command_executed= 0;
5410
5572
string save_file("");
5411
5573
struct stat res_info;
5415
internal::my_init();
5417
po::options_description commandline_options("Options used only in command line");
5418
commandline_options.add_options()
5419
("help,?", "Display this help and exit.")
5420
("mark-progress", po::value<bool>(&opt_mark_progress)->default_value(false)->zero_tokens(),
5421
"Write linenumber and elapsed time to <testname>.progress ")
5422
("sleep,T", po::value<int32_t>(&opt_sleep)->default_value(-1)->notifier(&check_sleep),
5423
"Sleep always this many seconds on sleep commands.")
5424
("test-file,x", po::value<string>(),
5425
"Read test from/in this file (default stdin).")
5426
("timer-file,f", po::value<string>(),
5427
"File where the timing in micro seconds is stored.")
5428
("tmpdir,t", po::value<string>(),
5429
"Temporary directory where sockets are put.")
5430
("verbose,v", po::value<bool>(&verbose)->default_value(false),
5432
("version,V", "Output version information and exit.")
5433
("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
5434
"Configuration file defaults are not used if no-defaults is set")
5437
po::options_description test_options("Options specific to the drizzleimport");
5438
test_options.add_options()
5439
("basedir,b", po::value<string>(&opt_basedir)->default_value(""),
5440
"Basedir for tests.")
5441
("character-sets-dir", po::value<string>(&opt_charsets_dir)->default_value(""),
5442
"Directory where character sets are.")
5443
("database,D", po::value<string>(&opt_db)->default_value(""),
5445
("include,i", po::value<string>(&opt_include)->default_value(""),
5446
"Include SQL before each test case.")
5447
("testdir", po::value<string>(&opt_testdir)->default_value(""),
5448
"Path to use to search for test files")
5449
("logdir", po::value<string>(&opt_logdir)->default_value(""),
5450
"Directory for log files")
5451
("max-connect-retries", po::value<uint32_t>(&opt_max_connect_retries)->default_value(500)->notifier(&check_retries),
5452
"Max number of connection attempts when connecting to server")
5453
("quiet,s", po::value<bool>(&silent)->default_value(false)->zero_tokens(),
5454
"Suppress all normal output.")
5455
("record,r", "Record output of test_file into result file.")
5456
("result-file,R", po::value<string>(&result_file_name)->default_value(""),
5457
"Read/Store result from/in this file.")
5458
("silent,s", po::value<bool>(&silent)->default_value(false)->zero_tokens(),
5459
"Suppress all normal output. Synonym for --quiet.")
5460
("tail-lines", po::value<uint32_t>(&opt_tail_lines)->default_value(0)->notifier(&check_tail_lines),
5461
"Number of lines of the resul to include in a failure report")
5464
po::options_description client_options("Options specific to the client");
5465
client_options.add_options()
5467
("host,h", po::value<string>(&opt_host)->default_value("localhost"),
5469
("password,P", po::value<string>(&password)->default_value("PASSWORD_SENTINEL"),
5470
"Password to use when connecting to server.")
5471
("port,p", po::value<uint32_t>(&opt_port)->default_value(0),
5472
"Port number to use for connection or 0 for default")
5473
("protocol", po::value<string>(&opt_protocol),
5474
"The protocol of connection (mysql or drizzle).")
5475
("user,u", po::value<string>(&opt_user)->default_value(""),
5479
po::positional_options_description p;
5480
p.add("database", 1);
5482
po::options_description long_options("Allowed Options");
5483
long_options.add(commandline_options).add(test_options).add(client_options);
5485
std::string system_config_dir_test(SYSCONFDIR);
5486
system_config_dir_test.append("/drizzle/drizzletest.cnf");
5488
std::string system_config_dir_client(SYSCONFDIR);
5489
system_config_dir_client.append("/drizzle/client.cnf");
5491
std::string user_config_dir((getenv("XDG_CONFIG_HOME")? getenv("XDG_CONFIG_HOME"):"~/.config"));
5493
if (user_config_dir.compare(0, 2, "~/") == 0)
5495
const char *homedir= getenv("HOME");
5496
if (homedir != NULL)
5497
user_config_dir.replace(0, 1, homedir);
5500
po::variables_map vm;
5502
// Disable allow_guessing
5503
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
5505
po::store(po::command_line_parser(argc, argv).options(long_options).
5506
style(style).positional(p).extra_parser(parse_password_arg).run(),
5509
if (! vm["no-defaults"].as<bool>())
5511
std::string user_config_dir_test(user_config_dir);
5512
user_config_dir_test.append("/drizzle/drizzletest.cnf");
5514
std::string user_config_dir_client(user_config_dir);
5515
user_config_dir_client.append("/drizzle/client.cnf");
5517
ifstream user_test_ifs(user_config_dir_test.c_str());
5518
po::store(parse_config_file(user_test_ifs, test_options), vm);
5520
ifstream user_client_ifs(user_config_dir_client.c_str());
5521
po::store(parse_config_file(user_client_ifs, client_options), vm);
5523
ifstream system_test_ifs(system_config_dir_test.c_str());
5524
store(parse_config_file(system_test_ifs, test_options), vm);
5526
ifstream system_client_ifs(system_config_dir_client.c_str());
5527
po::store(parse_config_file(system_client_ifs, client_options), vm);
5532
5578
/* Init expected errors */
5533
5579
memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
5563
5611
ds_progress.reserve(2048);
5564
5612
ds_warning_messages.reserve(2048);
5567
if (vm.count("record"))
5572
if (vm.count("test-file"))
5574
string tmp= vm["test-file"].as<string>();
5575
char buff[FN_REFLEN];
5576
if (!internal::test_if_hard_path(tmp.c_str()))
5578
snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),tmp.c_str());
5581
internal::fn_format(buff, tmp.c_str(), "", "", MY_UNPACK_FILENAME);
5582
assert(cur_file == file_stack.data() && cur_file->file == 0);
5583
if (!(cur_file->file= fopen(buff, "r")))
5585
fprintf(stderr, _("Could not open '%s' for reading: errno = %d"), buff, errno);
5586
return EXIT_ARGUMENT_INVALID;
5588
if (!(cur_file->file_name= strdup(buff)))
5590
fprintf(stderr, _("Out of memory"));
5591
return EXIT_OUT_OF_MEMORY;
5593
cur_file->lineno= 1;
5596
if (vm.count("timer-file"))
5598
string tmp= vm["timer-file"].as<string>().c_str();
5599
static char buff[FN_REFLEN];
5600
if (!internal::test_if_hard_path(tmp.c_str()))
5602
snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),tmp.c_str());
5605
internal::fn_format(buff, tmp.c_str(), "", "", MY_UNPACK_FILENAME);
5607
unlink(timer_file); /* Ignore error, may not exist */
5610
if (vm.count("protocol"))
5612
std::transform(opt_protocol.begin(), opt_protocol.end(),
5613
opt_protocol.begin(), ::tolower);
5615
if (not opt_protocol.compare("mysql"))
5616
use_drizzle_protocol=false;
5617
else if (not opt_protocol.compare("drizzle"))
5618
use_drizzle_protocol=true;
5621
cout << _("Error: Unknown protocol") << " '" << opt_protocol << "'" << endl;
5626
if (vm.count("port"))
5628
/* If the port number is > 65535 it is not a valid port
5629
This also helps with potential data loss casting unsigned long to a
5631
if (opt_port > 65535)
5633
fprintf(stderr, _("Value supplied for port is not valid.\n"));
5634
exit(EXIT_ARGUMENT_INVALID);
5638
if( vm.count("password") )
5640
if (!opt_password.empty())
5641
opt_password.erase();
5642
if (password == PASSWORD_SENTINEL)
5648
opt_password= password;
5649
tty_password= false;
5657
if (vm.count("tmpdir"))
5659
strncpy(TMPDIR, vm["tmpdir"].as<string>().c_str(), sizeof(TMPDIR));
5662
if (vm.count("version"))
5664
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,MTEST_VERSION,
5665
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
5669
if (vm.count("help"))
5671
printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,MTEST_VERSION,
5672
drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
5673
printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
5674
printf("Drizzle version modified by Brian, Jay, Monty Taylor, PatG and Stewart\n");
5675
printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
5676
printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n");
5677
printf("Usage: %s [OPTIONS] [database] < test_file\n", internal::my_progname);
5683
opt_pass= client_get_tty_password(NULL); /* purify tested */
5614
parse_args(argc, argv);
5686
5616
server_initialized= 1;
5687
if (cur_file == file_stack.data() && cur_file->file == 0)
5617
if (cur_file == file_stack && cur_file->file == 0)
5689
5619
cur_file->file= stdin;
5690
5620
cur_file->file_name= strdup("<stdin>");