[PATCH] WL#3704 mgmapi timeouts: Return sane errors for timeout in mgmapi

In ndb_mgm_call, add checks for expired timeout in (Input|Output)Stream.
In case of timeout, we set NdbMgmHandle->last_error and return NULL.

In api calls not using ndb_mgm_call (or using it in conjunction with
own IO), they'll need to check for timeouts manually. Macros are provided
to do this.

Add ndb_mgm_disconnect_quiet(h) to disconnect without checking errors
(so we don't clobber NdbMgmHandle->last_error). This helps us provide
the *consistent* semantic that on timeout we leave the NdbMgmHandle
*disconnected*. We check for this in testMgm.

Change CHECK_REPLY in mgmapi to also check for set error in handle->last_error
This will pick up the ETIMEDOUT errors and return them to client (through
returning correct failure code for API call and setting NdbMgmHandle error).
Applications written to MGMAPI before this patch will behave as before,
and even hopefully check get_last_error and report the error back to the
end user!

Adding the last CHECK_TIMEDOUT_RET and delete in ndb_mgm_call() we
slightly change behaviour of mgmapi. Previously, if disconnect
midway through a reply, where there were only optional parameters left,
we'd get a Properties object from ndb_mgm_call() containing NULLs for
the optional parameters, leading to interesting error messages. This
enables the returning of the *real* message and actually improves the API
without breaking compatibility.

ndb_mgm_start_signallog
ndb_mgm_stop_signallog
ndb_mgm_log_signals
ndb_mgm_set_trace
ndb_mgm_insert_error
ndb_mgm_set_int64_parameter [1]
ndb_mgm_set_string_parameter [1]
ndb_mgm_purge_stale_sessions [2]
 - return error code on error during ndb_mgm_call

TODO:
ndb_mgm_report_event [2]

[1] marked for removal, unused.
[2] return codes incorrect in CHECK_HANDLE/CONNECTED. undocumented.


Server side:
 in Services (per session) add macro for injecting timeout error
 (just waiting 10 seconds before continuing... it does work!)

 We inject these errors in a number of critical places - including
 the tricky api functions that don't just use ndb_mgm_call but do
 their own thing (get_config, get_status and friends)

ATRT:
 Expand testMgm to add timout tests for API. Fully automated.
 *THEORETICALLY* timing dependent - an ultra-slow network will
 cause problems and "fake" failures... I welcome other solutions.

 Tests aren't exhaustive, but cover the generics and the tricky bits.
 Also test some calling semantics (incl disconnected on error).

 It is encouraged to add *more* mgmapi tests, not less :)

InputStream:
  Fix where timedout error is set


