1 /* Copyright (c) 2003-2005, 2007 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
19 #include <my_getopt.h>
22 #include <NdbAutoPtr.hpp>
24 #include <SysLogHandler.hpp>
25 #include <FileLogHandler.hpp>
29 #define PATH_SEPARATOR "/"
31 /** Global variables */
32 static const char progname
[] = "ndb_atrt";
33 static const char * g_gather_progname
= "atrt-gather-result.sh";
34 static const char * g_analyze_progname
= "atrt-analyze-result.sh";
35 static const char * g_clear_progname
= "atrt-clear-result.sh";
36 static const char * g_setup_progname
= "atrt-setup.sh";
38 static const char * g_log_filename
= 0;
39 static const char * g_test_case_filename
= 0;
40 static const char * g_report_filename
= 0;
42 static int g_do_setup
= 0;
43 static int g_do_deploy
= 0;
44 static int g_do_sshx
= 0;
45 static int g_do_start
= 0;
46 static int g_do_quit
= 0;
48 static int g_help
= 0;
49 static int g_verbosity
= 1;
50 static FILE * g_report_file
= 0;
51 static FILE * g_test_case_file
= stdin
;
52 static int g_mode
= 0;
56 const char * g_user
= 0;
57 int g_baseport
= 10000;
59 int g_default_ports
= 0;
61 const char * g_cwd
= 0;
62 const char * g_basedir
= 0;
63 const char * g_my_cnf
= 0;
64 const char * g_prefix
= 0;
65 const char * g_clusters
= 0;
66 BaseString g_replicate
;
67 const char *save_file
= 0;
68 char *save_extra_file
= 0;
69 const char *save_group_suffix
= 0;
71 char * g_env_path
= 0;
73 /** Dummy, extern declared in ndb_opts.h */
74 int g_print_full_config
= 0, opt_ndb_shm
;
77 static struct my_option g_options
[] =
79 { "help", '?', "Display this help and exit.",
80 (uchar
**) &g_help
, (uchar
**) &g_help
,
81 0, GET_BOOL
, NO_ARG
, 0, 0, 0, 0, 0, 0 },
82 { "version", 'V', "Output version information and exit.", 0, 0, 0,
83 GET_NO_ARG
, NO_ARG
, 0, 0, 0, 0, 0, 0 },
84 { "clusters", 256, "Cluster",
85 (uchar
**) &g_clusters
, (uchar
**) &g_clusters
,
86 0, GET_STR
, REQUIRED_ARG
, 0, 0, 0, 0, 0, 0},
87 { "replicate", 1024, "replicate",
88 (uchar
**) &g_dummy
, (uchar
**) &g_dummy
,
89 0, GET_STR
, REQUIRED_ARG
, 0, 0, 0, 0, 0, 0},
90 { "log-file", 256, "log-file",
91 (uchar
**) &g_log_filename
, (uchar
**) &g_log_filename
,
92 0, GET_STR
, REQUIRED_ARG
, 0, 0, 0, 0, 0, 0},
93 { "testcase-file", 'f', "testcase-file",
94 (uchar
**) &g_test_case_filename
, (uchar
**) &g_test_case_filename
,
95 0, GET_STR
, REQUIRED_ARG
, 0, 0, 0, 0, 0, 0},
96 { "report-file", 'r', "report-file",
97 (uchar
**) &g_report_filename
, (uchar
**) &g_report_filename
,
98 0, GET_STR
, REQUIRED_ARG
, 0, 0, 0, 0, 0, 0},
99 { "basedir", 256, "Base path",
100 (uchar
**) &g_basedir
, (uchar
**) &g_basedir
,
101 0, GET_STR
, REQUIRED_ARG
, 0, 0, 0, 0, 0, 0},
102 { "baseport", 256, "Base port",
103 (uchar
**) &g_baseport
, (uchar
**) &g_baseport
,
104 0, GET_INT
, REQUIRED_ARG
, g_baseport
, 0, 0, 0, 0, 0},
105 { "prefix", 256, "mysql install dir",
106 (uchar
**) &g_prefix
, (uchar
**) &g_prefix
,
107 0, GET_STR
, REQUIRED_ARG
, 0, 0, 0, 0, 0, 0},
108 { "verbose", 'v', "Verbosity",
109 (uchar
**) &g_verbosity
, (uchar
**) &g_verbosity
,
110 0, GET_INT
, REQUIRED_ARG
, g_verbosity
, 0, 0, 0, 0, 0},
111 { "configure", 256, "configure",
112 (uchar
**) &g_do_setup
, (uchar
**) &g_do_setup
,
113 0, GET_INT
, REQUIRED_ARG
, g_do_setup
, 0, 0, 0, 0, 0 },
114 { "deploy", 256, "deploy",
115 (uchar
**) &g_do_deploy
, (uchar
**) &g_do_deploy
,
116 0, GET_INT
, REQUIRED_ARG
, g_do_deploy
, 0, 0, 0, 0, 0 },
117 { "sshx", 256, "sshx",
118 (uchar
**) &g_do_sshx
, (uchar
**) &g_do_sshx
,
119 0, GET_INT
, REQUIRED_ARG
, g_do_sshx
, 0, 0, 0, 0, 0 },
120 { "start", 256, "start",
121 (uchar
**) &g_do_start
, (uchar
**) &g_do_start
,
122 0, GET_INT
, REQUIRED_ARG
, g_do_start
, 0, 0, 0, 0, 0 },
123 { "fqpn", 256, "Fully qualified path-names ",
124 (uchar
**) &g_fqpn
, (uchar
**) &g_fqpn
,
125 0, GET_INT
, REQUIRED_ARG
, g_fqpn
, 0, 0, 0, 0, 0 },
126 { "default-ports", 256, "Use default ports when possible",
127 (uchar
**) &g_default_ports
, (uchar
**) &g_default_ports
,
128 0, GET_INT
, REQUIRED_ARG
, g_default_ports
, 0, 0, 0, 0, 0 },
129 { "mode", 256, "Mode 0=interactive 1=regression 2=bench",
130 (uchar
**) &g_mode
, (uchar
**) &g_mode
,
131 0, GET_INT
, REQUIRED_ARG
, g_mode
, 0, 0, 0, 0, 0 },
132 { "quit", 256, "Quit before starting tests",
133 (uchar
**) &g_mode
, (uchar
**) &g_do_quit
,
134 0, GET_BOOL
, NO_ARG
, g_do_quit
, 0, 0, 0, 0, 0 },
135 { 0, 0, 0, 0, 0, 0, GET_NO_ARG
, NO_ARG
, 0, 0, 0, 0, 0, 0}
138 const int p_ndb
= atrt_process::AP_NDB_MGMD
| atrt_process::AP_NDBD
;
139 const int p_servers
= atrt_process::AP_MYSQLD
;
140 const int p_clients
= atrt_process::AP_CLIENT
| atrt_process::AP_NDB_API
;
143 main(int argc
, char ** argv
)
152 g_logger
.setCategory(progname
);
153 g_logger
.enable(Logger::LL_ALL
);
154 g_logger
.createConsoleHandler();
156 if(!parse_args(argc
, argv
))
159 g_logger
.info("Starting...");
160 g_config
.m_generated
= false;
161 g_config
.m_replication
= g_replicate
;
162 if (!setup_config(g_config
))
165 if (!configure(g_config
, g_do_setup
))
168 g_logger
.info("Setting up directories");
169 if (!setup_directories(g_config
, g_do_setup
))
174 g_logger
.info("Setting up files");
175 if (!setup_files(g_config
, g_do_setup
, g_do_sshx
))
181 if (!deploy(g_config
))
191 if(!setup_hosts(g_config
))
196 g_logger
.info("Starting xterm-ssh");
197 if (!sshx(g_config
, g_do_sshx
))
200 g_logger
.info("Done...sleeping");
203 NdbSleep_SecSleep(1);
209 g_logger
.info("Connecting to hosts");
210 if(!connect_hosts(g_config
))
213 if (g_do_start
&& !g_test_case_filename
)
215 g_logger
.info("Starting server processes: %x", g_do_start
);
216 if (!start(g_config
, g_do_start
))
219 g_logger
.info("Done...sleeping");
222 NdbSleep_SecSleep(1);
233 while(!feof(g_test_case_file
)){
235 * Do we need to restart ndb
238 g_logger
.info("(Re)starting server processes processes");
239 if(!stop_processes(g_config
, ~0))
242 if (!setup_directories(g_config
, 2))
245 if (!setup_files(g_config
, 2, 1))
248 if(!setup_hosts(g_config
))
251 if (!start(g_config
, p_ndb
| p_servers
))
253 g_logger
.info("All servers start completed");
256 // const int start_line = lineno;
257 atrt_testcase test_case
;
258 if(!read_test_case(g_test_case_file
, test_case
, lineno
))
261 g_logger
.info("#%d - %s %s",
263 test_case
.m_command
.c_str(), test_case
.m_args
.c_str());
265 // Assign processes to programs
266 if(!setup_test_case(g_config
, test_case
))
269 if(!start_processes(g_config
, p_clients
))
274 const time_t start
= time(0);
277 if(!update_status(g_config
, atrt_process::AP_ALL
))
282 if((count
= is_running(g_config
, p_ndb
)) != 2){
283 result
= ERR_NDB_FAILED
;
287 if((count
= is_running(g_config
, p_servers
)) != 2){
288 result
= ERR_SERVERS_FAILED
;
292 if((count
= is_running(g_config
, p_clients
)) == 0){
297 if(now
> (start
+ test_case
.m_max_time
)){
298 result
= ERR_MAX_TIME_ELAPSED
;
301 NdbSleep_SecSleep(1);
304 const time_t elapsed
= time(0) - start
;
306 if(!stop_processes(g_config
, p_clients
))
309 int tmp
, *rp
= result
? &tmp
: &result
;
310 if(!gather_result(g_config
, rp
))
313 g_logger
.info("#%d %s(%d)",
315 (result
== 0 ? "OK" : "FAILED"), result
);
317 if(g_report_file
!= 0){
318 fprintf(g_report_file
, "%s ; %d ; %d ; %ld\n",
319 test_case
.m_name
.c_str(), test_no
, result
, elapsed
);
320 fflush(g_report_file
);
323 if(g_mode
== 0 && result
){
325 ("Encountered failed test in interactive mode - terminating");
330 resdir
.assfmt("result.%d", test_no
);
331 remove_dir(resdir
.c_str(), true);
333 if(test_case
.m_report
|| g_mode
== 2 || (g_mode
&& result
))
335 if(rename("result", resdir
.c_str()) != 0)
337 g_logger
.critical("Failed to rename %s as %s",
338 "result", resdir
.c_str());
344 remove_dir("result", true);
356 if(g_report_file
!= 0){
357 fclose(g_report_file
);
361 if(g_test_case_file
!= 0 && g_test_case_file
!= stdin
){
362 fclose(g_test_case_file
);
363 g_test_case_file
= 0;
366 stop_processes(g_config
, atrt_process::AP_ALL
);
372 get_one_option(int arg
, const struct my_option
* opt
, char * value
)
376 if (g_replicate
.length())
377 g_replicate
.append(";");
378 g_replicate
.append(value
);
385 parse_args(int argc
, char** argv
)
388 if (getcwd(buf
, sizeof(buf
)) == 0)
390 g_logger
.error("Unable to get current working directory");
397 if (argc
> 1 && lstat(argv
[argc
-1], &sbuf
) == 0)
400 mycnf
.append(PATH_SEPARATOR
);
401 mycnf
.append(argv
[argc
-1]);
406 mycnf
.append(PATH_SEPARATOR
);
407 mycnf
.append("my.cnf");
408 if (lstat(mycnf
.c_str(), &sbuf
) != 0)
410 g_logger
.error("Unable to stat %s", mycnf
.c_str());
415 g_logger
.info("Bootstrapping using %s", mycnf
.c_str());
417 const char *groups
[] = { "atrt", 0 };
418 int ret
= load_defaults(mycnf
.c_str(), groups
, &argc
, &argv
);
420 save_file
= my_defaults_file
;
421 save_extra_file
= my_defaults_extra_file
;
422 save_group_suffix
= my_defaults_group_suffix
;
426 g_logger
.error("--defaults-extra-file(%s) is not supported...",
431 if (ret
|| handle_options(&argc
, &argv
, g_options
, get_one_option
))
433 g_logger
.error("Failed to load defaults/handle_options");
439 const char * arg
= argv
[argc
-2];
444 g_do_setup
= (g_do_setup
== 0) ? 1 : g_do_setup
;
453 g_do_sshx
= atrt_process::AP_CLIENT
| atrt_process::AP_NDB_API
;
456 g_do_sshx
= atrt_process::AP_ALL
;
462 g_do_start
= p_ndb
| p_servers
;
471 g_logger
.error("Unknown switch '%c'", *arg
);
478 if(g_log_filename
!= 0)
480 g_logger
.removeConsoleHandler();
481 g_logger
.addHandler(new FileLogHandler(g_log_filename
));
485 int tmp
= Logger::LL_WARNING
- g_verbosity
;
486 tmp
= (tmp
< Logger::LL_DEBUG
? Logger::LL_DEBUG
: tmp
);
487 g_logger
.disable(Logger::LL_ALL
);
488 g_logger
.enable(Logger::LL_ON
);
489 g_logger
.enable((Logger::LoggerLevel
)tmp
, Logger::LL_ALERT
);
495 g_logger
.info("basedir not specified, using %s", g_basedir
);
500 g_prefix
= DEFAULT_PREFIX
;
504 * Add path to atrt-*.sh
508 const char* env
= getenv("PATH");
509 if (env
&& strlen(env
))
511 tmp
.assfmt("PATH=%s:%s/mysql-test/ndb",
516 tmp
.assfmt("PATH=%s/mysql-test/ndb", g_prefix
);
518 g_env_path
= strdup(tmp
.c_str());
524 my_print_help(g_options
);
525 my_print_variables(g_options
);
529 if(g_test_case_filename
)
531 g_test_case_file
= fopen(g_test_case_filename
, "r");
532 if(g_test_case_file
== 0)
534 g_logger
.critical("Unable to open file: %s", g_test_case_filename
);
541 g_do_start
= p_ndb
| p_servers
;
548 g_logger
.critical("ssx specified...not possible with testfile");
556 tmp
.append(g_basedir
);
557 tmp
.append(PATH_SEPARATOR
);
558 tmp
.append("my.cnf");
559 if (lstat(tmp
.c_str(), &sbuf
) != 0)
561 g_logger
.error("Unable to stat %s", tmp
.c_str());
565 if (!S_ISREG(sbuf
.st_mode
))
567 g_logger
.error("%s is not a regular file", tmp
.c_str());
571 g_my_cnf
= strdup(tmp
.c_str());
572 g_logger
.info("Using %s", tmp
.c_str());
576 g_my_cnf
= strdup(mycnf
.c_str());
579 g_logger
.info("Using --prefix=\"%s\"", g_prefix
);
581 if(g_report_filename
)
583 g_report_file
= fopen(g_report_filename
, "w");
584 if(g_report_file
== 0)
586 g_logger
.critical("Unable to create report file: %s", g_report_filename
);
593 g_logger
.critical("No clusters specified");
597 g_user
= strdup(getenv("LOGNAME"));
603 connect_hosts(atrt_config
& config
){
604 for(size_t i
= 0; i
<config
.m_hosts
.size(); i
++){
605 if(config
.m_hosts
[i
]->m_cpcd
->connect() != 0){
606 g_logger
.error("Unable to connect to cpc %s:%d",
607 config
.m_hosts
[i
]->m_cpcd
->getHost(),
608 config
.m_hosts
[i
]->m_cpcd
->getPort());
611 g_logger
.debug("Connected to %s:%d",
612 config
.m_hosts
[i
]->m_cpcd
->getHost(),
613 config
.m_hosts
[i
]->m_cpcd
->getPort());
620 connect_ndb_mgm(atrt_process
& proc
){
621 NdbMgmHandle handle
= ndb_mgm_create_handle();
623 g_logger
.critical("Unable to create mgm handle");
626 BaseString tmp
= proc
.m_host
->m_hostname
;
628 proc
.m_options
.m_loaded
.get("--PortNumber=", &val
);
629 tmp
.appfmt(":%s", val
);
631 if (ndb_mgm_set_connectstring(handle
,tmp
.c_str()))
633 g_logger
.critical("Unable to create parse connectstring");
637 if(ndb_mgm_connect(handle
, 30, 1, 0) != -1)
639 proc
.m_ndb_mgm_handle
= handle
;
643 g_logger
.critical("Unable to connect to ndb mgm %s", tmp
.c_str());
648 connect_ndb_mgm(atrt_config
& config
){
649 for(size_t i
= 0; i
<config
.m_processes
.size(); i
++){
650 atrt_process
& proc
= *config
.m_processes
[i
];
651 if((proc
.m_type
& atrt_process::AP_NDB_MGMD
) != 0){
652 if(!connect_ndb_mgm(proc
)){
661 static int remap(int i
){
662 if(i
== NDB_MGM_NODE_STATUS_NO_CONTACT
) return NDB_MGM_NODE_STATUS_UNKNOWN
;
663 if(i
== NDB_MGM_NODE_STATUS_UNKNOWN
) return NDB_MGM_NODE_STATUS_NO_CONTACT
;
668 wait_ndb(atrt_config
& config
, int goal
){
673 for (size_t i
= 0; i
<config
.m_clusters
.size(); i
++)
675 atrt_cluster
* cluster
= config
.m_clusters
[i
];
677 * Get mgm handle for cluster
679 NdbMgmHandle handle
= 0;
680 for(size_t j
= 0; j
<cluster
->m_processes
.size(); j
++){
681 atrt_process
& proc
= *cluster
->m_processes
[j
];
682 if((proc
.m_type
& atrt_process::AP_NDB_MGMD
) != 0){
683 handle
= proc
.m_ndb_mgm_handle
;
689 g_logger
.critical("Unable to find mgm handle");
693 if(goal
== NDB_MGM_NODE_STATUS_STARTED
){
695 * 1) wait NOT_STARTED
699 if(!wait_ndb(config
, NDB_MGM_NODE_STATUS_NOT_STARTED
))
702 ndb_mgm_start(handle
, 0, 0);
705 struct ndb_mgm_cluster_state
* state
;
707 time_t now
= time(0);
708 time_t end
= now
+ 360;
709 int min
= remap(NDB_MGM_NODE_STATUS_NO_CONTACT
);
714 * 1) retreive current state
718 state
= ndb_mgm_get_status(handle
);
720 const int err
= ndb_mgm_get_latest_error(handle
);
721 g_logger
.error("Unable to poll db state: %d %s %s",
722 ndb_mgm_get_latest_error(handle
),
723 ndb_mgm_get_latest_error_msg(handle
),
724 ndb_mgm_get_latest_error_desc(handle
));
725 if(err
== NDB_MGM_SERVER_NOT_CONNECTED
&& connect_ndb_mgm(config
)){
726 g_logger
.error("Reconnected...");
732 NdbAutoPtr
<void> tmp(state
);
735 for(int j
= 0; j
<state
->no_of_nodes
; j
++){
736 if(state
->node_states
[j
].node_type
== NDB_MGM_NODE_TYPE_NDB
){
737 const int s
= remap(state
->node_states
[j
].node_status
);
738 min2
= (min2
< s
? min2
: s
);
740 if(s
< remap(NDB_MGM_NODE_STATUS_NO_CONTACT
) ||
741 s
> NDB_MGM_NODE_STATUS_STARTED
){
742 g_logger
.critical("Strange DB status during start: %d %d",
748 g_logger
.critical("wait ndb failed node: %d %d %d %d",
749 state
->node_states
[j
].node_id
, min
, min2
, goal
);
755 g_logger
.critical("wait ndb failed %d %d %d", min
, min2
, goal
);
768 g_logger
.critical("wait ndb timed out %d %d %d", min
, min2
, goal
);
775 return cnt
== config
.m_clusters
.size();
779 start_process(atrt_process
& proc
){
780 if(proc
.m_proc
.m_id
!= -1){
781 g_logger
.critical("starting already started process: %d", proc
.m_index
);
785 BaseString tmp
= g_setup_progname
;
786 tmp
.appfmt(" %s %s/ %s",
787 proc
.m_host
->m_hostname
.c_str(),
788 proc
.m_proc
.m_cwd
.c_str(),
789 proc
.m_proc
.m_cwd
.c_str());
791 g_logger
.debug("system(%s)", tmp
.c_str());
792 const int r1
= system(tmp
.c_str());
794 g_logger
.critical("Failed to setup process");
800 if(proc
.m_host
->m_cpcd
->define_process(proc
.m_proc
, reply
) != 0){
802 reply
.get("errormessage", msg
);
803 g_logger
.error("Unable to define process: %s", msg
.c_str());
809 if(proc
.m_host
->m_cpcd
->start_process(proc
.m_proc
.m_id
, reply
) != 0){
811 reply
.get("errormessage", msg
);
812 g_logger
.error("Unable to start process: %s", msg
.c_str());
820 start_processes(atrt_config
& config
, int types
){
821 for(size_t i
= 0; i
<config
.m_processes
.size(); i
++){
822 atrt_process
& proc
= *config
.m_processes
[i
];
823 if((types
& proc
.m_type
) != 0 && proc
.m_proc
.m_path
!= ""){
824 if(!start_process(proc
)){
833 stop_process(atrt_process
& proc
){
834 if(proc
.m_proc
.m_id
== -1){
840 if(proc
.m_host
->m_cpcd
->stop_process(proc
.m_proc
.m_id
, reply
) != 0){
842 reply
.get("status", &status
);
845 reply
.get("errormessage", msg
);
846 g_logger
.error("Unable to stop process: %s(%d)", msg
.c_str(), status
);
853 if(proc
.m_host
->m_cpcd
->undefine_process(proc
.m_proc
.m_id
, reply
) != 0){
855 reply
.get("errormessage", msg
);
856 g_logger
.error("Unable to undefine process: %s", msg
.c_str());
859 proc
.m_proc
.m_id
= -1;
865 stop_processes(atrt_config
& config
, int types
){
866 for(size_t i
= 0; i
<config
.m_processes
.size(); i
++){
867 atrt_process
& proc
= *config
.m_processes
[i
];
868 if((types
& proc
.m_type
) != 0){
869 if(!stop_process(proc
)){
878 update_status(atrt_config
& config
, int){
880 Vector
<Vector
<SimpleCpcClient::Process
> > m_procs
;
882 Vector
<SimpleCpcClient::Process
> dummy
;
883 m_procs
.fill(config
.m_hosts
.size(), dummy
);
884 for(size_t i
= 0; i
<config
.m_hosts
.size(); i
++){
886 config
.m_hosts
[i
]->m_cpcd
->list_processes(m_procs
[i
], p
);
889 for(size_t i
= 0; i
<config
.m_processes
.size(); i
++){
890 atrt_process
& proc
= *config
.m_processes
[i
];
891 if(proc
.m_proc
.m_id
!= -1){
892 Vector
<SimpleCpcClient::Process
> &h_procs
= m_procs
[proc
.m_host
->m_index
];
894 for(size_t j
= 0; j
<h_procs
.size(); j
++){
895 if(proc
.m_proc
.m_id
== h_procs
[j
].m_id
){
897 proc
.m_proc
.m_status
= h_procs
[j
].m_status
;
902 g_logger
.error("update_status: not found");
903 g_logger
.error("id: %d host: %s cmd: %s",
905 proc
.m_host
->m_hostname
.c_str(),
906 proc
.m_proc
.m_path
.c_str());
907 for(size_t j
= 0; j
<h_procs
.size(); j
++){
908 g_logger
.error("found: %d %s", h_procs
[j
].m_id
,
909 h_procs
[j
].m_path
.c_str());
919 is_running(atrt_config
& config
, int types
){
920 int found
= 0, running
= 0;
921 for(size_t i
= 0; i
<config
.m_processes
.size(); i
++){
922 atrt_process
& proc
= *config
.m_processes
[i
];
923 if((types
& proc
.m_type
) != 0){
925 if(proc
.m_proc
.m_status
== "running")
939 insert(const char * pair
, Properties
& p
){
940 BaseString
tmp(pair
);
944 Vector
<BaseString
> split
;
945 tmp
.split(split
, ":=", 2);
947 if(split
.size() != 2)
950 p
.put(split
[0].trim().c_str(), split
[1].trim().c_str());
956 read_test_case(FILE * file
, atrt_testcase
& tc
, int& line
){
962 if(!fgets(buf
, 1024, file
))
966 BaseString tmp
= buf
;
968 if(tmp
.length() > 0 && tmp
.c_str()[0] == '#')
971 if(insert(tmp
.c_str(), p
) != 0)
981 Vector
<BaseString
> split
;
982 tmp
.split(split
, " ", 2);
983 tc
.m_command
= split
[0];
984 if(split
.size() == 2)
985 tc
.m_args
= split
[1];
988 tc
.m_max_time
= 60000;
994 if(!p
.get("cmd", tc
.m_command
)){
995 g_logger
.critical("Invalid test file: cmd is missing near line: %d", line
);
999 if(!p
.get("args", tc
.m_args
))
1002 const char * mt
= 0;
1003 if(!p
.get("max-time", &mt
))
1004 tc
.m_max_time
= 60000;
1006 tc
.m_max_time
= atoi(mt
);
1008 if(p
.get("type", &mt
) && strcmp(mt
, "bench") == 0)
1013 if(p
.get("run-all", &mt
) && strcmp(mt
, "yes") == 0)
1016 tc
.m_run_all
= false;
1018 if (!p
.get("name", &mt
))
1020 tc
.m_name
.assfmt("%s %s",
1021 tc
.m_command
.c_str(),
1026 tc
.m_name
.assign(mt
);
1033 setup_test_case(atrt_config
& config
, const atrt_testcase
& tc
){
1034 g_logger
.debug("system(%s)", g_clear_progname
);
1035 const int r1
= system(g_clear_progname
);
1037 g_logger
.critical("Failed to clear result");
1042 for(; i
<config
.m_processes
.size(); i
++)
1044 atrt_process
& proc
= *config
.m_processes
[i
];
1045 if(proc
.m_type
== atrt_process::AP_NDB_API
|| proc
.m_type
== atrt_process::AP_CLIENT
){
1046 proc
.m_proc
.m_path
= "";
1047 if (tc
.m_command
.c_str()[0] != '/')
1049 proc
.m_proc
.m_path
.appfmt("%s/bin/", g_prefix
);
1051 proc
.m_proc
.m_path
.append(tc
.m_command
.c_str());
1052 proc
.m_proc
.m_args
.assign(tc
.m_args
);
1057 for(i
++; i
<config
.m_processes
.size(); i
++){
1058 atrt_process
& proc
= *config
.m_processes
[i
];
1059 if(proc
.m_type
== atrt_process::AP_NDB_API
|| proc
.m_type
== atrt_process::AP_CLIENT
){
1060 proc
.m_proc
.m_path
.assign("");
1061 proc
.m_proc
.m_args
.assign("");
1068 gather_result(atrt_config
& config
, int * result
){
1069 BaseString tmp
= g_gather_progname
;
1071 for(size_t i
= 0; i
<config
.m_hosts
.size(); i
++)
1073 tmp
.appfmt(" %s:%s/*",
1074 config
.m_hosts
[i
]->m_hostname
.c_str(),
1075 config
.m_hosts
[i
]->m_basedir
.c_str());
1078 g_logger
.debug("system(%s)", tmp
.c_str());
1079 const int r1
= system(tmp
.c_str());
1082 g_logger
.critical("Failed to gather result!");
1086 g_logger
.debug("system(%s)", g_analyze_progname
);
1087 const int r2
= system(g_analyze_progname
);
1089 if(r2
== -1 || r2
== (127 << 8))
1091 g_logger
.critical("Failed to analyze results");
1100 setup_hosts(atrt_config
& config
){
1101 g_logger
.debug("system(%s)", g_clear_progname
);
1102 const int r1
= system(g_clear_progname
);
1104 g_logger
.critical("Failed to clear result");
1108 for(size_t i
= 0; i
<config
.m_hosts
.size(); i
++){
1109 BaseString tmp
= g_setup_progname
;
1110 tmp
.appfmt(" %s %s/ %s/",
1111 config
.m_hosts
[i
]->m_hostname
.c_str(),
1113 config
.m_hosts
[i
]->m_basedir
.c_str());
1115 g_logger
.debug("system(%s)", tmp
.c_str());
1116 const int r1
= system(tmp
.c_str());
1118 g_logger
.critical("Failed to setup %s",
1119 config
.m_hosts
[i
]->m_hostname
.c_str());
1127 deploy(atrt_config
& config
)
1129 for (size_t i
= 0; i
<config
.m_hosts
.size(); i
++)
1131 BaseString tmp
= g_setup_progname
;
1132 tmp
.appfmt(" %s %s/ %s",
1133 config
.m_hosts
[i
]->m_hostname
.c_str(),
1137 g_logger
.info("rsyncing %s to %s", g_prefix
,
1138 config
.m_hosts
[i
]->m_hostname
.c_str());
1139 g_logger
.debug("system(%s)", tmp
.c_str());
1140 const int r1
= system(tmp
.c_str());
1143 g_logger
.critical("Failed to rsync %s to %s",
1145 config
.m_hosts
[i
]->m_hostname
.c_str());
1154 sshx(atrt_config
& config
, unsigned mask
)
1156 for (size_t i
= 0; i
<config
.m_processes
.size(); i
++)
1158 atrt_process
& proc
= *config
.m_processes
[i
];
1161 const char * type
= 0;
1162 switch(proc
.m_type
){
1163 case atrt_process::AP_NDB_MGMD
:
1164 type
= (mask
& proc
.m_type
) ? "ndb_mgmd" : 0;
1166 case atrt_process::AP_NDBD
:
1167 type
= (mask
& proc
.m_type
) ? "ndbd" : 0;
1169 case atrt_process::AP_MYSQLD
:
1170 type
= (mask
& proc
.m_type
) ? "mysqld" : 0;
1172 case atrt_process::AP_NDB_API
:
1173 type
= (mask
& proc
.m_type
) ? "ndbapi" : 0;
1175 case atrt_process::AP_CLIENT
:
1176 type
= (mask
& proc
.m_type
) ? "client" : 0;
1185 tmp
.appfmt("xterm -fg black -title \"%s(%s) on %s\""
1186 " -e 'ssh -t -X %s sh %s/ssh-login.sh' &",
1188 proc
.m_cluster
->m_name
.c_str(),
1189 proc
.m_host
->m_hostname
.c_str(),
1190 proc
.m_host
->m_hostname
.c_str(),
1191 proc
.m_proc
.m_cwd
.c_str());
1193 g_logger
.debug("system(%s)", tmp
.c_str());
1194 const int r1
= system(tmp
.c_str());
1197 g_logger
.critical("Failed sshx (%s)",
1201 NdbSleep_MilliSleep(300); // To prevent xlock problem
1208 start(atrt_config
& config
, unsigned proc_mask
)
1210 if (proc_mask
& atrt_process::AP_NDB_MGMD
)
1211 if(!start_processes(g_config
, atrt_process::AP_NDB_MGMD
))
1214 if (proc_mask
& atrt_process::AP_NDBD
)
1216 if(!connect_ndb_mgm(g_config
)){
1220 if(!start_processes(g_config
, atrt_process::AP_NDBD
))
1223 if(!wait_ndb(g_config
, NDB_MGM_NODE_STATUS_NOT_STARTED
))
1226 for(Uint32 i
= 0; i
<3; i
++)
1227 if(wait_ndb(g_config
, NDB_MGM_NODE_STATUS_STARTED
))
1233 if(!start_processes(g_config
, p_servers
& proc_mask
))
1246 template class Vector
<Vector
<SimpleCpcClient::Process
> >;
1247 template class Vector
<atrt_host
*>;
1248 template class Vector
<atrt_cluster
*>;
1249 template class Vector
<atrt_process
*>;