Merge lp:~vjsamuel/drizzle/refactor-drizzletest into lp:~drizzle-trunk/drizzle/development

Proposed by Vijay Samuel
Status: Merged
Approved by: Brian Aker
Approved revision: 1614
Merged at revision: 1624
Proposed branch: lp:~vjsamuel/drizzle/refactor-drizzletest
Merge into: lp:~drizzle-trunk/drizzle/development
Diff against target: 898 lines (+349/-268)
3 files modified
client/drizzle.cc (+1/-1)
client/drizzletest.cc (+347/-266)
client/include.am (+1/-1)
To merge this branch: bzr merge lp:~vjsamuel/drizzle/refactor-drizzletest
Reviewer Review Type Date Requested Status
Brian Aker Pending
Drizzle Developers Pending
Review via email: mp+27680@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'client/drizzle.cc'
2--- client/drizzle.cc 2010-06-09 21:36:07 +0000
3+++ client/drizzle.cc 2010-06-16 07:57:30 +0000
4@@ -1531,7 +1531,7 @@
5 po::variables_map vm;
6
7 po::positional_options_description p;
8- p.add("database", -1);
9+ p.add("database", 1);
10
11 po::store(po::command_line_parser(argc, argv).options(long_options).
12 positional(p).extra_parser(parse_password_arg).run(), vm);
13
14=== modified file 'client/drizzletest.cc'
15--- client/drizzletest.cc 2010-06-03 07:59:07 +0000
16+++ client/drizzletest.cc 2010-06-16 07:57:30 +0000
17@@ -44,6 +44,7 @@
18 #include <map>
19 #include <string>
20 #include <sstream>
21+#include <fstream>
22 #include <iostream>
23 #include <vector>
24 #include <algorithm>
25@@ -54,6 +55,7 @@
26 #include <sys/stat.h>
27 #include <sys/types.h>
28 #include <fcntl.h>
29+#include <boost/program_options.hpp>
30
31 #include PCRE_HEADER
32
33@@ -66,11 +68,12 @@
34 #include "drizzled/gettext.h"
35 #include "drizzled/drizzle_time.h"
36 #include "drizzled/charset.h"
37+#include <drizzled/configmake.h>
38
39 #ifndef DRIZZLE_RETURN_SERVER_GONE
40 #define DRIZZLE_RETURN_HANDSHAKE_FAILED DRIZZLE_RETURN_ERROR_CODE
41 #endif
42-
43+namespace po= boost::program_options;
44 using namespace std;
45 using namespace drizzled;
46
47@@ -95,14 +98,10 @@
48 };
49
50 static int record= 0, opt_sleep= -1;
51-static char *opt_db= NULL, *opt_pass= NULL;
52-const char *opt_user= NULL, *opt_host= NULL, *unix_sock= NULL,
53- *opt_basedir= "./";
54-const char *opt_logdir= "";
55-const char *opt_include= NULL, *opt_charsets_dir;
56-const char *opt_testdir= NULL;
57+static char *opt_pass= NULL;
58+const char *unix_sock= NULL;
59 static uint32_t opt_port= 0;
60-static int opt_max_connect_retries;
61+static uint32_t opt_max_connect_retries;
62 static bool silent= false, verbose= false;
63 static bool tty_password= false;
64 static bool opt_mark_progress= false;
65@@ -116,10 +115,21 @@
66 static bool server_initialized= false;
67 static bool is_windows= false;
68 static bool opt_mysql= false;
69-static char **default_argv;
70-static const char *load_default_groups[]= { "drizzletest", "client", 0 };
71+const string PASSWORD_SENTINEL("\0\0\0\0\0", 5);
72 static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer;
73
74+std::string opt_basedir,
75+ opt_charsets_dir,
76+ opt_db,
77+ opt_host,
78+ opt_include,
79+ opt_testdir,
80+ opt_logdir,
81+ password,
82+ opt_password,
83+ result_file_name,
84+ opt_user;
85+
86 static uint32_t start_lineno= 0; /* Start line of current command */
87
88 /* Number of lines of the result to include in failure report */
89@@ -189,7 +199,6 @@
90 master_pos_st master_pos;
91
92 /* if set, all results are concated and compared against this file */
93-const char *result_file_name= NULL;
94
95 typedef struct st_var
96 {
97@@ -920,7 +929,6 @@
98
99 free_all_replace();
100 free(opt_pass);
101- internal::free_defaults(default_argv);
102
103 return;
104 }
105@@ -1002,11 +1010,11 @@
106 }
107
108 /* Dump the result that has been accumulated so far to .log file */
109- if (result_file_name && ds_res.length())
110+ if (! result_file_name.empty() && ds_res.length())
111 dump_result_to_log_file(ds_res.c_str(), ds_res.length());
112
113 /* Dump warning messages */
114- if (result_file_name && ds_warning_messages.length())
115+ if (! result_file_name.empty() && ds_warning_messages.length())
116 dump_warning_messages();
117
118 /*
119@@ -1354,7 +1362,7 @@
120 if ((fd2= internal::my_open(fname, O_RDONLY, MYF(0))) < 0)
121 {
122 internal::my_close(fd, MYF(0));
123- if (opt_testdir != NULL)
124+ if (! opt_testdir.empty())
125 {
126 tmpfile= opt_testdir;
127 if (tmpfile[tmpfile.length()] != '/')
128@@ -1494,12 +1502,12 @@
129 const char* mess= "Result content mismatch\n";
130
131
132- assert(result_file_name);
133-
134- if (access(result_file_name, F_OK) != 0)
135- die("The specified result file does not exist: '%s'", result_file_name);
136-
137- switch (string_cmp(ds, result_file_name)) {
138+ assert(result_file_name.c_str());
139+
140+ if (access(result_file_name.c_str(), F_OK) != 0)
141+ die("The specified result file does not exist: '%s'", result_file_name.c_str());
142+
143+ switch (string_cmp(ds, result_file_name.c_str())) {
144 case RESULT_OK:
145 break; /* ok */
146 case RESULT_LENGTH_MISMATCH:
147@@ -1513,25 +1521,25 @@
148 */
149 char reject_file[FN_REFLEN];
150 size_t reject_length;
151- internal::dirname_part(reject_file, result_file_name, &reject_length);
152+ internal::dirname_part(reject_file, result_file_name.c_str(), &reject_length);
153
154 if (access(reject_file, W_OK) == 0)
155 {
156 /* Result file directory is writable, save reject file there */
157- internal::fn_format(reject_file, result_file_name, NULL,
158+ internal::fn_format(reject_file, result_file_name.c_str(), NULL,
159 ".reject", MY_REPLACE_EXT);
160 }
161 else
162 {
163 /* Put reject file in opt_logdir */
164- internal::fn_format(reject_file, result_file_name, opt_logdir,
165+ internal::fn_format(reject_file, result_file_name.c_str(), opt_logdir.c_str(),
166 ".reject", MY_REPLACE_DIR | MY_REPLACE_EXT);
167 }
168 str_to_file(reject_file, ds->c_str(), ds->length());
169
170 ds->erase(); /* Don't create a .log file */
171
172- show_diff(NULL, result_file_name, reject_file);
173+ show_diff(NULL, result_file_name.c_str(), reject_file);
174 die("%s",mess);
175 break;
176 }
177@@ -2147,7 +2155,7 @@
178
179 if (!internal::test_if_hard_path(name))
180 {
181- snprintf(buff, sizeof(buff), "%s%s",opt_basedir,name);
182+ snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),name);
183 name=buff;
184 }
185 internal::fn_format(buff, name, "", "", MY_UNPACK_FILENAME);
186@@ -2201,7 +2209,7 @@
187 ; /* Do nothing */
188 else
189 {
190- if (opt_testdir != NULL)
191+ if (! opt_testdir.empty())
192 {
193 string testdir(opt_testdir);
194 if (testdir[testdir.length()] != '/')
195@@ -3348,7 +3356,7 @@
196 if (*p)
197 *p++= 0;
198 command->last_argument= p;
199- if (opt_testdir != NULL)
200+ if (! opt_testdir.empty())
201 {
202 dest= opt_testdir;
203 if (dest[dest.length()] != '/')
204@@ -3685,16 +3693,16 @@
205 */
206
207 static void safe_connect(drizzle_con_st *con, const char *name,
208- const char *host, const char *user, const char *pass,
209- const char *db, int port)
210+ const string host, const string user, const char *pass,
211+ const string db, uint32_t port)
212 {
213- int failed_attempts= 0;
214+ uint32_t failed_attempts= 0;
215 static uint32_t connection_retry_sleep= 100000; /* Microseconds */
216 drizzle_return_t ret;
217
218- drizzle_con_set_tcp(con, host, port);
219- drizzle_con_set_auth(con, user, pass);
220- drizzle_con_set_db(con, db);
221+ drizzle_con_set_tcp(con, host.c_str(), port);
222+ drizzle_con_set_auth(con, user.c_str(), pass);
223+ drizzle_con_set_db(con, db.c_str());
224 while((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
225 {
226 /*
227@@ -3836,7 +3844,7 @@
228
229 static void do_connect(struct st_command *command)
230 {
231- int con_port= opt_port;
232+ uint32_t con_port= opt_port;
233 const char *con_options;
234 bool con_ssl= 0, con_compress= 0;
235 struct st_connection* con_slot;
236@@ -4496,8 +4504,6 @@
237 return;
238 }
239
240-
241-
242 /*
243 Create a command from a set of lines
244
245@@ -4577,217 +4583,6 @@
246 return(0);
247 }
248
249-
250-static struct option my_long_options[] =
251-{
252- {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG,
253- 0, 0, 0, 0, 0, 0},
254- {"basedir", 'b', "Basedir for tests.", (char**) &opt_basedir,
255- (char**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
256- {"character-sets-dir", OPT_CHARSETS_DIR,
257- "Directory where character sets are.", (char**) &opt_charsets_dir,
258- (char**) &opt_charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
259- {"database", 'D', "Database to use.", (char**) &opt_db, (char**) &opt_db, 0,
260- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
261- {"host", 'h', "Connect to host.", (char**) &opt_host, (char**) &opt_host, 0,
262- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
263- {"include", 'i', "Include SQL before each test case.", (char**) &opt_include,
264- (char**) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
265- {"testdir", OPT_TESTDIR, "Path to use to search for test files",
266- (char**) &opt_testdir,
267- (char**) &opt_testdir, 0,GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
268- {"logdir", OPT_LOG_DIR, "Directory for log files", (char**) &opt_logdir,
269- (char**) &opt_logdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
270- {"mark-progress", OPT_MARK_PROGRESS,
271- "Write linenumber and elapsed time to <testname>.progress ",
272- (char**) &opt_mark_progress, (char**) &opt_mark_progress, 0,
273- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
274- {"max-connect-retries", OPT_MAX_CONNECT_RETRIES,
275- "Max number of connection attempts when connecting to server",
276- (char**) &opt_max_connect_retries, (char**) &opt_max_connect_retries, 0,
277- GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0},
278- {"mysql", 'm', N_("Use MySQL Protocol."),
279- (char**) &opt_mysql, (char**) &opt_mysql, 0, GET_BOOL, NO_ARG, 1, 0, 0,
280- 0, 0, 0},
281- {"password", 'P', "Password to use when connecting to server.",
282- 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
283- {"port", 'p', "Port number to use for connection or 0 for default to, in "
284- "order of preference, drizzle.cnf, $DRIZZLE_TCP_PORT, "
285- "built-in default (" STRINGIFY_ARG(DRIZZLE_PORT) ").",
286- 0, 0, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
287- {"quiet", 's', "Suppress all normal output.", (char**) &silent,
288- (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
289- {"record", 'r', "Record output of test_file into result file.",
290- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
291- {"result-file", 'R', "Read/Store result from/in this file.",
292- (char**) &result_file_name, (char**) &result_file_name, 0,
293- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
294- {"silent", 's', "Suppress all normal output. Synonym for --quiet.",
295- (char**) &silent, (char**) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
296- {"sleep", 'T', "Sleep always this many seconds on sleep commands.",
297- (char**) &opt_sleep, (char**) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, -1, 0,
298- 0, 0, 0},
299- {"tail-lines", OPT_TAIL_LINES,
300- "Number of lines of the resul to include in a failure report",
301- (char**) &opt_tail_lines, (char**) &opt_tail_lines, 0,
302- GET_INT, REQUIRED_ARG, 0, 0, 10000, 0, 0, 0},
303- {"test-file", 'x', "Read test from/in this file (default stdin).",
304- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
305- {"timer-file", 'm', "File where the timing in micro seconds is stored.",
306- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
307- {"tmpdir", 't', "Temporary directory where sockets are put.",
308- 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
309- {"user", 'u', "User for login.", (char**) &opt_user, (char**) &opt_user, 0,
310- GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
311- {"verbose", 'v', "Write more.", (char**) &verbose, (char**) &verbose, 0,
312- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
313- {"version", 'V', "Output version information and exit.",
314- 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
315- { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
316-};
317-
318-
319-static void print_version(void)
320-{
321- printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,MTEST_VERSION,
322- drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
323-}
324-
325-static void usage(void)
326-{
327- print_version();
328- printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
329- printf("Drizzle version modified by Brian, Jay, Monty Taylor, PatG and Stewart\n");
330- printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
331- printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n");
332- printf("Usage: %s [OPTIONS] [database] < test_file\n", internal::my_progname);
333- my_print_help(my_long_options);
334- printf(" --no-defaults Don't read default options from any options file.\n");
335- my_print_variables(my_long_options);
336-}
337-
338-int get_one_option(int optid, const struct option *, char *argument)
339-{
340- char *endchar= NULL;
341- uint64_t temp_drizzle_port= 0;
342-
343- switch(optid) {
344- case 'r':
345- record = 1;
346- break;
347- case 'x':
348- {
349- char buff[FN_REFLEN];
350- if (!internal::test_if_hard_path(argument))
351- {
352- snprintf(buff, sizeof(buff), "%s%s",opt_basedir,argument);
353- argument= buff;
354- }
355- internal::fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
356- assert(cur_file == file_stack && cur_file->file == 0);
357- if (!(cur_file->file= fopen(buff, "r")))
358- {
359- fprintf(stderr, _("Could not open '%s' for reading: errno = %d"), buff, errno);
360- return EXIT_ARGUMENT_INVALID;
361- }
362- if (!(cur_file->file_name= strdup(buff)))
363- {
364- fprintf(stderr, _("Out of memory"));
365- return EXIT_OUT_OF_MEMORY;
366- }
367- cur_file->lineno= 1;
368- break;
369- }
370- case 'm':
371- {
372- static char buff[FN_REFLEN];
373- if (!internal::test_if_hard_path(argument))
374- {
375- snprintf(buff, sizeof(buff), "%s%s",opt_basedir,argument);
376- argument= buff;
377- }
378- internal::fn_format(buff, argument, "", "", MY_UNPACK_FILENAME);
379- timer_file= buff;
380- unlink(timer_file); /* Ignore error, may not exist */
381- break;
382- }
383- case 'p':
384- temp_drizzle_port= (uint64_t) strtoul(argument, &endchar, 10);
385- /* if there is an alpha character this is not a valid port */
386- if (strlen(endchar) != 0)
387- {
388- fprintf(stderr, _("Non-integer value supplied for port. If you are trying to enter a password please use --password instead.\n"));
389- return EXIT_ARGUMENT_INVALID;
390- }
391- /* If the port number is > 65535 it is not a valid port
392- This also helps with potential data loss casting unsigned long to a
393- uint32_t. */
394- if ((temp_drizzle_port == 0) || (temp_drizzle_port > 65535))
395- {
396- fprintf(stderr, _("Value supplied for port is not valid.\n"));
397- return EXIT_ARGUMENT_INVALID;
398- }
399- else
400- {
401- opt_port= (uint32_t) temp_drizzle_port;
402- }
403- break;
404- case 'P':
405- if (argument)
406- {
407- if (opt_pass)
408- free(opt_pass);
409- opt_pass = strdup(argument);
410- if (opt_pass == NULL)
411- {
412- fprintf(stderr, _("Out of memory"));
413- return EXIT_OUT_OF_MEMORY;
414- }
415- while (*argument)
416- {
417- /* Overwriting password with 'x' */
418- *argument++= 'x';
419- }
420- tty_password= 0;
421- }
422- else
423- tty_password= 1;
424- break;
425- case 't':
426- strncpy(TMPDIR, argument, sizeof(TMPDIR));
427- break;
428- case 'V':
429- print_version();
430- exit(0);
431- case '?':
432- usage();
433- exit(0);
434- }
435- return 0;
436-}
437-
438-
439-static int parse_args(int argc, char **argv)
440-{
441- internal::load_defaults("drizzle",load_default_groups,&argc,&argv);
442- default_argv= argv;
443-
444- if ((handle_options(&argc, &argv, my_long_options, get_one_option)))
445- exit(1);
446-
447- if (argc > 1)
448- {
449- usage();
450- exit(1);
451- }
452- if (argc == 1)
453- opt_db= *argv;
454- if (tty_password)
455- opt_pass= client_get_tty_password(NULL); /* purify tested */
456-
457- return 0;
458-}
459-
460 /*
461 Write the content of str into file
462
463@@ -4806,7 +4601,7 @@
464 int flags= O_WRONLY | O_CREAT;
465 if (!internal::test_if_hard_path(fname))
466 {
467- snprintf(buff, sizeof(buff), "%s%s",opt_basedir,fname);
468+ snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),fname);
469 fname= buff;
470 }
471 internal::fn_format(buff, fname, "", "", MY_UNPACK_FILENAME);
472@@ -4842,8 +4637,8 @@
473 void dump_result_to_log_file(const char *buf, int size)
474 {
475 char log_file[FN_REFLEN];
476- str_to_file(internal::fn_format(log_file, result_file_name, opt_logdir, ".log",
477- *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
478+ str_to_file(internal::fn_format(log_file, result_file_name.c_str(), opt_logdir.c_str(), ".log",
479+ ! opt_logdir.empty() ? MY_REPLACE_DIR | MY_REPLACE_EXT :
480 MY_REPLACE_EXT),
481 buf, size);
482 fprintf(stderr, "\nMore results from queries before failure can be found in %s\n",
483@@ -4853,9 +4648,9 @@
484 void dump_progress(void)
485 {
486 char progress_file[FN_REFLEN];
487- str_to_file(internal::fn_format(progress_file, result_file_name,
488- opt_logdir, ".progress",
489- *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
490+ str_to_file(internal::fn_format(progress_file, result_file_name.c_str(),
491+ opt_logdir.c_str(), ".progress",
492+ ! opt_logdir.empty() ? MY_REPLACE_DIR | MY_REPLACE_EXT :
493 MY_REPLACE_EXT),
494 ds_progress.c_str(), ds_progress.length());
495 }
496@@ -4864,8 +4659,8 @@
497 {
498 char warn_file[FN_REFLEN];
499
500- str_to_file(internal::fn_format(warn_file, result_file_name, opt_logdir, ".warnings",
501- *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
502+ str_to_file(internal::fn_format(warn_file, result_file_name.c_str(), opt_logdir.c_str(), ".warnings",
503+ ! opt_logdir.empty() ? MY_REPLACE_DIR | MY_REPLACE_EXT :
504 MY_REPLACE_EXT),
505 ds_warning_messages.c_str(), ds_warning_messages.length());
506 }
507@@ -5563,18 +5358,185 @@
508
509 }
510
511+static void check_retries(uint32_t in_opt_max_connect_retries)
512+{
513+ if (in_opt_max_connect_retries > 10000 || opt_max_connect_retries<1)
514+ {
515+ cout<<N_("Error: Invalid Value for opt_max_connect_retries");
516+ exit(-1);
517+ }
518+ opt_max_connect_retries= in_opt_max_connect_retries;
519+}
520+
521+static void check_tail_lines(uint32_t in_opt_tail_lines)
522+{
523+ if (in_opt_tail_lines > 10000)
524+ {
525+ cout<<N_("Error: Invalid Value for opt_tail_lines");
526+ exit(-1);
527+ }
528+ opt_tail_lines= in_opt_tail_lines;
529+}
530+
531+static void check_sleep(int32_t in_opt_sleep)
532+{
533+ if (in_opt_sleep < -1)
534+ {
535+ cout<<N_("Error: Invalid Value for opt_sleep");
536+ exit(-1);
537+ }
538+ opt_sleep= in_opt_sleep;
539+}
540+
541+static pair<string, string> parse_password_arg(std::string s)
542+{
543+ if (s.find("--password") == 0)
544+ {
545+ if (s == "--password")
546+ {
547+ tty_password= true;
548+ //check if no argument is passed.
549+ return make_pair("password", PASSWORD_SENTINEL);
550+ }
551+
552+ if (s.substr(10,3) == "=\"\"" || s.substr(10,3) == "=''")
553+ {
554+ // Check if --password="" or --password=''
555+ return make_pair("password", PASSWORD_SENTINEL);
556+ }
557+
558+ if(s.substr(10) == "=" && s.length() == 11)
559+ {
560+ // check if --password= and return a default value
561+ return make_pair("password", PASSWORD_SENTINEL);
562+ }
563+
564+ if(s.length()>12 && (s[10] == '"' || s[10] == '\''))
565+ {
566+ // check if --password has quotes, remove quotes and return the value
567+ return make_pair("password", s.substr(11,s.length()-1));
568+ }
569+
570+ // if all above are false, it implies that --password=value, return value.
571+ return make_pair("password", s.substr(11));
572+ }
573+
574+ else
575+ {
576+ return make_pair(string(""), string(""));
577+ }
578+}
579
580 int main(int argc, char **argv)
581 {
582+try
583+{
584 struct st_command *command;
585 bool q_send_flag= 0, abort_flag= 0;
586 uint32_t command_executed= 0, last_command_executed= 0;
587 string save_file("");
588 struct stat res_info;
589- MY_INIT(argv[0]);
590
591 TMPDIR[0]= 0;
592
593+ po::options_description commandline_options("Options used only in command line");
594+ commandline_options.add_options()
595+ ("help,?", "Display this help and exit.")
596+ ("mark-progress", po::value<bool>(&opt_mark_progress)->default_value(false)->zero_tokens(),
597+ "Write linenumber and elapsed time to <testname>.progress ")
598+ ("sleep,T", po::value<int32_t>(&opt_sleep)->default_value(-1)->notifier(&check_sleep),
599+ "Sleep always this many seconds on sleep commands.")
600+ ("test-file,x", po::value<string>(),
601+ "Read test from/in this file (default stdin).")
602+ ("timer-file,f", po::value<string>(),
603+ "File where the timing in micro seconds is stored.")
604+ ("tmpdir,t", po::value<string>(),
605+ "Temporary directory where sockets are put.")
606+ ("verbose,v", po::value<bool>(&verbose)->default_value(false),
607+ "Write more.")
608+ ("version,V", "Output version information and exit.")
609+ ("no-defaults", po::value<bool>()->default_value(false)->zero_tokens(),
610+ "Configuration file defaults are not used if no-defaults is set")
611+ ;
612+
613+ po::options_description test_options("Options specific to the drizzleimport");
614+ test_options.add_options()
615+ ("basedir,b", po::value<string>(&opt_basedir)->default_value(""),
616+ "Basedir for tests.")
617+ ("character-sets-dir", po::value<string>(&opt_charsets_dir)->default_value(""),
618+ "Directory where character sets are.")
619+ ("database,D", po::value<string>(&opt_db)->default_value(""),
620+ "Database to use.")
621+ ("include,i", po::value<string>(&opt_include)->default_value(""),
622+ "Include SQL before each test case.")
623+ ("testdir", po::value<string>(&opt_testdir)->default_value(""),
624+ "Path to use to search for test files")
625+ ("logdir", po::value<string>(&opt_logdir)->default_value(""),
626+ "Directory for log files")
627+ ("max-connect-retries", po::value<uint32_t>(&opt_max_connect_retries)->default_value(500)->notifier(&check_retries),
628+ "Max number of connection attempts when connecting to server")
629+ ("quiet,s", po::value<bool>(&silent)->default_value(0)->zero_tokens(),
630+ "Suppress all normal output.")
631+ ("record,r", "Record output of test_file into result file.")
632+ ("result-file,R", po::value<string>(&result_file_name)->default_value(""),
633+ "Read/Store result from/in this file.")
634+ ("silent,s", po::value<bool>(&silent)->default_value(false)->zero_tokens(),
635+ "Suppress all normal output. Synonym for --quiet.")
636+ ("tail-lines", po::value<uint32_t>(&opt_tail_lines)->default_value(0)->notifier(&check_tail_lines),
637+ "Number of lines of the resul to include in a failure report")
638+ ;
639+
640+ po::options_description client_options("Options specific to the client");
641+ client_options.add_options()
642+
643+ ("host,h", po::value<string>(&opt_host)->default_value("localhost"),
644+ "Connect to host.")
645+ ("mysql,m", po::value<bool>(&opt_mysql)->default_value(true)->zero_tokens(),
646+ N_("Use MySQL Protocol."))
647+ ("password,P", po::value<string>(&password)->default_value("PASSWORD_SENTINEL"),
648+ "Password to use when connecting to server.")
649+ ("port,p", po::value<uint32_t>(&opt_port)->default_value(0),
650+ "Port number to use for connection or 0 for default")
651+ ("protocol", po::value<string>(),
652+ "The protocol of connection (tcp,socket,pipe,memory).")
653+ ("user,u", po::value<string>(&opt_user)->default_value(""),
654+ "User for login.")
655+ ;
656+
657+ po::positional_options_description p;
658+ p.add("database", 1);
659+
660+ po::options_description long_options("Allowed Options");
661+ long_options.add(commandline_options).add(test_options).add(client_options);
662+
663+ std::string system_config_dir_test(SYSCONFDIR);
664+ system_config_dir_test.append("/drizzle/drizzletest.cnf");
665+
666+ std::string system_config_dir_client(SYSCONFDIR);
667+ system_config_dir_client.append("/drizzle/client.cnf");
668+
669+ po::variables_map vm;
670+
671+ po::store(po::command_line_parser(argc, argv).options(long_options).
672+ positional(p).extra_parser(parse_password_arg).run(), vm);
673+
674+ if (! vm["no-defaults"].as<bool>())
675+ {
676+ ifstream user_test_ifs("~/.drizzle/drizzletest.cnf");
677+ po::store(parse_config_file(user_test_ifs, test_options), vm);
678+
679+ ifstream system_test_ifs(system_config_dir_test.c_str());
680+ store(parse_config_file(system_test_ifs, test_options), vm);
681+
682+ ifstream user_client_ifs("~/.drizzle/client.cnf");
683+ po::store(parse_config_file(user_client_ifs, client_options), vm);
684+
685+ ifstream system_client_ifs(system_config_dir_client.c_str());
686+ po::store(parse_config_file(system_client_ifs, client_options), vm);
687+ }
688+
689+ po::notify(vm);
690+
691 /* Init expected errors */
692 memset(&saved_expected_errors, 0, sizeof(saved_expected_errors));
693
694@@ -5611,7 +5573,120 @@
695 ds_progress.reserve(2048);
696 ds_warning_messages.reserve(2048);
697
698- parse_args(argc, argv);
699+
700+ if (vm.count("record"))
701+ {
702+ record = 1;
703+ }
704+
705+ if (vm.count("test-file"))
706+ {
707+ string tmp= vm["test-file"].as<string>();
708+ char buff[FN_REFLEN];
709+ if (!internal::test_if_hard_path(tmp.c_str()))
710+ {
711+ snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),tmp.c_str());
712+ tmp= buff;
713+ }
714+ internal::fn_format(buff, tmp.c_str(), "", "", MY_UNPACK_FILENAME);
715+ assert(cur_file == file_stack && cur_file->file == 0);
716+ if (!(cur_file->file= fopen(buff, "r")))
717+ {
718+ fprintf(stderr, _("Could not open '%s' for reading: errno = %d"), buff, errno);
719+ return EXIT_ARGUMENT_INVALID;
720+ }
721+ if (!(cur_file->file_name= strdup(buff)))
722+ {
723+ fprintf(stderr, _("Out of memory"));
724+ return EXIT_OUT_OF_MEMORY;
725+ }
726+ cur_file->lineno= 1;
727+ }
728+
729+ if (vm.count("timer-file"))
730+ {
731+ string tmp= vm["timer-file"].as<string>().c_str();
732+ static char buff[FN_REFLEN];
733+ if (!internal::test_if_hard_path(tmp.c_str()))
734+ {
735+ snprintf(buff, sizeof(buff), "%s%s",opt_basedir.c_str(),tmp.c_str());
736+ tmp= buff;
737+ }
738+ internal::fn_format(buff, tmp.c_str(), "", "", MY_UNPACK_FILENAME);
739+ timer_file= buff;
740+ unlink(timer_file); /* Ignore error, may not exist */
741+ }
742+
743+ if (vm.count("port"))
744+ {
745+ /* If the port number is > 65535 it is not a valid port
746+ This also helps with potential data loss casting unsigned long to a
747+ uint32_t. */
748+ if (opt_port > 65535)
749+ {
750+ fprintf(stderr, _("Value supplied for port is not valid.\n"));
751+ exit(EXIT_ARGUMENT_INVALID);
752+ }
753+ }
754+
755+ if (vm.count("password"))
756+ {
757+ if (!opt_password.empty())
758+ opt_password.erase();
759+ if (password == PASSWORD_SENTINEL)
760+ {
761+ opt_password= "";
762+ }
763+ else
764+ {
765+ opt_password= password;
766+ tty_password= false;
767+ }
768+ char *start= (char *)password.c_str();
769+ char *temp_pass= (char *)password.c_str();
770+ while (*temp_pass)
771+ {
772+ /* Overwriting password with 'x' */
773+ *temp_pass++= 'x';
774+ }
775+ if (*start)
776+ {
777+ start[1]= 0;
778+ }
779+ }
780+ else
781+ {
782+ tty_password= true;
783+ }
784+
785+ if (vm.count("tmpdir"))
786+ {
787+ strncpy(TMPDIR, vm["tmpdir"].as<string>().c_str(), sizeof(TMPDIR));
788+ }
789+
790+ if (vm.count("version"))
791+ {
792+ printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,MTEST_VERSION,
793+ drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
794+ exit(0);
795+ }
796+
797+ if (vm.count("help"))
798+ {
799+ printf("%s Ver %s Distrib %s, for %s-%s (%s)\n",internal::my_progname,MTEST_VERSION,
800+ drizzle_version(),HOST_VENDOR,HOST_OS,HOST_CPU);
801+ printf("MySQL AB, by Sasha, Matt, Monty & Jani\n");
802+ printf("Drizzle version modified by Brian, Jay, Monty Taylor, PatG and Stewart\n");
803+ printf("This software comes with ABSOLUTELY NO WARRANTY\n\n");
804+ printf("Runs a test against the DRIZZLE server and compares output with a results file.\n\n");
805+ printf("Usage: %s [OPTIONS] [database] < test_file\n", internal::my_progname);
806+ exit(0);
807+ }
808+
809+ if (tty_password)
810+ {
811+ opt_pass= client_get_tty_password(NULL); /* purify tested */
812+ }
813
814 server_initialized= 1;
815 if (cur_file == file_stack && cur_file->file == 0)
816@@ -5632,7 +5707,6 @@
817
818 if (!(cur_con->name = strdup("default")))
819 die("Out of memory");
820-
821 safe_connect(&cur_con->con, cur_con->name, opt_host, opt_user, opt_pass,
822 opt_db, opt_port);
823
824@@ -5649,9 +5723,9 @@
825 /* Update $drizzleclient_get_server_version to that of current connection */
826 var_set_drizzleclient_get_server_version(&cur_con->con);
827
828- if (opt_include)
829+ if (! opt_include.empty())
830 {
831- open_file(opt_include);
832+ open_file(opt_include.c_str());
833 }
834
835 while (!read_command(&command) && !abort_flag)
836@@ -5955,14 +6029,14 @@
837 */
838 if (ds_res.length())
839 {
840- if (result_file_name)
841+ if (! result_file_name.empty())
842 {
843 /* A result file has been specified */
844
845 if (record)
846 {
847 /* Recording - dump the output from test to result file */
848- str_to_file(result_file_name, ds_res.c_str(), ds_res.length());
849+ str_to_file(result_file_name.c_str(), ds_res.c_str(), ds_res.length());
850 }
851 else
852 {
853@@ -5985,7 +6059,7 @@
854 }
855
856 if (!command_executed &&
857- result_file_name && !stat(result_file_name, &res_info))
858+ ! result_file_name.empty() && !stat(result_file_name.c_str(), &res_info))
859 {
860 /*
861 my_stat() successful on result file. Check if we have not run a
862@@ -5997,16 +6071,23 @@
863 die("No queries executed but result file found!");
864 }
865
866- if ( opt_mark_progress && result_file_name )
867+ if ( opt_mark_progress && ! result_file_name.empty() )
868 dump_progress();
869
870 /* Dump warning messages */
871- if (result_file_name && ds_warning_messages.length())
872+ if (! result_file_name.empty() && ds_warning_messages.length())
873 dump_warning_messages();
874
875 timer_output();
876 /* Yes, if we got this far the test has suceeded! Sakila smiles */
877 cleanup_and_exit(0);
878+}
879+
880+ catch(exception &err)
881+ {
882+ cerr<<err.what()<<endl;
883+ }
884+
885 return 0; /* Keep compiler happy too */
886 }
887
888
889=== modified file 'client/include.am'
890--- client/include.am 2010-06-12 21:25:45 +0000
891+++ client/include.am 2010-06-16 07:57:30 +0000
892@@ -65,7 +65,7 @@
893 client_drizzleslap_CXXFLAGS= ${CLIENT_CXXFLAGS}
894
895 client_drizzletest_SOURCES= client/drizzletest.cc client/errname.cc
896-client_drizzletest_LDADD= ${CLIENT_LDADD} ${LIBPCRE}
897+client_drizzletest_LDADD= ${CLIENT_LDADD} ${BOOST_LIBS} ${LIBPCRE}
898 client_drizzletest_CXXFLAGS= ${CLIENT_CXXFLAGS}
899
900