Index: ndb-work/storage/ndb/src/mgmapi/mgmapi.cpp
===================================================================
parent 64361ee3
...@@ -59,6 +59,7 @@ SocketInputStream::gets(char * buf, int bufLen) { ...@@ -59,6 +59,7 @@ SocketInputStream::gets(char * buf, int bufLen) {
if(res == 0) if(res == 0)
{ {
m_timedout= true;
buf[0]=0; buf[0]=0;
return buf; return buf;
} }
...@@ -67,7 +68,6 @@ SocketInputStream::gets(char * buf, int bufLen) { ...@@ -67,7 +68,6 @@ SocketInputStream::gets(char * buf, int bufLen) {
if(res == -1) if(res == -1)
{ {
m_timedout= true;
return 0; return 0;
} }
......
...@@ -137,18 +137,41 @@ setError(NdbMgmHandle h, int error, int error_line, const char * msg, ...){ ...@@ -137,18 +137,41 @@ setError(NdbMgmHandle h, int error, int error_line, const char * msg, ...){
return ret; \ return ret; \
} }
#define CHECK_REPLY(reply, ret) \ #define CHECK_REPLY(handle, reply, ret) \
if(reply == NULL) { \ if(reply == NULL) { \
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \ if(!handle->last_error) \
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
return ret; \ return ret; \
} }
#define DBUG_CHECK_REPLY(reply, ret) \ #define DBUG_CHECK_REPLY(handle, reply, ret) \
if (reply == NULL) { \ if (reply == NULL) { \
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \ if(!handle->last_error) \
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, ""); \
DBUG_RETURN(ret); \ DBUG_RETURN(ret); \
} }
#define CHECK_TIMEDOUT(in, out) \
if(in.timedout() || out.timedout()) \
SET_ERROR(handle, ETIMEDOUT, \
"Time out talking to management server");
#define CHECK_TIMEDOUT_RET(h, in, out, ret) \
if(in.timedout() || out.timedout()) { \
SET_ERROR(handle, ETIMEDOUT, \
"Time out talking to management server"); \
ndb_mgm_disconnect_quiet(h); \
return ret; \
}
#define DBUG_CHECK_TIMEDOUT_RET(h, in, out, ret) \
if(in.timedout() || out.timedout()) { \
SET_ERROR(handle, ETIMEDOUT, \
"Time out talking to management server"); \
ndb_mgm_disconnect_quiet(h); \
DBUG_RETURN(ret); \
}
/***************************************************************************** /*****************************************************************************
* Handles * Handles
*****************************************************************************/ *****************************************************************************/
...@@ -375,6 +398,8 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, ...@@ -375,6 +398,8 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
} }
out.println(""); out.println("");
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
Parser_t::Context ctx; Parser_t::Context ctx;
ParserDummy session(handle->socket); ParserDummy session(handle->socket);
Parser_t parser(command_reply, in, true, true, true); Parser_t parser(command_reply, in, true, true, true);
...@@ -382,14 +407,17 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, ...@@ -382,14 +407,17 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
const Properties* p = parser.parse(ctx, session); const Properties* p = parser.parse(ctx, session);
if (p == NULL){ if (p == NULL){
if(!ndb_mgm_is_connected(handle)) { if(!ndb_mgm_is_connected(handle)) {
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
else else
{ {
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
if(ctx.m_status==Parser_t::Eof if(ctx.m_status==Parser_t::Eof
|| ctx.m_status==Parser_t::NoLine) || ctx.m_status==Parser_t::NoLine)
{ {
ndb_mgm_disconnect(handle); ndb_mgm_disconnect(handle);
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
/** /**
...@@ -411,6 +439,10 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, ...@@ -411,6 +439,10 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply,
p->print(handle->logfile, "IN: "); p->print(handle->logfile, "IN: ");
} }
#endif #endif
if(p && (in.timedout() || out.timedout()))
delete p;
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
DBUG_RETURN(p); DBUG_RETURN(p);
} }
...@@ -603,6 +635,22 @@ ndb_mgm_get_fd(NdbMgmHandle handle) ...@@ -603,6 +635,22 @@ ndb_mgm_get_fd(NdbMgmHandle handle)
return handle->socket; return handle->socket;
} }
/**
* Disconnect from mgm server without error checking
* Should be used internally only.
* e.g. on timeout, we leave NdbMgmHandle disconnected
*/
extern "C"
int
ndb_mgm_disconnect_quiet(NdbMgmHandle handle)
{
NDB_CLOSE_SOCKET(handle->socket);
handle->socket = NDB_INVALID_SOCKET;
handle->connected = 0;
return 0;
}
/** /**
* Disconnect from a mgm server * Disconnect from a mgm server
*/ */
...@@ -614,11 +662,7 @@ ndb_mgm_disconnect(NdbMgmHandle handle) ...@@ -614,11 +662,7 @@ ndb_mgm_disconnect(NdbMgmHandle handle)
CHECK_HANDLE(handle, -1); CHECK_HANDLE(handle, -1);
CHECK_CONNECTED(handle, -1); CHECK_CONNECTED(handle, -1);
NDB_CLOSE_SOCKET(handle->socket); return ndb_mgm_disconnect_quiet(handle);
handle->socket = NDB_INVALID_SOCKET;
handle->connected = 0;
return 0;
} }
struct ndb_mgm_type_atoi struct ndb_mgm_type_atoi
...@@ -787,18 +831,24 @@ ndb_mgm_get_status(NdbMgmHandle handle) ...@@ -787,18 +831,24 @@ ndb_mgm_get_status(NdbMgmHandle handle)
out.println("get status"); out.println("get status");
out.println(""); out.println("");
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
char buf[1024]; char buf[1024];
if(!in.gets(buf, sizeof(buf))) if(!in.gets(buf, sizeof(buf)))
{ {
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected"); SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
return NULL; return NULL;
} }
if(strcmp("node status\n", buf) != 0) { if(strcmp("node status\n", buf) != 0) {
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
ndbout << in.timedout() << " " << out.timedout() << buf << endl;
SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf); SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
return NULL; return NULL;
} }
if(!in.gets(buf, sizeof(buf))) if(!in.gets(buf, sizeof(buf)))
{ {
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected"); SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, "Probably disconnected");
return NULL; return NULL;
} }
...@@ -807,6 +857,7 @@ ndb_mgm_get_status(NdbMgmHandle handle) ...@@ -807,6 +857,7 @@ ndb_mgm_get_status(NdbMgmHandle handle)
Vector<BaseString> split; Vector<BaseString> split;
tmp.split(split, ":"); tmp.split(split, ":");
if(split.size() != 2){ if(split.size() != 2){
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf); SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
return NULL; return NULL;
} }
...@@ -841,8 +892,12 @@ ndb_mgm_get_status(NdbMgmHandle handle) ...@@ -841,8 +892,12 @@ ndb_mgm_get_status(NdbMgmHandle handle)
if(!in.gets(buf, sizeof(buf))) if(!in.gets(buf, sizeof(buf)))
{ {
free(state); free(state);
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY, if(in.timedout() || out.timedout())
"Probably disconnected"); SET_ERROR(handle, ETIMEDOUT,
"Time out talking to management server");
else
SET_ERROR(handle, NDB_MGM_ILLEGAL_SERVER_REPLY,
"Probably disconnected");
return NULL; return NULL;
} }
tmp.assign(buf); tmp.assign(buf);
...@@ -873,6 +928,7 @@ ndb_mgm_get_status(NdbMgmHandle handle) ...@@ -873,6 +928,7 @@ ndb_mgm_get_status(NdbMgmHandle handle)
if(i+1 != noOfNodes){ if(i+1 != noOfNodes){
free(state); free(state);
CHECK_TIMEDOUT_RET(handle, in, out, NULL);
SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, "Node count mismatch"); SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, "Node count mismatch");
return NULL; return NULL;
} }
...@@ -901,7 +957,7 @@ ndb_mgm_enter_single_user(NdbMgmHandle handle, ...@@ -901,7 +957,7 @@ ndb_mgm_enter_single_user(NdbMgmHandle handle,
args.put("nodeId", nodeId); args.put("nodeId", nodeId);
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, enter_single_reply, "enter single user", &args); reply = ndb_mgm_call(handle, enter_single_reply, "enter single user", &args);
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
BaseString result; BaseString result;
reply->get("result", result); reply->get("result", result);
...@@ -932,7 +988,7 @@ ndb_mgm_exit_single_user(NdbMgmHandle handle, struct ndb_mgm_reply* /*reply*/) ...@@ -932,7 +988,7 @@ ndb_mgm_exit_single_user(NdbMgmHandle handle, struct ndb_mgm_reply* /*reply*/)
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, exit_single_reply, "exit single user", 0); reply = ndb_mgm_call(handle, exit_single_reply, "exit single user", 0);
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
const char * buf; const char * buf;
reply->get("result", &buf); reply->get("result", &buf);
...@@ -1029,7 +1085,7 @@ ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -1029,7 +1085,7 @@ ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
reply = ndb_mgm_call(handle, stop_reply_v2, "stop all", &args); reply = ndb_mgm_call(handle, stop_reply_v2, "stop all", &args);
else else
reply = ndb_mgm_call(handle, stop_reply_v1, "stop all", &args); reply = ndb_mgm_call(handle, stop_reply_v1, "stop all", &args);
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
if(!reply->get("stopped", &stoppedNoOfNodes)){ if(!reply->get("stopped", &stoppedNoOfNodes)){
SET_ERROR(handle, NDB_MGM_STOP_FAILED, SET_ERROR(handle, NDB_MGM_STOP_FAILED,
...@@ -1071,7 +1127,7 @@ ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -1071,7 +1127,7 @@ ndb_mgm_stop3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
else else
reply = ndb_mgm_call(handle, stop_reply_v1, "stop", &args); reply = ndb_mgm_call(handle, stop_reply_v1, "stop", &args);
CHECK_REPLY(reply, stoppedNoOfNodes); CHECK_REPLY(handle, reply, stoppedNoOfNodes);
if(!reply->get("stopped", &stoppedNoOfNodes)){ if(!reply->get("stopped", &stoppedNoOfNodes)){
SET_ERROR(handle, NDB_MGM_STOP_FAILED, SET_ERROR(handle, NDB_MGM_STOP_FAILED,
"Could not get number of stopped nodes from mgm server"); "Could not get number of stopped nodes from mgm server");
...@@ -1174,7 +1230,7 @@ ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes, const int * node_list, ...@@ -1174,7 +1230,7 @@ ndb_mgm_restart3(NdbMgmHandle handle, int no_of_nodes, const int * node_list,
handle->read_timeout= 5*60*1000; // 5 minutes handle->read_timeout= 5*60*1000; // 5 minutes
reply = ndb_mgm_call(handle, restart_reply_v1, "restart all", &args); reply = ndb_mgm_call(handle, restart_reply_v1, "restart all", &args);
handle->read_timeout= timeout; handle->read_timeout= timeout;
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
BaseString result; BaseString result;
reply->get("result", result); reply->get("result", result);
...@@ -1301,7 +1357,7 @@ ndb_mgm_get_clusterlog_severity_filter(NdbMgmHandle handle, ...@@ -1301,7 +1357,7 @@ ndb_mgm_get_clusterlog_severity_filter(NdbMgmHandle handle,
Properties args; Properties args;
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args); reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args);
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
for(unsigned int i=0; i < severity_size; i++) { for(unsigned int i=0; i < severity_size; i++) {
reply->get(clusterlog_severity_names[severity[i].category], &severity[i].value); reply->get(clusterlog_severity_names[severity[i].category], &severity[i].value);
...@@ -1332,7 +1388,7 @@ ndb_mgm_get_clusterlog_severity_filter_old(NdbMgmHandle handle) ...@@ -1332,7 +1388,7 @@ ndb_mgm_get_clusterlog_severity_filter_old(NdbMgmHandle handle)
Properties args; Properties args;
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args); reply = ndb_mgm_call(handle, getinfo_reply, "get info clusterlog", &args);
CHECK_REPLY(reply, NULL); CHECK_REPLY(handle, reply, NULL);
for(int i=0; i < (int)NDB_MGM_EVENT_SEVERITY_ALL; i++) { for(int i=0; i < (int)NDB_MGM_EVENT_SEVERITY_ALL; i++) {
reply->get(clusterlog_severity_names[i], &enabled[i]); reply->get(clusterlog_severity_names[i], &enabled[i]);
...@@ -1364,7 +1420,7 @@ ndb_mgm_set_clusterlog_severity_filter(NdbMgmHandle handle, ...@@ -1364,7 +1420,7 @@ ndb_mgm_set_clusterlog_severity_filter(NdbMgmHandle handle,
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, filter_reply, "set logfilter", &args); reply = ndb_mgm_call(handle, filter_reply, "set logfilter", &args);
CHECK_REPLY(reply, retval); CHECK_REPLY(handle, reply, retval);
BaseString result; BaseString result;
reply->get("result", result); reply->get("result", result);
...@@ -1458,7 +1514,7 @@ ndb_mgm_get_clusterlog_loglevel(NdbMgmHandle handle, ...@@ -1458,7 +1514,7 @@ ndb_mgm_get_clusterlog_loglevel(NdbMgmHandle handle,
Properties args; Properties args;
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args); reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args);
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
for(int i=0; i < loglevel_count; i++) { for(int i=0; i < loglevel_count; i++) {
reply->get(clusterlog_names[loglevel[i].category], &loglevel[i].value); reply->get(clusterlog_names[loglevel[i].category], &loglevel[i].value);
...@@ -1494,7 +1550,7 @@ ndb_mgm_get_clusterlog_loglevel_old(NdbMgmHandle handle) ...@@ -1494,7 +1550,7 @@ ndb_mgm_get_clusterlog_loglevel_old(NdbMgmHandle handle)
Properties args; Properties args;
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args); reply = ndb_mgm_call(handle, getloglevel_reply, "get cluster loglevel", &args);
CHECK_REPLY(reply, NULL); CHECK_REPLY(handle, reply, NULL);
for(int i=0; i < loglevel_count; i++) { for(int i=0; i < loglevel_count; i++) {
reply->get(clusterlog_names[i], &loglevel[i]); reply->get(clusterlog_names[i], &loglevel[i]);
...@@ -1527,7 +1583,7 @@ ndb_mgm_set_clusterlog_loglevel(NdbMgmHandle handle, int nodeId, ...@@ -1527,7 +1583,7 @@ ndb_mgm_set_clusterlog_loglevel(NdbMgmHandle handle, int nodeId,
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, clusterlog_reply, reply = ndb_mgm_call(handle, clusterlog_reply,
"set cluster loglevel", &args); "set cluster loglevel", &args);
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
DBUG_ENTER("ndb_mgm_set_clusterlog_loglevel"); DBUG_ENTER("ndb_mgm_set_clusterlog_loglevel");
DBUG_PRINT("enter",("node=%d, category=%d, level=%d", nodeId, cat, level)); DBUG_PRINT("enter",("node=%d, category=%d, level=%d", nodeId, cat, level));
...@@ -1565,7 +1621,7 @@ ndb_mgm_set_loglevel_node(NdbMgmHandle handle, int nodeId, ...@@ -1565,7 +1621,7 @@ ndb_mgm_set_loglevel_node(NdbMgmHandle handle, int nodeId,
args.put("level", level); args.put("level", level);
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, loglevel_reply, "set loglevel", &args); reply = ndb_mgm_call(handle, loglevel_reply, "set loglevel", &args);
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
BaseString result; BaseString result;
reply->get("result", result); reply->get("result", result);
...@@ -1624,7 +1680,7 @@ ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[], ...@@ -1624,7 +1680,7 @@ ndb_mgm_listen_event_internal(NdbMgmHandle handle, const int filter[],
if(reply == NULL) { if(reply == NULL) {
close(sockfd); close(sockfd);
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
} }
delete reply; delete reply;
return sockfd; return sockfd;
...@@ -1668,7 +1724,7 @@ ndb_mgm_dump_state(NdbMgmHandle handle, int nodeId, const int * _args, ...@@ -1668,7 +1724,7 @@ ndb_mgm_dump_state(NdbMgmHandle handle, int nodeId, const int * _args,
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, dump_state_reply, "dump state", &args); prop = ndb_mgm_call(handle, dump_state_reply, "dump state", &args);
CHECK_REPLY(prop, -1); CHECK_REPLY(handle, prop, -1);
BaseString result; BaseString result;
prop->get("result", result); prop->get("result", result);
...@@ -1705,6 +1761,7 @@ ndb_mgm_start_signallog(NdbMgmHandle handle, int nodeId, ...@@ -1705,6 +1761,7 @@ ndb_mgm_start_signallog(NdbMgmHandle handle, int nodeId,
start_signallog_reply, start_signallog_reply,
"start signallog", "start signallog",
&args); &args);
CHECK_REPLY(handle, prop, -1);
if(prop != NULL) { if(prop != NULL) {
BaseString result; BaseString result;
...@@ -1741,6 +1798,7 @@ ndb_mgm_stop_signallog(NdbMgmHandle handle, int nodeId, ...@@ -1741,6 +1798,7 @@ ndb_mgm_stop_signallog(NdbMgmHandle handle, int nodeId,
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, stop_signallog_reply, "stop signallog", &args); prop = ndb_mgm_call(handle, stop_signallog_reply, "stop signallog", &args);
CHECK_REPLY(handle, prop, -1);
if(prop != NULL) { if(prop != NULL) {
BaseString result; BaseString result;
...@@ -1805,6 +1863,7 @@ ndb_mgm_log_signals(NdbMgmHandle handle, int nodeId, ...@@ -1805,6 +1863,7 @@ ndb_mgm_log_signals(NdbMgmHandle handle, int nodeId,
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, stop_signallog_reply, "log signals", &args); prop = ndb_mgm_call(handle, stop_signallog_reply, "log signals", &args);
CHECK_REPLY(handle, prop, -1);
if(prop != NULL) { if(prop != NULL) {
BaseString result; BaseString result;
...@@ -1842,6 +1901,7 @@ ndb_mgm_set_trace(NdbMgmHandle handle, int nodeId, int traceNumber, ...@@ -1842,6 +1901,7 @@ ndb_mgm_set_trace(NdbMgmHandle handle, int nodeId, int traceNumber,
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, set_trace_reply, "set trace", &args); prop = ndb_mgm_call(handle, set_trace_reply, "set trace", &args);
CHECK_REPLY(handle, prop, -1);
if(prop != NULL) { if(prop != NULL) {
BaseString result; BaseString result;
...@@ -1879,6 +1939,7 @@ ndb_mgm_insert_error(NdbMgmHandle handle, int nodeId, int errorCode, ...@@ -1879,6 +1939,7 @@ ndb_mgm_insert_error(NdbMgmHandle handle, int nodeId, int errorCode,
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, insert_error_reply, "insert error", &args); prop = ndb_mgm_call(handle, insert_error_reply, "insert error", &args);
CHECK_REPLY(handle, prop, -1);
if(prop != NULL) { if(prop != NULL) {
BaseString result; BaseString result;
...@@ -1919,7 +1980,7 @@ ndb_mgm_start(NdbMgmHandle handle, int no_of_nodes, const int * node_list) ...@@ -1919,7 +1980,7 @@ ndb_mgm_start(NdbMgmHandle handle, int no_of_nodes, const int * node_list)
Properties args; Properties args;
const Properties *reply; const Properties *reply;
reply = ndb_mgm_call(handle, start_reply, "start all", &args); reply = ndb_mgm_call(handle, start_reply, "start all", &args);
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
Uint32 count = 0; Uint32 count = 0;
if(!reply->get("started", &count)){ if(!reply->get("started", &count)){
...@@ -1985,7 +2046,7 @@ ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed, ...@@ -1985,7 +2046,7 @@ ndb_mgm_start_backup(NdbMgmHandle handle, int wait_completed,
reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args); reply = ndb_mgm_call(handle, start_backup_reply, "start backup", &args);
handle->read_timeout= old_timeout; handle->read_timeout= old_timeout;
} }
CHECK_REPLY(reply, -1); CHECK_REPLY(handle, reply, -1);
BaseString result; BaseString result;
reply->get("result", result); reply->get("result", result);
...@@ -2019,7 +2080,7 @@ ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId, ...@@ -2019,7 +2080,7 @@ ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId,
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, stop_backup_reply, "abort backup", &args); prop = ndb_mgm_call(handle, stop_backup_reply, "abort backup", &args);
CHECK_REPLY(prop, -1); CHECK_REPLY(handle, prop, -1);
const char * buf; const char * buf;
prop->get("result", &buf); prop->get("result", &buf);
...@@ -2036,7 +2097,7 @@ ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId, ...@@ -2036,7 +2097,7 @@ ndb_mgm_abort_backup(NdbMgmHandle handle, unsigned int backupId,
extern "C" extern "C"
struct ndb_mgm_configuration * struct ndb_mgm_configuration *
ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
SET_ERROR(handle, NDB_MGM_NO_ERROR, "Executing: ndb_mgm_get_configuration");
CHECK_HANDLE(handle, 0); CHECK_HANDLE(handle, 0);
CHECK_CONNECTED(handle, 0); CHECK_CONNECTED(handle, 0);
...@@ -2054,7 +2115,7 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { ...@@ -2054,7 +2115,7 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, reply, "get config", &args); prop = ndb_mgm_call(handle, reply, "get config", &args);
CHECK_REPLY(prop, 0); CHECK_REPLY(handle, prop, 0);
do { do {
const char * buf; const char * buf;
...@@ -2091,9 +2152,14 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) { ...@@ -2091,9 +2152,14 @@ ndb_mgm_get_configuration(NdbMgmHandle handle, unsigned int version) {
size_t start = 0; size_t start = 0;
do { do {
if((read = read_socket(handle->socket, handle->read_timeout, if((read = read_socket(handle->socket, handle->read_timeout,
&buf64[start], len-start)) == -1){ &buf64[start], len-start)) < 1){
delete[] buf64; delete[] buf64;
buf64 = 0; buf64 = 0;
if(read==0)
SET_ERROR(handle, ETIMEDOUT, "Timeout reading packed config");
else
SET_ERROR(handle, errno, "Error reading packed config");
ndb_mgm_disconnect_quiet(handle);
break; break;
} }
start += read; start += read;
...@@ -2214,7 +2280,7 @@ ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype, ...@@ -2214,7 +2280,7 @@ ndb_mgm_alloc_nodeid(NdbMgmHandle handle, unsigned int version, int nodetype,
const Properties *prop; const Properties *prop;
prop= ndb_mgm_call(handle, reply, "get nodeid", &args); prop= ndb_mgm_call(handle, reply, "get nodeid", &args);
CHECK_REPLY(prop, -1); CHECK_REPLY(handle, prop, -1);
nodeid= -1; nodeid= -1;
do { do {
...@@ -2266,7 +2332,7 @@ ndb_mgm_set_int_parameter(NdbMgmHandle handle, ...@@ -2266,7 +2332,7 @@ ndb_mgm_set_int_parameter(NdbMgmHandle handle,
const Properties *prop; const Properties *prop;
prop= ndb_mgm_call(handle, reply, "set parameter", &args); prop= ndb_mgm_call(handle, reply, "set parameter", &args);
CHECK_REPLY(prop, -1); CHECK_REPLY(handle, prop, -1);
int res= -1; int res= -1;
do { do {
...@@ -2305,7 +2371,8 @@ ndb_mgm_set_int64_parameter(NdbMgmHandle handle, ...@@ -2305,7 +2371,8 @@ ndb_mgm_set_int64_parameter(NdbMgmHandle handle,
const Properties *prop; const Properties *prop;
prop= ndb_mgm_call(handle, reply, "set parameter", &args); prop= ndb_mgm_call(handle, reply, "set parameter", &args);
CHECK_REPLY(handle, prop, 0);
if(prop == NULL) { if(prop == NULL) {
SET_ERROR(handle, EIO, "Unable set parameter"); SET_ERROR(handle, EIO, "Unable set parameter");
return -1; return -1;
...@@ -2348,6 +2415,7 @@ ndb_mgm_set_string_parameter(NdbMgmHandle handle, ...@@ -2348,6 +2415,7 @@ ndb_mgm_set_string_parameter(NdbMgmHandle handle,
const Properties *prop; const Properties *prop;
prop= ndb_mgm_call(handle, reply, "set parameter", &args); prop= ndb_mgm_call(handle, reply, "set parameter", &args);
CHECK_REPLY(handle, prop, 0);
if(prop == NULL) { if(prop == NULL) {
SET_ERROR(handle, EIO, "Unable set parameter"); SET_ERROR(handle, EIO, "Unable set parameter");
...@@ -2385,7 +2453,8 @@ ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **purged){ ...@@ -2385,7 +2453,8 @@ ndb_mgm_purge_stale_sessions(NdbMgmHandle handle, char **purged){
const Properties *prop; const Properties *prop;
prop= ndb_mgm_call(handle, reply, "purge stale sessions", &args); prop= ndb_mgm_call(handle, reply, "purge stale sessions", &args);
CHECK_REPLY(handle, prop, -1);
if(prop == NULL) { if(prop == NULL) {
SET_ERROR(handle, EIO, "Unable to purge stale sessions"); SET_ERROR(handle, EIO, "Unable to purge stale sessions");
return -1; return -1;
...@@ -2470,7 +2539,7 @@ ndb_mgm_set_connection_int_parameter(NdbMgmHandle handle, ...@@ -2470,7 +2539,7 @@ ndb_mgm_set_connection_int_parameter(NdbMgmHandle handle,
const Properties *prop; const Properties *prop;
prop= ndb_mgm_call(handle, reply, "set connection parameter", &args); prop= ndb_mgm_call(handle, reply, "set connection parameter", &args);
DBUG_CHECK_REPLY(prop, -1); DBUG_CHECK_REPLY(handle, prop, -1);
int res= -1; int res= -1;
do { do {
...@@ -2512,7 +2581,7 @@ ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle, ...@@ -2512,7 +2581,7 @@ ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle,
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, reply, "get connection parameter", &args); prop = ndb_mgm_call(handle, reply, "get connection parameter", &args);
DBUG_CHECK_REPLY(prop, -3); DBUG_CHECK_REPLY(handle, prop, -3);
int res= -1; int res= -1;
do { do {
...@@ -2574,7 +2643,7 @@ ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle) ...@@ -2574,7 +2643,7 @@ ndb_mgm_get_mgmd_nodeid(NdbMgmHandle handle)
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, reply, "get mgmd nodeid", &args); prop = ndb_mgm_call(handle, reply, "get mgmd nodeid", &args);
DBUG_CHECK_REPLY(prop, 0); DBUG_CHECK_REPLY(handle, prop, 0);
if(!prop->get("nodeid",&nodeid)){ if(!prop->get("nodeid",&nodeid)){
fprintf(handle->errstream, "Unable to get value\n"); fprintf(handle->errstream, "Unable to get value\n");
...@@ -2609,7 +2678,7 @@ int ndb_mgm_report_event(NdbMgmHandle handle, Uint32 *data, Uint32 length) ...@@ -2609,7 +2678,7 @@ int ndb_mgm_report_event(NdbMgmHandle handle, Uint32 *data, Uint32 length)
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, reply, "report event", &args); prop = ndb_mgm_call(handle, reply, "report event", &args);
DBUG_CHECK_REPLY(prop, -1); DBUG_CHECK_REPLY(handle, prop, -1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -2628,6 +2697,7 @@ int ndb_mgm_end_session(NdbMgmHandle handle) ...@@ -2628,6 +2697,7 @@ int ndb_mgm_end_session(NdbMgmHandle handle)
SocketInputStream in(handle->socket, handle->read_timeout); SocketInputStream in(handle->socket, handle->read_timeout);
char buf[32]; char buf[32];
in.gets(buf, sizeof(buf)); in.gets(buf, sizeof(buf));
CHECK_TIMEDOUT_RET(handle, in, s_output, -1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -2653,7 +2723,7 @@ int ndb_mgm_get_version(NdbMgmHandle handle, ...@@ -2653,7 +2723,7 @@ int ndb_mgm_get_version(NdbMgmHandle handle,
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, reply, "get version", &args); prop = ndb_mgm_call(handle, reply, "get version", &args);
CHECK_REPLY(prop, 0); CHECK_REPLY(handle, prop, 0);
Uint32 id; Uint32 id;
if(!prop->get("id",&id)){ if(!prop->get("id",&id)){
...@@ -2704,7 +2774,7 @@ ndb_mgm_get_session_id(NdbMgmHandle handle) ...@@ -2704,7 +2774,7 @@ ndb_mgm_get_session_id(NdbMgmHandle handle)
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, reply, "get session id", &args); prop = ndb_mgm_call(handle, reply, "get session id", &args);
CHECK_REPLY(prop, 0); CHECK_REPLY(handle, prop, 0);
if(!prop->get("id",&session_id)){ if(!prop->get("id",&session_id)){
fprintf(handle->errstream, "Unable to get session id\n"); fprintf(handle->errstream, "Unable to get session id\n");
...@@ -2741,7 +2811,7 @@ ndb_mgm_get_session(NdbMgmHandle handle, Uint64 id, ...@@ -2741,7 +2811,7 @@ ndb_mgm_get_session(NdbMgmHandle handle, Uint64 id,
const Properties *prop; const Properties *prop;
prop = ndb_mgm_call(handle, reply, "get session", &args); prop = ndb_mgm_call(handle, reply, "get session", &args);
CHECK_REPLY(prop, 0); CHECK_REPLY(handle, prop, 0);
Uint64 r_id; Uint64 r_id;
int rlen= 0; int rlen= 0;
......
...@@ -68,6 +68,8 @@ extern "C" { ...@@ -68,6 +68,8 @@ extern "C" {
*/ */
NDB_SOCKET_TYPE ndb_mgm_convert_to_transporter(NdbMgmHandle *handle); NDB_SOCKET_TYPE ndb_mgm_convert_to_transporter(NdbMgmHandle *handle);
int ndb_mgm_disconnect_quiet(NdbMgmHandle handle);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
......
...@@ -290,6 +290,8 @@ struct PurgeStruct ...@@ -290,6 +290,8 @@ struct PurgeStruct
#define ERROR_INSERTED(x) (g_errorInsert == x || m_errorInsert == x) #define ERROR_INSERTED(x) (g_errorInsert == x || m_errorInsert == x)
#define SLEEP_ERROR_INSERTED(x) if(ERROR_INSERTED(x)){NdbSleep_SecSleep(10);}
MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id) MgmApiSession::MgmApiSession(class MgmtSrvr & mgm, NDB_SOCKET_TYPE sock, Uint64 session_id)
: SocketServer::Session(sock), m_mgmsrv(mgm) : SocketServer::Session(sock), m_mgmsrv(mgm)
{ {
...@@ -599,13 +601,23 @@ MgmApiSession::getConfig(Parser_t::Context &, ...@@ -599,13 +601,23 @@ MgmApiSession::getConfig(Parser_t::Context &,
char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length())); char *tmp_str = (char *) malloc(base64_needed_encoded_length(src.length()));
(void) base64_encode(src.get_data(), src.length(), tmp_str); (void) base64_encode(src.get_data(), src.length(), tmp_str);
SLEEP_ERROR_INSERTED(1);
m_output->println("get config reply"); m_output->println("get config reply");
m_output->println("result: Ok"); m_output->println("result: Ok");
m_output->println("Content-Length: %d", strlen(tmp_str)); m_output->println("Content-Length: %d", strlen(tmp_str));
m_output->println("Content-Type: ndbconfig/octet-stream"); m_output->println("Content-Type: ndbconfig/octet-stream");
SLEEP_ERROR_INSERTED(2);
m_output->println("Content-Transfer-Encoding: base64"); m_output->println("Content-Transfer-Encoding: base64");
m_output->println(""); m_output->println("");
if(ERROR_INSERTED(3))
{
int l= strlen(tmp_str);
tmp_str[l/2]='\0';
m_output->println(tmp_str);
NdbSleep_SecSleep(10);
}
m_output->println(tmp_str); m_output->println(tmp_str);
free(tmp_str); free(tmp_str);
...@@ -748,6 +760,7 @@ MgmApiSession::endSession(Parser<MgmApiSession>::Context &, ...@@ -748,6 +760,7 @@ MgmApiSession::endSession(Parser<MgmApiSession>::Context &,
m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv); m_allocated_resources= new MgmtSrvr::Allocated_resources(m_mgmsrv);
SLEEP_ERROR_INSERTED(1);
m_output->println("end session reply"); m_output->println("end session reply");
} }
...@@ -998,12 +1011,16 @@ MgmApiSession::getStatus(Parser<MgmApiSession>::Context &, ...@@ -998,12 +1011,16 @@ MgmApiSession::getStatus(Parser<MgmApiSession>::Context &,
while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM)){ while(m_mgmsrv.getNextNodeId(&nodeId, NDB_MGM_NODE_TYPE_MGM)){
noOfNodes++; noOfNodes++;
} }
SLEEP_ERROR_INSERTED(1);
m_output->println("node status"); m_output->println("node status");
SLEEP_ERROR_INSERTED(2);
m_output->println("nodes: %d", noOfNodes); m_output->println("nodes: %d", noOfNodes);
SLEEP_ERROR_INSERTED(3);
printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_NDB); printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_NDB);
printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_MGM); printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_MGM);
SLEEP_ERROR_INSERTED(4);
printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_API); printNodeStatus(m_output, m_mgmsrv, NDB_MGM_NODE_TYPE_API);
SLEEP_ERROR_INSERTED(5);
nodeId = 0; nodeId = 0;
...@@ -1118,8 +1135,10 @@ MgmApiSession::enterSingleUser(Parser<MgmApiSession>::Context &, ...@@ -1118,8 +1135,10 @@ MgmApiSession::enterSingleUser(Parser<MgmApiSession>::Context &,
Properties const &args) { Properties const &args) {
int stopped = 0; int stopped = 0;
Uint32 nodeId = 0; Uint32 nodeId = 0;
int result= 0;
args.get("nodeId", &nodeId); args.get("nodeId", &nodeId);
int result = m_mgmsrv.enterSingleUser(&stopped, nodeId);
result = m_mgmsrv.enterSingleUser(&stopped, nodeId);
m_output->println("enter single user reply"); m_output->println("enter single user reply");
if(result != 0) { if(result != 0) {
m_output->println("result: %s", get_error_text(result)); m_output->println("result: %s", get_error_text(result));
...@@ -1616,12 +1635,11 @@ void ...@@ -1616,12 +1635,11 @@ void
MgmApiSession::check_connection(Parser_t::Context &ctx, MgmApiSession::check_connection(Parser_t::Context &ctx,
const class Properties &args) const class Properties &args)
{ {
if(ERROR_INSERTED(1)) SLEEP_ERROR_INSERTED(1);
{
NdbSleep_SecSleep(10);
}
m_output->println("check connection reply"); m_output->println("check connection reply");
SLEEP_ERROR_INSERTED(2);
m_output->println("result: Ok"); m_output->println("result: Ok");
SLEEP_ERROR_INSERTED(3);
m_output->println(""); m_output->println("");
} }
...@@ -1642,10 +1660,7 @@ MgmApiSession::get_mgmd_nodeid(Parser_t::Context &ctx, ...@@ -1642,10 +1660,7 @@ MgmApiSession::get_mgmd_nodeid(Parser_t::Context &ctx,
{ {
m_output->println("get mgmd nodeid reply"); m_output->println("get mgmd nodeid reply");
m_output->println("nodeid:%u",m_mgmsrv.getOwnNodeId()); m_output->println("nodeid:%u",m_mgmsrv.getOwnNodeId());
if(ERROR_INSERTED(1)) SLEEP_ERROR_INSERTED(1);
{
NdbSleep_SecSleep(10);
}
m_output->println(""); m_output->println("");
} }
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <random.h> #include <random.h>
#include <mgmapi.h> #include <mgmapi.h>
#include <mgmapi_debug.h> #include <mgmapi_debug.h>
#include <InputStream.hpp>
int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
...@@ -191,6 +192,8 @@ int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step) ...@@ -191,6 +192,8 @@ int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step)
ndb_mgm_set_connectstring(h, mgm); ndb_mgm_set_connectstring(h, mgm);
ndb_mgm_connect(h,0,0,0); ndb_mgm_connect(h,0,0,0);
NdbSleep_SecSleep(1);
if(ndb_mgm_get_session(h,session_id,&sess,&slen)) if(ndb_mgm_get_session(h,session_id,&sess,&slen))
{ {
ndbout << "Failed, session still exists" << endl; ndbout << "Failed, session still exists" << endl;
...@@ -207,64 +210,278 @@ int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step) ...@@ -207,64 +210,278 @@ int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step)
} }
} }
int runTestApiTimeout1(NDBT_Context* ctx, NDBT_Step* step) int runTestApiTimeoutBasic(NDBT_Context* ctx, NDBT_Step* step)
{ {
char *mgm= ctx->getRemoteMgm(); char *mgm= ctx->getRemoteMgm();
int result= NDBT_FAILED; int result= NDBT_FAILED;
int cc= 0; int cc= 0;
int mgmd_nodeid= 0;
ndb_mgm_reply reply;
NdbMgmHandle h; NdbMgmHandle h;
h= ndb_mgm_create_handle(); h= ndb_mgm_create_handle();
ndb_mgm_set_connectstring(h, mgm); ndb_mgm_set_connectstring(h, mgm);
ndb_mgm_connect(h,0,0,0);
if(ndb_mgm_check_connection(h) < 0) ndbout << "TEST timout check_connection" << endl;
for(int error_ins=1; error_ins<=3; error_ins++)
{ {
result= NDBT_FAILED; ndbout << "trying error " << error_ins << endl;
goto done; ndb_mgm_connect(h,0,0,0);
if(ndb_mgm_check_connection(h) < 0)
{
result= NDBT_FAILED;
goto done;
}
mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
if(mgmd_nodeid==0)
{
ndbout << "Failed to get mgmd node id to insert error" << endl;
result= NDBT_FAILED;
goto done;
}
reply.return_code= 0;
if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
{
ndbout << "failed to insert error " << endl;
result= NDBT_FAILED;
goto done;
}
ndb_mgm_set_timeout(h,2500);
cc= ndb_mgm_check_connection(h);
if(cc < 0)
result= NDBT_OK;
else
result= NDBT_FAILED;
if(ndb_mgm_is_connected(h))
{
ndbout << "FAILED: still connected" << endl;
result= NDBT_FAILED;
}
} }
ndb_mgm_reply reply; ndbout << "TEST get_mgmd_nodeid" << endl;
reply.return_code= 0; ndb_mgm_connect(h,0,0,0);
if(ndb_mgm_insert_error(h, 3, 1, &reply)< 0) if(ndb_mgm_insert_error(h, mgmd_nodeid, 0, &reply)< 0)
{ {
ndbout << "failed to insert error " << endl; ndbout << "failed to remove inserted error " << endl;
result= NDBT_FAILED; result= NDBT_FAILED;
goto done; goto done;
} }
ndb_mgm_set_timeout(h,2500);
cc= ndb_mgm_check_connection(h);
if(cc < 0)
result= NDBT_OK;
else
result= NDBT_FAILED;
ndbout << "test 2" << endl;
ndb_mgm_connect(h,0,0,0);
cc= ndb_mgm_get_mgmd_nodeid(h); cc= ndb_mgm_get_mgmd_nodeid(h);
ndbout << "got node id: " << cc << endl;
if(cc==0) if(cc==0)
result= NDBT_OK; {
else ndbout << "FAILED: didn't get node id" << endl;
result= NDBT_FAILED; result= NDBT_FAILED;
}
else
result= NDBT_OK;
ndbout << "TEST end_session" << endl;
ndb_mgm_connect(h,0,0,0);
if(ndb_mgm_insert_error(h, 3, 0, &reply)< 0) if(ndb_mgm_insert_error(h, mgmd_nodeid, 1, &reply)< 0)
{ {
ndbout << "failed to remove inserted error " << endl; ndbout << "FAILED: insert error 1" << endl;
result= NDBT_FAILED; result= NDBT_FAILED;
goto done; goto done;
} }
cc= ndb_mgm_get_mgmd_nodeid(h); cc= ndb_mgm_end_session(h);
ndbout << "got node id: " << cc << endl;
if(cc==0) if(cc==0)
{
ndbout << "FAILED: success in calling end_session" << endl;
result= NDBT_FAILED;
}
else if(ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
{
ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
<< " != expected " << ETIMEDOUT << ") desc: "
<< ndb_mgm_get_latest_error_desc(h)
<< " line: " << ndb_mgm_get_latest_error_line(h)
<< " msg: " << ndb_mgm_get_latest_error_msg(h)
<< endl;
result= NDBT_FAILED; result= NDBT_FAILED;
}
else else
result= NDBT_OK; result= NDBT_OK;
if(ndb_mgm_is_connected(h))
{
ndbout << "FAILED: is still connected after error" << endl;
result= NDBT_FAILED;
}
done:
ndb_mgm_disconnect(h);
ndb_mgm_destroy_handle(&h);
return result;
}
int runTestApiGetStatusTimeout(NDBT_Context* ctx, NDBT_Step* step)
{
char *mgm= ctx->getRemoteMgm();
int result= NDBT_OK;
int cc= 0;
int mgmd_nodeid= 0;
NdbMgmHandle h;
h= ndb_mgm_create_handle();
ndb_mgm_set_connectstring(h, mgm);
for(int error_ins=0; error_ins<=5; error_ins++)
{
ndb_mgm_connect(h,0,0,0);
if(ndb_mgm_check_connection(h) < 0)
{
result= NDBT_FAILED;
goto done;
}
mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
if(mgmd_nodeid==0)
{
ndbout << "Failed to get mgmd node id to insert error" << endl;
result= NDBT_FAILED;
goto done;
}
ndb_mgm_reply reply;
reply.return_code= 0;
if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
{
ndbout << "failed to insert error " << error_ins << endl;
result= NDBT_FAILED;
}
ndbout << "trying error: " << error_ins << endl;
ndb_mgm_set_timeout(h,2500);
struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(h);
if(cl!=NULL)
free(cl);
/*
* For whatever strange reason,
* get_status is okay with not having the last enter there.
* instead of "fixing" the api, let's have a special case
* so we don't break any behaviour
*/
if(error_ins!=0 && error_ins!=5 && cl!=NULL)
{
ndbout << "FAILED: got a ndb_mgm_cluster_state back" << endl;
result= NDBT_FAILED;
}
if(error_ins!=0 && error_ins!=5 && ndb_mgm_is_connected(h))
{
ndbout << "FAILED: is still connected after error" << endl;
result= NDBT_FAILED;
}
if(error_ins!=0 && error_ins!=5 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
{
ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
<< " != expected " << ETIMEDOUT << ") desc: "
<< ndb_mgm_get_latest_error_desc(h)
<< " line: " << ndb_mgm_get_latest_error_line(h)
<< " msg: " << ndb_mgm_get_latest_error_msg(h)
<< endl;
result= NDBT_FAILED;
}
}
done:
ndb_mgm_disconnect(h);
ndb_mgm_destroy_handle(&h);
return result;
}
int runTestMgmApiGetConfigTimeout(NDBT_Context* ctx, NDBT_Step* step)
{
char *mgm= ctx->getRemoteMgm();
int result= NDBT_OK;
int mgmd_nodeid= 0;
NdbMgmHandle h;
h= ndb_mgm_create_handle();
ndb_mgm_set_connectstring(h, mgm);
for(int error_ins=0; error_ins<=3; error_ins++)
{
ndb_mgm_connect(h,0,0,0);
if(ndb_mgm_check_connection(h) < 0)
{
result= NDBT_FAILED;
goto done;
}
mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
if(mgmd_nodeid==0)
{
ndbout << "Failed to get mgmd node id to insert error" << endl;
result= NDBT_FAILED;
goto done;
}
ndb_mgm_reply reply;
reply.return_code= 0;
if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
{
ndbout << "failed to insert error " << error_ins << endl;
result= NDBT_FAILED;
}
ndbout << "trying error: " << error_ins << endl;
ndb_mgm_set_timeout(h,2500);
struct ndb_mgm_configuration *c= ndb_mgm_get_configuration(h,0);
if(c!=NULL)
free(c);
if(error_ins!=0 && c!=NULL)
{
ndbout << "FAILED: got a ndb_mgm_configuration back" << endl;
result= NDBT_FAILED;
}
if(error_ins!=0 && ndb_mgm_is_connected(h))
{
ndbout << "FAILED: is still connected after error" << endl;
result= NDBT_FAILED;
}
if(error_ins!=0 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
{
ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
<< " != expected " << ETIMEDOUT << ") desc: "
<< ndb_mgm_get_latest_error_desc(h)
<< " line: " << ndb_mgm_get_latest_error_line(h)
<< " msg: " << ndb_mgm_get_latest_error_msg(h)
<< endl;
result= NDBT_FAILED;
}
}
done: done:
ndb_mgm_disconnect(h); ndb_mgm_disconnect(h);
ndb_mgm_destroy_handle(&h); ndb_mgm_destroy_handle(&h);
...@@ -272,6 +489,103 @@ done: ...@@ -272,6 +489,103 @@ done:
return result; return result;
} }
int runTestMgmApiEventTimeout(NDBT_Context* ctx, NDBT_Step* step)
{
char *mgm= ctx->getRemoteMgm();
int result= NDBT_OK;
int mgmd_nodeid= 0;
NdbMgmHandle h;
h= ndb_mgm_create_handle();
ndb_mgm_set_connectstring(h, mgm);
for(int error_ins=0; error_ins<=3; error_ins++)
{
ndb_mgm_connect(h,0,0,0);
if(ndb_mgm_check_connection(h) < 0)
{
result= NDBT_FAILED;
goto done;
}
mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
if(mgmd_nodeid==0)
{
ndbout << "Failed to get mgmd node id to insert error" << endl;
result= NDBT_FAILED;
goto done;
}
ndb_mgm_reply reply;
reply.return_code= 0;
if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
{
ndbout << "failed to insert error " << error_ins << endl;
result= NDBT_FAILED;
}
ndbout << "trying error: " << error_ins << endl;
ndb_mgm_set_timeout(h,2500);
int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
1, NDB_MGM_EVENT_CATEGORY_STARTUP,
0 };
int fd= ndb_mgm_listen_event(h, filter);
if(fd==NDB_INVALID_SOCKET)
{
ndbout << "FAILED: could not listen to event" << endl;
result= NDBT_FAILED;
}
char *tmp= 0;
char buf[512];
SocketInputStream in(fd,20000);
do {
if((tmp = in.gets(buf, sizeof(buf))))
{
const char ping_token[]="<PING>";
if(memcmp(ping_token,tmp,sizeof(ping_token)-1))
if(tmp && strlen(tmp))
ndbout << tmp;
}
else
{
if(in.timedout())
{
ndbout << "TIMED OUT READING EVENT" << endl;
break;
}
}
} while(true);
if(error_ins!=0 && ndb_mgm_is_connected(h))
{
ndbout << "FAILED: is still connected after error" << endl;
result= NDBT_FAILED;
}
if(error_ins!=0 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
{
ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
<< " != expected " << ETIMEDOUT << ") desc: "
<< ndb_mgm_get_latest_error_desc(h)
<< " line: " << ndb_mgm_get_latest_error_line(h)
<< " msg: " << ndb_mgm_get_latest_error_msg(h)
<< endl;
result= NDBT_FAILED;
}
}
done:
ndb_mgm_disconnect(h);
ndb_mgm_destroy_handle(&h);
return result;
}
NDBT_TESTSUITE(testMgm); NDBT_TESTSUITE(testMgm);
TESTCASE("SingleUserMode", TESTCASE("SingleUserMode",
...@@ -284,9 +598,24 @@ TESTCASE("ApiSessionFailure", ...@@ -284,9 +598,24 @@ TESTCASE("ApiSessionFailure",
INITIALIZER(runTestApiSession); INITIALIZER(runTestApiSession);
} }
TESTCASE("ApiTimeout1", TESTCASE("ApiTimeoutBasic",
"Test timeout for MGMAPI"){ "Basic timeout tests for MGMAPI"){
INITIALIZER(runTestApiTimeout1); INITIALIZER(runTestApiTimeoutBasic);
}
TESTCASE("ApiGetStatusTimeout",
"Test timeout for MGMAPI getStatus"){
INITIALIZER(runTestApiGetStatusTimeout);
}
TESTCASE("ApiGetConfigTimeout",
"Test timeouts for mgmapi get_configuration"){
INITIALIZER(runTestMgmApiGetConfigTimeout);
}
TESTCASE("ApiMgmEventTimeout",
"Test timeouts for mgmapi get_configuration"){
INITIALIZER(runTestMgmApiEventTimeout);
} }
NDBT_TESTSUITE_END(testMgm); NDBT_TESTSUITE_END(testMgm);
......
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