MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
testMgm.cpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <NDBT.hpp>
19 #include <NDBT_Test.hpp>
20 #include "NdbMgmd.hpp"
21 #include <mgmapi.h>
22 #include <mgmapi_debug.h>
23 #include <InputStream.hpp>
24 #include <signaldata/EventReport.hpp>
25 #include <NdbRestarter.hpp>
26 #include <random.h>
27 
28 /*
29  Tests that only need the mgmd(s) started
30 
31  Start ndb_mgmd and set NDB_CONNECTSTRING pointing
32  to that/those ndb_mgmd(s), then run testMgm
33  */
34 
35 
36 int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step)
37 {
38  NdbMgmd mgmd;
39  Uint64 session_id= 0;
40 
41  NdbMgmHandle h;
43  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
44  ndb_mgm_connect(h,0,0,0);
45 #ifdef NDB_WIN
46  SOCKET s = ndb_mgm_get_fd(h);
47 #else
48  int s= ndb_mgm_get_fd(h);
49 #endif
50  session_id= ndb_mgm_get_session_id(h);
51  ndbout << "MGM Session id: " << session_id << endl;
52  send(s,"get",3,0);
55 
56  struct NdbMgmSession sess;
57  int slen= sizeof(struct NdbMgmSession);
58 
60  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
61  ndb_mgm_connect(h,0,0,0);
62 
63  NdbSleep_SecSleep(1);
64 
65  if(ndb_mgm_get_session(h,session_id,&sess,&slen))
66  {
67  ndbout << "Failed, session still exists" << endl;
70  return NDBT_FAILED;
71  }
72  else
73  {
74  ndbout << "SUCCESS: session is gone" << endl;
77  return NDBT_OK;
78  }
79 }
80 
81 int runTestApiConnectTimeout(NDBT_Context* ctx, NDBT_Step* step)
82 {
83  NdbMgmd mgmd;
84 
85  g_info << "Check connect works with timeout 3000" << endl;
86  if (!mgmd.set_timeout(3000))
87  return NDBT_FAILED;
88 
89  if (!mgmd.connect())
90  {
91  g_err << "Connect failed with timeout 3000" << endl;
92  return NDBT_FAILED;
93  }
94 
95  if (!mgmd.disconnect())
96  return NDBT_FAILED;
97 
98  g_info << "Check connect to illegal host will timeout after 3000" << endl;
99  if (!mgmd.set_timeout(3000))
100  return NDBT_FAILED;
101  mgmd.setConnectString("1.1.1.1");
102 
103  NDB_TICKS tstart= NdbTick_CurrentMillisecond();
104  if (mgmd.connect())
105  {
106  g_err << "Connect to illegal host suceeded" << endl;
107  return NDBT_FAILED;
108  }
109 
110  NDB_TICKS msecs= NdbTick_CurrentMillisecond() - tstart;
111  ndbout << "Took about " << msecs <<" milliseconds"<<endl;
112 
113  if(msecs > 6000)
114  {
115  g_err << "The connect to illegal host timedout after much longer "
116  << "time than was expected, expected <= 6000, got " << msecs << endl;
117  return NDBT_FAILED;
118  }
119  return NDBT_OK;
120 }
121 
122 
123 int runTestApiTimeoutBasic(NDBT_Context* ctx, NDBT_Step* step)
124 {
125  NdbMgmd mgmd;
126  int result= NDBT_FAILED;
127  int cc= 0;
128  int mgmd_nodeid= 0;
130 
131  NdbMgmHandle h;
133  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
134 
135  ndbout << "TEST timout check_connection" << endl;
136  int errs[] = { 1, 2, 3, -1};
137 
138  for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
139  {
140  int error_ins= errs[error_ins_no];
141  ndbout << "trying error " << error_ins << endl;
142  ndb_mgm_connect(h,0,0,0);
143 
144  if(ndb_mgm_check_connection(h) < 0)
145  {
146  result= NDBT_FAILED;
147  goto done;
148  }
149 
150  mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
151  if(mgmd_nodeid==0)
152  {
153  ndbout << "Failed to get mgmd node id to insert error" << endl;
154  result= NDBT_FAILED;
155  goto done;
156  }
157 
158  reply.return_code= 0;
159 
160  if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
161  {
162  ndbout << "failed to insert error " << endl;
163  result= NDBT_FAILED;
164  goto done;
165  }
166 
167  ndb_mgm_set_timeout(h,2500);
168 
169  cc= ndb_mgm_check_connection(h);
170  if(cc < 0)
171  result= NDBT_OK;
172  else
173  result= NDBT_FAILED;
174 
175  if(ndb_mgm_is_connected(h))
176  {
177  ndbout << "FAILED: still connected" << endl;
178  result= NDBT_FAILED;
179  }
180  }
181 
182  ndbout << "TEST get_mgmd_nodeid" << endl;
183  ndb_mgm_connect(h,0,0,0);
184 
185  if(ndb_mgm_insert_error(h, mgmd_nodeid, 0, &reply)< 0)
186  {
187  ndbout << "failed to remove inserted error " << endl;
188  result= NDBT_FAILED;
189  goto done;
190  }
191 
193  ndbout << "got node id: " << cc << endl;
194  if(cc==0)
195  {
196  ndbout << "FAILED: didn't get node id" << endl;
197  result= NDBT_FAILED;
198  }
199  else
200  result= NDBT_OK;
201 
202  ndbout << "TEST end_session" << endl;
203  ndb_mgm_connect(h,0,0,0);
204 
205  if(ndb_mgm_insert_error(h, mgmd_nodeid, 4, &reply)< 0)
206  {
207  ndbout << "FAILED: insert error 1" << endl;
208  result= NDBT_FAILED;
209  goto done;
210  }
211 
212  cc= ndb_mgm_end_session(h);
213  if(cc==0)
214  {
215  ndbout << "FAILED: success in calling end_session" << endl;
216  result= NDBT_FAILED;
217  }
218  else if(ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
219  {
220  ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
221  << " != expected " << ETIMEDOUT << ") desc: "
223  << " line: " << ndb_mgm_get_latest_error_line(h)
224  << " msg: " << ndb_mgm_get_latest_error_msg(h)
225  << endl;
226  result= NDBT_FAILED;
227  }
228  else
229  result= NDBT_OK;
230 
231  if(ndb_mgm_is_connected(h))
232  {
233  ndbout << "FAILED: is still connected after error" << endl;
234  result= NDBT_FAILED;
235  }
236 done:
239 
240  return result;
241 }
242 
243 int runTestApiGetStatusTimeout(NDBT_Context* ctx, NDBT_Step* step)
244 {
245  NdbMgmd mgmd;
246  int result= NDBT_OK;
247  int mgmd_nodeid= 0;
248 
249  NdbMgmHandle h;
251  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
252 
253  int errs[] = { 0, 5, 6, 7, 8, 9, -1 };
254 
255  for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
256  {
257  int error_ins= errs[error_ins_no];
258  ndb_mgm_connect(h,0,0,0);
259 
260  if(ndb_mgm_check_connection(h) < 0)
261  {
262  result= NDBT_FAILED;
263  goto done;
264  }
265 
266  mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
267  if(mgmd_nodeid==0)
268  {
269  ndbout << "Failed to get mgmd node id to insert error" << endl;
270  result= NDBT_FAILED;
271  goto done;
272  }
273 
274  ndb_mgm_reply reply;
275  reply.return_code= 0;
276 
277  if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
278  {
279  ndbout << "failed to insert error " << error_ins << endl;
280  result= NDBT_FAILED;
281  }
282 
283  ndbout << "trying error: " << error_ins << endl;
284 
285  ndb_mgm_set_timeout(h,2500);
286 
288 
289  if(cl!=NULL)
290  free(cl);
291 
292  /*
293  * For whatever strange reason,
294  * get_status is okay with not having the last enter there.
295  * instead of "fixing" the api, let's have a special case
296  * so we don't break any behaviour
297  */
298 
299  if(error_ins!=0 && error_ins!=9 && cl!=NULL)
300  {
301  ndbout << "FAILED: got a ndb_mgm_cluster_state back" << endl;
302  result= NDBT_FAILED;
303  }
304 
305  if(error_ins!=0 && error_ins!=9 && ndb_mgm_is_connected(h))
306  {
307  ndbout << "FAILED: is still connected after error" << endl;
308  result= NDBT_FAILED;
309  }
310 
311  if(error_ins!=0 && error_ins!=9 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
312  {
313  ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
314  << " != expected " << ETIMEDOUT << ") desc: "
316  << " line: " << ndb_mgm_get_latest_error_line(h)
317  << " msg: " << ndb_mgm_get_latest_error_msg(h)
318  << endl;
319  result= NDBT_FAILED;
320  }
321  }
322 
323 done:
326 
327  return result;
328 }
329 
330 int runTestMgmApiGetConfigTimeout(NDBT_Context* ctx, NDBT_Step* step)
331 {
332  NdbMgmd mgmd;
333  int result= NDBT_OK;
334  int mgmd_nodeid= 0;
335 
336  NdbMgmHandle h;
338  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
339 
340  int errs[] = { 0, 1, 2, 3, -1 };
341 
342  for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
343  {
344  int error_ins= errs[error_ins_no];
345  ndb_mgm_connect(h,0,0,0);
346 
347  if(ndb_mgm_check_connection(h) < 0)
348  {
349  result= NDBT_FAILED;
350  goto done;
351  }
352 
353  mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
354  if(mgmd_nodeid==0)
355  {
356  ndbout << "Failed to get mgmd node id to insert error" << endl;
357  result= NDBT_FAILED;
358  goto done;
359  }
360 
361  ndb_mgm_reply reply;
362  reply.return_code= 0;
363 
364  if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
365  {
366  ndbout << "failed to insert error " << error_ins << endl;
367  result= NDBT_FAILED;
368  }
369 
370  ndbout << "trying error: " << error_ins << endl;
371 
372  ndb_mgm_set_timeout(h,2500);
373 
375 
376  if(c!=NULL)
377  free(c);
378 
379  if(error_ins!=0 && c!=NULL)
380  {
381  ndbout << "FAILED: got a ndb_mgm_configuration back" << endl;
382  result= NDBT_FAILED;
383  }
384 
385  if(error_ins!=0 && ndb_mgm_is_connected(h))
386  {
387  ndbout << "FAILED: is still connected after error" << endl;
388  result= NDBT_FAILED;
389  }
390 
391  if(error_ins!=0 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
392  {
393  ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
394  << " != expected " << ETIMEDOUT << ") desc: "
396  << " line: " << ndb_mgm_get_latest_error_line(h)
397  << " msg: " << ndb_mgm_get_latest_error_msg(h)
398  << endl;
399  result= NDBT_FAILED;
400  }
401  }
402 
403 done:
406 
407  return result;
408 }
409 
410 int runTestMgmApiEventTimeout(NDBT_Context* ctx, NDBT_Step* step)
411 {
412  NdbMgmd mgmd;
413  int result= NDBT_OK;
414  int mgmd_nodeid= 0;
415 
416  NdbMgmHandle h;
418  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
419 
420  int errs[] = { 10000, 0, -1 };
421 
422  for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
423  {
424  int error_ins= errs[error_ins_no];
425  ndb_mgm_connect(h,0,0,0);
426 
427  if(ndb_mgm_check_connection(h) < 0)
428  {
429  result= NDBT_FAILED;
430  goto done;
431  }
432 
433  mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
434  if(mgmd_nodeid==0)
435  {
436  ndbout << "Failed to get mgmd node id to insert error" << endl;
437  result= NDBT_FAILED;
438  goto done;
439  }
440 
441  ndb_mgm_reply reply;
442  reply.return_code= 0;
443 
444  if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
445  {
446  ndbout << "failed to insert error " << error_ins << endl;
447  result= NDBT_FAILED;
448  }
449 
450  ndbout << "trying error: " << error_ins << endl;
451 
452  ndb_mgm_set_timeout(h,2500);
453 
454  int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
456  0 };
457 
458  NDB_SOCKET_TYPE my_fd;
459 #ifdef NDB_WIN
460  SOCKET fd= ndb_mgm_listen_event(h, filter);
461  my_fd.s= fd;
462 #else
463  int fd= ndb_mgm_listen_event(h, filter);
464  my_fd.fd= fd;
465 #endif
466 
467  if(!my_socket_valid(my_fd))
468  {
469  ndbout << "FAILED: could not listen to event" << endl;
470  result= NDBT_FAILED;
471  }
472 
473  union {
474  Uint32 theData[25];
475  EventReport repData;
476  };
477  EventReport *fake_event = &repData;
478  fake_event->setEventType(NDB_LE_NDBStopForced);
479  fake_event->setNodeId(42);
480  theData[2]= 0;
481  theData[3]= 0;
482  theData[4]= 0;
483  theData[5]= 0;
484 
485  ndb_mgm_report_event(h, theData, 6);
486 
487  char *tmp= 0;
488  char buf[512];
489 
490  SocketInputStream in(my_fd,2000);
491  for(int i=0; i<20; i++)
492  {
493  if((tmp = in.gets(buf, sizeof(buf))))
494  {
495 // const char ping_token[]="<PING>";
496 // if(memcmp(ping_token,tmp,sizeof(ping_token)-1))
497  if(tmp && strlen(tmp))
498  ndbout << tmp;
499  }
500  else
501  {
502  if(in.timedout())
503  {
504  ndbout << "TIMED OUT READING EVENT at iteration " << i << endl;
505  break;
506  }
507  }
508  }
509 
510  /*
511  * events go through a *DIFFERENT* socket than the NdbMgmHandle
512  * so we should still be connected (and be able to check_connection)
513  *
514  */
515 
516  if(ndb_mgm_check_connection(h) && !ndb_mgm_is_connected(h))
517  {
518  ndbout << "FAILED: is still connected after error" << endl;
519  result= NDBT_FAILED;
520  }
521 
523  }
524 
525 done:
528 
529  return result;
530 }
531 
532 int runTestMgmApiStructEventTimeout(NDBT_Context* ctx, NDBT_Step* step)
533 {
534  NdbMgmd mgmd;
535  int result= NDBT_OK;
536  int mgmd_nodeid= 0;
537 
538  NdbMgmHandle h;
540  ndb_mgm_set_connectstring(h, mgmd.getConnectString());
541 
542  int errs[] = { 10000, 0, -1 };
543 
544  for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
545  {
546  int error_ins= errs[error_ins_no];
547  ndb_mgm_connect(h,0,0,0);
548 
549  if(ndb_mgm_check_connection(h) < 0)
550  {
551  result= NDBT_FAILED;
552  goto done;
553  }
554 
555  mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
556  if(mgmd_nodeid==0)
557  {
558  ndbout << "Failed to get mgmd node id to insert error" << endl;
559  result= NDBT_FAILED;
560  goto done;
561  }
562 
563  ndb_mgm_reply reply;
564  reply.return_code= 0;
565 
566  if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
567  {
568  ndbout << "failed to insert error " << error_ins << endl;
569  result= NDBT_FAILED;
570  }
571 
572  ndbout << "trying error: " << error_ins << endl;
573 
574  ndb_mgm_set_timeout(h,2500);
575 
576  int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
578  0 };
580 
581  struct ndb_logevent le;
582  for(int i=0; i<20; i++)
583  {
584  if(error_ins==0 || (error_ins!=0 && i<5))
585  {
586  union {
587  Uint32 theData[25];
588  EventReport repData;
589  };
590  EventReport *fake_event = &repData;
591  fake_event->setEventType(NDB_LE_NDBStopForced);
592  fake_event->setNodeId(42);
593  theData[2]= 0;
594  theData[3]= 0;
595  theData[4]= 0;
596  theData[5]= 0;
597 
598  ndb_mgm_report_event(h, theData, 6);
599  }
600  int r= ndb_logevent_get_next(le_handle, &le, 2500);
601  if(r>0)
602  {
603  ndbout << "Receieved event" << endl;
604  }
605  else if(r<0)
606  {
607  ndbout << "ERROR" << endl;
608  }
609  else // no event
610  {
611  ndbout << "TIMED OUT READING EVENT at iteration " << i << endl;
612  if(error_ins==0)
613  result= NDBT_FAILED;
614  else
615  result= NDBT_OK;
616  break;
617  }
618  }
619 
620  /*
621  * events go through a *DIFFERENT* socket than the NdbMgmHandle
622  * so we should still be connected (and be able to check_connection)
623  *
624  */
625 
626  if(ndb_mgm_check_connection(h) && !ndb_mgm_is_connected(h))
627  {
628  ndbout << "FAILED: is still connected after error" << endl;
629  result= NDBT_FAILED;
630  }
631 
633  }
634 
635 done:
638 
639  return result;
640 }
641 
642 #include <mgmapi_internal.h>
643 
644 int runSetConfig(NDBT_Context* ctx, NDBT_Step* step)
645 {
646  NdbMgmd mgmd;
647 
648  if (!mgmd.connect())
649  return NDBT_FAILED;
650 
651  int loops= ctx->getNumLoops();
652  for (int l= 0; l < loops; l++){
653  g_info << l << ": ";
654 
655  struct ndb_mgm_configuration* conf=
656  ndb_mgm_get_configuration(mgmd.handle(), 0);
657  if (!conf)
658  {
659  g_err << "ndb_mgm_get_configuration failed, error: "
660  << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl;
661  return NDBT_FAILED;
662  }
663 
664  int r= ndb_mgm_set_configuration(mgmd.handle(), conf);
665  free(conf);
666 
667  if (r != 0)
668  {
669  g_err << "ndb_mgm_set_configuration failed, error: "
670  << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl;
671  return NDBT_FAILED;
672  }
673  }
674  return NDBT_OK;
675 }
676 
677 
678 int runSetConfigUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
679 {
680  int result= NDBT_OK;
681  while(!ctx->isTestStopped() &&
682  (result= runSetConfig(ctx, step)) == NDBT_OK)
683  ;
684  return result;
685 }
686 
687 
688 int runGetConfig(NDBT_Context* ctx, NDBT_Step* step)
689 {
690  NdbMgmd mgmd;
691 
692  if (!mgmd.connect())
693  return NDBT_FAILED;
694 
695  int loops= ctx->getNumLoops();
696  for (int l= 0; l < loops; l++){
697  g_info << l << ": ";
698  struct ndb_mgm_configuration* conf=
699  ndb_mgm_get_configuration(mgmd.handle(), 0);
700  if (!conf)
701  return NDBT_FAILED;
702  free(conf);
703  }
704  return NDBT_OK;
705 }
706 
707 
708 int runGetConfigUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
709 {
710  int result= NDBT_OK;
711  while(!ctx->isTestStopped() &&
712  (result= runGetConfig(ctx, step)) == NDBT_OK)
713  ;
714  return result;
715 }
716 
717 
718 // Find a random node of a given type.
719 
720 static bool
721 get_nodeid_of_type(NdbMgmd& mgmd, ndb_mgm_node_type type, int *nodeId)
722 {
724  node_types[2] = { type,
725  NDB_MGM_NODE_TYPE_UNKNOWN };
726 
727  ndb_mgm_cluster_state *cs = ndb_mgm_get_status2(mgmd.handle(), node_types);
728  if (cs == NULL)
729  {
730  g_err << "ndb_mgm_get_status2 failed, error: "
731  << ndb_mgm_get_latest_error(mgmd.handle()) << " "
732  << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl;
733  return false;
734  }
735 
736  int noOfNodes = cs->no_of_nodes;
737  int randomnode = myRandom48(noOfNodes);
738  ndb_mgm_node_state *ns = cs->node_states + randomnode;
739  assert(ns->node_type == (Uint32)type);
740  assert(ns->node_id);
741 
742  *nodeId = ns->node_id;
743  g_info << "Got node id " << *nodeId << " of type " << type << endl;
744 
745  free(cs);
746  return true;
747 }
748 
749 
750 // Ensure getting config from an illegal node fails.
751 // Return true in that case.
752 
753 static bool
754 get_config_from_illegal_node(NdbMgmd& mgmd, int nodeId)
755 {
756  struct ndb_mgm_configuration* conf=
757  ndb_mgm_get_configuration_from_node(mgmd.handle(), nodeId);
758 
759  // Get conf from an illegal node should fail.
760  if (ndb_mgm_get_latest_error(mgmd.handle()) != NDB_MGM_GET_CONFIG_FAILED)
761  {
762  g_err << "ndb_mgm_get_configuration from illegal node "
763  << nodeId << " not failed, error: "
764  << ndb_mgm_get_latest_error(mgmd.handle()) << " "
765  << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl;
766  return false;
767  }
768 
769  if (conf)
770  {
771  // Should not get a conf from an illegal node.
772  g_err << "ndb_mgm_get_configuration from illegal node: "
773  << nodeId << ", error: "
774  << ndb_mgm_get_latest_error(mgmd.handle()) << " "
775  << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl;
776  free(conf);
777  return false;
778  }
779  return true;
780 }
781 
782 
783 // Check get_config from a non-existing node fails.
784 
785 static bool
786 check_get_config_illegal_node(NdbMgmd& mgmd)
787 {
788  // Find a node that does not exist
789  Config conf;
790  if (!mgmd.get_config(conf))
791  return false;
792 
793  int nodeId = 0;
794  for(Uint32 i= 1; i < MAX_NODES; i++){
795  ConfigIter iter(&conf, CFG_SECTION_NODE);
796  if (iter.find(CFG_NODE_ID, i) != 0){
797  nodeId = i;
798  break;
799  }
800  }
801  if (nodeId == 0)
802  return true; // All nodes probably defined
803 
804  return get_config_from_illegal_node(mgmd, nodeId);
805 }
806 
807 
808 
809 // Check get_config from a non-NDB/MGM node type fails
810 
811 static bool
812 check_get_config_wrong_type(NdbMgmd& mgmd)
813 {
814  int nodeId = 0;
815 
816  if (get_nodeid_of_type(mgmd, NDB_MGM_NODE_TYPE_API, &nodeId))
817  {
818  return get_config_from_illegal_node(mgmd, nodeId);
819  }
820  // No API nodes found.
821  return true;
822 }
823 
824 /* Find management node or a random data node, and get config from it.
825  * Also ensure failure when getting config from
826  * an illegal node (a non-NDB/MGM type, nodeid not defined,
827  * or nodeid > MAX_NODES).
828  */
829 int runGetConfigFromNode(NDBT_Context* ctx, NDBT_Step* step)
830 {
831  NdbMgmd mgmd;
832  if (!mgmd.connect())
833  return NDBT_FAILED;
834 
835  if (!check_get_config_wrong_type(mgmd) ||
836  !check_get_config_illegal_node(mgmd) ||
837  !get_config_from_illegal_node(mgmd, MAX_NODES + 2))
838  {
839  return NDBT_FAILED;
840  }
841 
842  int loops= ctx->getNumLoops();
843  for (int l= 0; l < loops; l++)
844  {
845  /* Get config from a node of type:
846  * NDB_MGM_NODE_TYPE_NDB or NDB_MGM_NODE_TYPE_MGM
847  */
848  int myChoice = myRandom48(2);
849  ndb_mgm_node_type randomAllowedType = (myChoice) ?
852  int nodeId = 0;
853  if (get_nodeid_of_type(mgmd, randomAllowedType, &nodeId))
854  {
855  struct ndb_mgm_configuration* conf =
856  ndb_mgm_get_configuration_from_node(mgmd.handle(), nodeId);
857  if (!conf)
858  {
859  g_err << "ndb_mgm_get_configuration_from_node "
860  << nodeId << " failed, error: "
861  << ndb_mgm_get_latest_error(mgmd.handle()) << " "
862  << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl;
863  return NDBT_FAILED;
864  }
865  free(conf);
866  }
867  else
868  {
869  // ignore
870  }
871  }
872  return NDBT_OK;
873 }
874 
875 
876 int runGetConfigFromNodeUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
877 {
878  int result= NDBT_OK;
879  while(!ctx->isTestStopped() &&
880  (result= runGetConfigFromNode(ctx, step)) == NDBT_OK)
881  ;
882  return result;
883 }
884 
885 
886 int runTestStatus(NDBT_Context* ctx, NDBT_Step* step)
887 {
888  ndb_mgm_node_type types[2] = {
890  NDB_MGM_NODE_TYPE_UNKNOWN
891  };
892 
893  NdbMgmd mgmd;
894  struct ndb_mgm_cluster_state *state;
895  int iterations = ctx->getNumLoops();
896 
897  if (!mgmd.connect())
898  return NDBT_FAILED;
899 
900  int result= NDBT_OK;
901  while (iterations-- != 0 && result == NDBT_OK)
902  {
903  state = ndb_mgm_get_status(mgmd.handle());
904  if(state == NULL) {
905  ndbout_c("Could not get status!");
906  result= NDBT_FAILED;
907  continue;
908  }
909  free(state);
910 
911  state = ndb_mgm_get_status2(mgmd.handle(), types);
912  if(state == NULL){
913  ndbout_c("Could not get status2!");
914  result= NDBT_FAILED;
915  continue;
916  }
917  free(state);
918 
919  state = ndb_mgm_get_status2(mgmd.handle(), 0);
920  if(state == NULL){
921  ndbout_c("Could not get status2 second time!");
922  result= NDBT_FAILED;
923  continue;
924  }
925  free(state);
926  }
927  return result;
928 }
929 
930 
931 int runTestStatusUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
932 {
933  int result= NDBT_OK;
934  while(!ctx->isTestStopped() &&
935  (result= runTestStatus(ctx, step)) == NDBT_OK)
936  ;
937  return result;
938 }
939 
940 
941 static bool
942 get_nodeid(NdbMgmd& mgmd,
943  const Properties& args,
944  Properties& reply)
945 {
946  // Fill in default values of other args
947  Properties call_args(args);
948  if (!call_args.contains("version"))
949  call_args.put("version", 1);
950  if (!call_args.contains("nodetype"))
951  call_args.put("nodetype", 1);
952  if (!call_args.contains("nodeid"))
953  call_args.put("nodeid", 1);
954  if (!call_args.contains("user"))
955  call_args.put("user", "mysqld");
956  if (!call_args.contains("password"))
957  call_args.put("password", "mysqld");
958  if (!call_args.contains("public key"))
959  call_args.put("public key", "a public key");
960  if (!call_args.contains("name"))
961  call_args.put("name", "testMgm");
962  if (!call_args.contains("log_event"))
963  call_args.put("log_event", 1);
964  if (!call_args.contains("timeout"))
965  call_args.put("timeout", 100);
966 
967  if (!call_args.contains("endian"))
968  {
969  union { long l; char c[sizeof(long)]; } endian_check;
970  endian_check.l = 1;
971  call_args.put("endian", (endian_check.c[sizeof(long)-1])?"big":"little");
972  }
973 
974  if (!mgmd.call("get nodeid", call_args,
975  "get nodeid reply", reply))
976  {
977  g_err << "get_nodeid: mgmd.call failed" << endl;
978  return false;
979  }
980 
981  // reply.print();
982  return true;
983 }
984 
985 
986 static const char*
987 get_result(const Properties& reply)
988 {
989  const char* result;
990  if (!reply.get("result", &result)){
991  ndbout_c("result: no 'result' found in reply");
992  return NULL;
993  }
994  return result;
995 }
996 
997 
998 static bool result_contains(const Properties& reply,
999  const char* expected_result)
1000 {
1001  BaseString result(get_result(reply));
1002  if (strstr(result.c_str(), expected_result) == NULL){
1003  ndbout_c("result_contains: result string '%s' "
1004  "didn't contain expected result '%s'",
1005  result.c_str(), expected_result);
1006  return false;
1007  }
1008  g_info << " result: " << result << endl;
1009  return true;
1010 }
1011 
1012 
1013 static bool ok(const Properties& reply)
1014 {
1015  BaseString result(get_result(reply));
1016  if (result == "Ok")
1017  return true;
1018  return false;
1019 }
1020 
1021 static bool failed(const Properties& reply)
1022 {
1023  BaseString result(get_result(reply));
1024  if (result == "Failed")
1025  return true;
1026  return false;
1027 }
1028 
1029 static const char*
1030 get_message(const Properties& reply)
1031 {
1032  const char* message;
1033  if (!reply.get("message", &message)){
1034  ndbout_c("message: no 'message' found in reply");
1035  return NULL;
1036  }
1037  return message;
1038 }
1039 
1040 
1041 static bool message_contains(const Properties& reply,
1042  const char* expected_message)
1043 {
1044  BaseString message(get_message(reply));
1045  if (strstr(message.c_str(), expected_message) == NULL){
1046  ndbout_c("message_contains: message string '%s' "
1047  "didn't contain expected message '%s'",
1048  message.c_str(), expected_message);
1049  return false;
1050  }
1051  g_info << " message: " << message << endl;
1052  return true;
1053 }
1054 
1055 
1056 static bool get_nodeid_result_contains(NdbMgmd& mgmd,
1057  const Properties& args,
1058  const char* expected_result)
1059 {
1060  Properties reply;
1061  if (!get_nodeid(mgmd, args, reply))
1062  return false;
1063  return result_contains(reply, expected_result);
1064 }
1065 
1066 
1067 
1068 static bool
1069 check_get_nodeid_invalid_endian1(NdbMgmd& mgmd)
1070 {
1071  union { long l; char c[sizeof(long)]; } endian_check;
1072  endian_check.l = 1;
1073  Properties args;
1074  /* Set endian to opposite value */
1075  args.put("endian", (endian_check.c[sizeof(long)-1])?"little":"big");
1076  return get_nodeid_result_contains(mgmd, args,
1077  "Node does not have the same endian");
1078 }
1079 
1080 
1081 static bool
1082 check_get_nodeid_invalid_endian2(NdbMgmd& mgmd)
1083 {
1084  Properties args;
1085  /* Set endian to weird value */
1086  args.put("endian", "hepp");
1087  return get_nodeid_result_contains(mgmd, args,
1088  "Node does not have the same endian");
1089 }
1090 
1091 
1092 static bool
1093 check_get_nodeid_invalid_nodetype1(NdbMgmd& mgmd)
1094 {
1095  Properties args;
1096  args.put("nodetype", 37);
1097  return get_nodeid_result_contains(mgmd, args,
1098  "unknown nodetype 37");
1099 }
1100 
1101 static bool
1102 check_get_nodeid_invalid_nodeid(NdbMgmd& mgmd)
1103 {
1104  for (int nodeId = MAX_NODES; nodeId < MAX_NODES+2; nodeId++){
1105  g_info << "Testing invalid node " << nodeId << endl;;
1106 
1107  Properties args;
1108  args.put("nodeid", nodeId);
1109  BaseString expected;
1110  expected.assfmt("illegal nodeid %d", nodeId);
1111  if (!get_nodeid_result_contains(mgmd, args, expected.c_str()))
1112  return false;
1113  }
1114  return true;
1115 }
1116 
1117 static bool
1118 check_get_nodeid_dynamic_nodeid(NdbMgmd& mgmd)
1119 {
1120  bool result = true;
1121  Uint32 nodeId= 0; // Get dynamic node id
1122  for (int nodeType = NDB_MGM_NODE_TYPE_MIN;
1123  nodeType < NDB_MGM_NODE_TYPE_MAX; nodeType++){
1124  while(true)
1125  {
1126  g_info << "Testing dynamic nodeid " << nodeId
1127  << ", nodeType: " << nodeType << endl;
1128 
1129  Properties args;
1130  args.put("nodeid", nodeId);
1131  args.put("nodetype", nodeType);
1132  Properties reply;
1133  if (!get_nodeid(mgmd, args, reply))
1134  return false;
1135 
1136  /*
1137  Continue to get dynamic id's until
1138  an error "there is no more nodeid" occur
1139  */
1140  if (!ok(reply)){
1141  BaseString expected1;
1142  expected1.assfmt("No free node id found for %s",
1143  NdbMgmd::NodeType(nodeType).c_str());
1144  BaseString expected2;
1145  expected2.assfmt("Connection done from wrong host");
1146  if (!(result_contains(reply, expected1.c_str()) ||
1147  result_contains(reply, expected2.c_str())))
1148  result= false; // Got wrong error message
1149  break;
1150  }
1151  }
1152  }
1153  return result;
1154 }
1155 
1156 
1157 static bool
1158 check_get_nodeid_nonode(NdbMgmd& mgmd)
1159 {
1160  // Find a node that does not exist
1161  Config conf;
1162  if (!mgmd.get_config(conf))
1163  return false;
1164 
1165  Uint32 nodeId = 0;
1166  for(Uint32 i= 1; i < MAX_NODES; i++){
1167  ConfigIter iter(&conf, CFG_SECTION_NODE);
1168  if (iter.find(CFG_NODE_ID, i) != 0){
1169  nodeId = i;
1170  break;
1171  }
1172  }
1173  if (nodeId == 0)
1174  return true; // All nodes probably defined
1175 
1176  g_info << "Testing nonexisting node " << nodeId << endl;;
1177 
1178  Properties args;
1179  args.put("nodeid", nodeId);
1180  BaseString expected;
1181  expected.assfmt("No node defined with id=%d", nodeId);
1182  return get_nodeid_result_contains(mgmd, args, expected.c_str());
1183 }
1184 
1185 #if 0
1186 static bool
1187 check_get_nodeid_nodeid1(NdbMgmd& mgmd)
1188 {
1189  // Find a node that does exist
1190  Config conf;
1191  if (!mgmd.get_config(conf))
1192  return false;
1193 
1194  Uint32 nodeId = 0;
1195  Uint32 nodeType = NDB_MGM_NODE_TYPE_UNKNOWN;
1196  for(Uint32 i= 1; i < MAX_NODES; i++){
1197  ConfigIter iter(&conf, CFG_SECTION_NODE);
1198  if (iter.find(CFG_NODE_ID, i) == 0){
1199  nodeId = i;
1200  iter.get(CFG_TYPE_OF_SECTION, &nodeType);
1201  break;
1202  }
1203  }
1204  assert(nodeId);
1205  assert(nodeType != (Uint32)NDB_MGM_NODE_TYPE_UNKNOWN);
1206 
1207  Properties args, reply;
1208  args.put("nodeid",nodeId);
1209  args.put("nodetype",nodeType);
1210  if (!get_nodeid(mgmd, args, reply))
1211  {
1212  g_err << "check_get_nodeid_nodeid1: failed for "
1213  << "nodeid: " << nodeId << ", nodetype: " << nodeType << endl;
1214  return false;
1215  }
1216  reply.print();
1217  return ok(reply);
1218 }
1219 #endif
1220 
1221 static bool
1222 check_get_nodeid_wrong_nodetype(NdbMgmd& mgmd)
1223 {
1224  // Find a node that does exist
1225  Config conf;
1226  if (!mgmd.get_config(conf))
1227  return false;
1228 
1229  Uint32 nodeId = 0;
1230  Uint32 nodeType = NDB_MGM_NODE_TYPE_UNKNOWN;
1231  for(Uint32 i= 1; i < MAX_NODES; i++){
1232  ConfigIter iter(&conf, CFG_SECTION_NODE);
1233  if (iter.find(CFG_NODE_ID, i) == 0){
1234  nodeId = i;
1235  iter.get(CFG_TYPE_OF_SECTION, &nodeType);
1236  break;
1237  }
1238  }
1239  assert(nodeId && nodeType != (Uint32)NDB_MGM_NODE_TYPE_UNKNOWN);
1240 
1241  nodeType = (nodeType + 1) / NDB_MGM_NODE_TYPE_MAX;
1242  assert((int)nodeType >= (int)NDB_MGM_NODE_TYPE_MIN &&
1243  (int)nodeType <= (int)NDB_MGM_NODE_TYPE_MAX);
1244 
1245  Properties args, reply;
1246  args.put("nodeid",nodeId);
1247  args.put("nodeid",nodeType);
1248  if (!get_nodeid(mgmd, args, reply))
1249  {
1250  g_err << "check_get_nodeid_nodeid1: failed for "
1251  << "nodeid: " << nodeId << ", nodetype: " << nodeType << endl;
1252  return false;
1253  }
1254  BaseString expected;
1255  expected.assfmt("Id %d configured as", nodeId);
1256  return result_contains(reply, expected.c_str());
1257 }
1258 
1259 
1260 
1261 int runTestGetNodeId(NDBT_Context* ctx, NDBT_Step* step)
1262 {
1263  NdbMgmd mgmd;
1264 
1265  if (!mgmd.connect())
1266  return NDBT_FAILED;
1267 
1268  int result= NDBT_FAILED;
1269  if (
1270  check_get_nodeid_invalid_endian1(mgmd) &&
1271  check_get_nodeid_invalid_endian2(mgmd) &&
1272  check_get_nodeid_invalid_nodetype1(mgmd) &&
1273  check_get_nodeid_invalid_nodeid(mgmd) &&
1274  check_get_nodeid_dynamic_nodeid(mgmd) &&
1275  check_get_nodeid_nonode(mgmd) &&
1276 // check_get_nodeid_nodeid1(mgmd) &&
1277  check_get_nodeid_wrong_nodetype(mgmd) &&
1278  true)
1279  result= NDBT_OK;
1280 
1281  if (!mgmd.end_session())
1282  result= NDBT_FAILED;
1283 
1284  return result;
1285 }
1286 
1287 
1288 int runTestGetNodeIdUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
1289 {
1290  int result= NDBT_OK;
1291  while(!ctx->isTestStopped() &&
1292  (result= runTestGetNodeId(ctx, step)) == NDBT_OK)
1293  ;
1294  return result;
1295 }
1296 
1297 
1298 int runSleepAndStop(NDBT_Context* ctx, NDBT_Step* step)
1299 {
1300  int counter= 3*ctx->getNumLoops();
1301 
1302  while(!ctx->isTestStopped() && counter--)
1303  NdbSleep_SecSleep(1);;
1304  ctx->stopTest();
1305  return NDBT_OK;
1306 }
1307 
1308 
1309 static bool
1310 check_connection(NdbMgmd& mgmd)
1311 {
1312  Properties args, reply;
1313  mgmd.verbose(false); // Verbose off
1314  bool result= mgmd.call("check connection", args,
1315  "check connection reply", reply);
1316  mgmd.verbose(); // Verbose on
1317  return result;
1318 }
1319 
1320 
1321 static bool
1322 check_transporter_connect(NdbMgmd& mgmd, const char * hello)
1323 {
1324  SocketOutputStream out(mgmd.socket());
1325 
1326  // Call 'transporter connect'
1327  if (out.println("transporter connect\n"))
1328  {
1329  g_err << "Send failed" << endl;
1330  return false;
1331  }
1332 
1333  // Send the 'hello'
1334  g_info << "Client hello: '" << hello << "'" << endl;
1335  if (out.println("%s", hello))
1336  {
1337  g_err << "Send hello '" << hello << "' failed" << endl;
1338  return false;
1339  }
1340 
1341  // Should not be possible to read a reply now, socket
1342  // should have been closed
1343  if (check_connection(mgmd)){
1344  g_err << "not disconnected" << endl;
1345  return false;
1346  }
1347 
1348  // disconnect and connect again
1349  if (!mgmd.disconnect())
1350  return false;
1351  if (!mgmd.connect())
1352  return false;
1353 
1354  return true;
1355 }
1356 
1357 
1358 int runTestTransporterConnect(NDBT_Context* ctx, NDBT_Step* step)
1359 {
1360  NdbMgmd mgmd;
1361 
1362  if (!mgmd.connect())
1363  return NDBT_FAILED;
1364 
1365  int result = NDBT_FAILED;
1366  if (
1367  // Junk hello strings
1368  check_transporter_connect(mgmd, "hello") &&
1369  check_transporter_connect(mgmd, "hello again") &&
1370 
1371  // "Blow" the buffer
1372  check_transporter_connect(mgmd, "string_longer_than_buf_1234567890") &&
1373 
1374  // Out of range nodeid
1375  check_transporter_connect(mgmd, "-1") &&
1376  check_transporter_connect(mgmd, "-2 2") &&
1377  check_transporter_connect(mgmd, "10000") &&
1378  check_transporter_connect(mgmd, "99999 8") &&
1379 
1380  // Valid nodeid, invalid transporter type
1381  // Valid nodeid and transporter type, state != CONNECTING
1382  // ^These are only possible to test by finding an existing
1383  // NDB node that are not started and use its setting(s)
1384 
1385  true)
1386  result = NDBT_OK;
1387 
1388  return result;
1389 }
1390 
1391 
1392 static bool
1393 show_config(NdbMgmd& mgmd,
1394  const Properties& args,
1395  Properties& reply)
1396 {
1397  if (!mgmd.call("show config", args,
1398  "show config reply", reply, NULL, false))
1399  {
1400  g_err << "show_config: mgmd.call failed" << endl;
1401  return false;
1402  }
1403 
1404  // reply.print();
1405  return true;
1406 }
1407 
1408 
1409 int runCheckConfig(NDBT_Context* ctx, NDBT_Step* step)
1410 {
1411  NdbMgmd mgmd;
1412 
1413  // Connect to any mgmd and get the config
1414  if (!mgmd.connect())
1415  return NDBT_FAILED;
1416 
1417  Properties args1;
1418  Properties config1;
1419  if (!show_config(mgmd, args1, config1))
1420  return NDBT_FAILED;
1421 
1422  // Get the binary config
1423  Config conf;
1424  if (!mgmd.get_config(conf))
1425  return NDBT_FAILED;
1426 
1427  // Extract list of connectstrings to each mgmd
1428  BaseString connectstring;
1429  conf.getConnectString(connectstring, ";");
1430 
1431  Vector<BaseString> mgmds;
1432  connectstring.split(mgmds, ";");
1433 
1434  // Connect to each mgmd and check
1435  // they all have the same config
1436  for (size_t i = 0; i < mgmds.size(); i++)
1437  {
1438  NdbMgmd mgmd2;
1439  g_info << "Connecting to " << mgmds[i].c_str() << endl;
1440  if (!mgmd2.connect(mgmds[i].c_str()))
1441  return NDBT_FAILED;
1442 
1443  Properties args2;
1444  Properties config2;
1445  if (!show_config(mgmd, args2, config2))
1446  return NDBT_FAILED;
1447 
1448  // Compare config1 and config2 line by line
1449  Uint32 line = 1;
1450  const char* value1;
1451  const char* value2;
1452  while (true)
1453  {
1454  if (config1.get("line", line, &value1))
1455  {
1456  // config1 had line, so should config2
1457  if (config2.get("line", line, &value2))
1458  {
1459  // both configs had line, check they are equal
1460  if (strcmp(value1, value2) != 0)
1461  {
1462  g_err << "the value on line " << line << "didn't match!" << endl;
1463  g_err << "config1, value: " << value1 << endl;
1464  g_err << "config2, value: " << value2 << endl;
1465  return NDBT_FAILED;
1466  }
1467  // g_info << line << ": " << value1 << " = " << value2 << endl;
1468  }
1469  else
1470  {
1471  g_err << "config2 didn't have line " << line << "!" << endl;
1472  return NDBT_FAILED;
1473  }
1474  }
1475  else
1476  {
1477  // Make sure config2 does not have this line either and end loop
1478  if (config2.get("line", line, &value2))
1479  {
1480  g_err << "config2 had line " << line << " not in config1!" << endl;
1481  return NDBT_FAILED;
1482  }
1483 
1484  // End of loop
1485  g_info << "There was " << line << " lines in config" << endl;
1486  break;
1487  }
1488  line++;
1489  }
1490  if (line == 0)
1491  {
1492  g_err << "FAIL: config should have lines!" << endl;
1493  return NDBT_FAILED;
1494  }
1495 
1496  // Compare the binary config
1497  Config conf2;
1498  if (!mgmd.get_config(conf2))
1499  return NDBT_FAILED;
1500 
1501  if (!conf.equal(&conf2))
1502  {
1503  g_err << "The binary config was different! host: " << mgmds[i] << endl;
1504  return NDBT_FAILED;
1505  }
1506 
1507  }
1508 
1509  return NDBT_OK;
1510 }
1511 
1512 
1513 static bool
1514 reload_config(NdbMgmd& mgmd,
1515  const Properties& args,
1516  Properties& reply)
1517 {
1518  if (!mgmd.call("reload config", args,
1519  "reload config reply", reply))
1520  {
1521  g_err << "reload config: mgmd.call failed" << endl;
1522  return false;
1523  }
1524 
1525  //reply.print();
1526  return true;
1527 }
1528 
1529 
1530 static bool reload_config_result_contains(NdbMgmd& mgmd,
1531  const Properties& args,
1532  const char* expected_result)
1533 {
1534  Properties reply;
1535  if (!reload_config(mgmd, args, reply))
1536  return false;
1537  return result_contains(reply, expected_result);
1538 }
1539 
1540 
1541 static bool
1542 check_reload_config_both_config_and_mycnf(NdbMgmd& mgmd)
1543 {
1544  Properties args;
1545  // Send reload command with both config_filename and mycnf set
1546  args.put("config_filename", "some filename");
1547  args.put("mycnf", 1);
1548  return reload_config_result_contains(mgmd, args,
1549  "ERROR: Both mycnf and config_filename");
1550 }
1551 
1552 
1553 static bool
1554 show_variables(NdbMgmd& mgmd, Properties& reply)
1555 {
1556  if (!mgmd.call("show variables", "",
1557  "show variables reply", reply))
1558  {
1559  g_err << "show_variables: mgmd.call failed" << endl;
1560  return false;
1561  }
1562  return true;
1563 }
1564 
1565 
1566 static bool
1567 check_reload_config_invalid_config_filename(NdbMgmd& mgmd, bool mycnf)
1568 {
1569 
1570  BaseString expected("Could not load configuration from 'nonexisting_file");
1571  if (mycnf)
1572  {
1573  // Differing error message if started from my.cnf
1574  expected.assign("Can't switch to use config.ini 'nonexisting_file' "
1575  "when node was started from my.cnf");
1576  }
1577 
1578  Properties args;
1579  // Send reload command with an invalid config_filename
1580  args.put("config_filename", "nonexisting_file");
1581  return reload_config_result_contains(mgmd, args, expected.c_str());
1582 }
1583 
1584 
1585 int runTestReloadConfig(NDBT_Context* ctx, NDBT_Step* step)
1586 {
1587  NdbMgmd mgmd;
1588 
1589  if (!mgmd.connect())
1590  return NDBT_FAILED;
1591 
1592  Properties variables;
1593  if (!show_variables(mgmd, variables))
1594  return NDBT_FAILED;
1595 
1596  variables.print();
1597 
1598  const char* mycnf_str;
1599  if (!variables.get("mycnf", &mycnf_str))
1600  abort();
1601  bool uses_mycnf = (strcmp(mycnf_str, "yes") == 0);
1602 
1603  int result= NDBT_FAILED;
1604  if (
1605  check_reload_config_both_config_and_mycnf(mgmd) &&
1606  check_reload_config_invalid_config_filename(mgmd, uses_mycnf) &&
1607  true)
1608  result= NDBT_OK;
1609 
1610  if (!mgmd.end_session())
1611  result= NDBT_FAILED;
1612 
1613  return result;
1614 }
1615 
1616 
1617 static bool
1618 set_config(NdbMgmd& mgmd,
1619  const Properties& args,
1620  BaseString encoded_config,
1621  Properties& reply)
1622 {
1623 
1624  // Fill in default values of other args
1625  Properties call_args(args);
1626  if (!call_args.contains("Content-Type"))
1627  call_args.put("Content-Type", "ndbconfig/octet-stream");
1628  if (!call_args.contains("Content-Transfer-Encoding"))
1629  call_args.put("Content-Transfer-Encoding", "base64");
1630  if (!call_args.contains("Content-Length"))
1631  call_args.put("Content-Length",
1632  encoded_config.length() ? encoded_config.length() - 1 : 1);
1633 
1634  if (!mgmd.call("set config", call_args,
1635  "set config reply", reply,
1636  encoded_config.c_str()))
1637  {
1638  g_err << "set config: mgmd.call failed" << endl;
1639  return false;
1640  }
1641 
1642  //reply.print();
1643  return true;
1644 }
1645 
1646 
1647 static bool set_config_result_contains(NdbMgmd& mgmd,
1648  const Properties& args,
1649  const BaseString& encoded_config,
1650  const char* expected_result)
1651 {
1652  Properties reply;
1653  if (!set_config(mgmd, args, encoded_config, reply))
1654  return false;
1655  return result_contains(reply, expected_result);
1656 }
1657 
1658 
1659 static bool set_config_result_contains(NdbMgmd& mgmd,
1660  const Config& conf,
1661  const char* expected_result)
1662 {
1663  Properties reply;
1664  Properties args;
1665 
1666  BaseString encoded_config;
1667  if (!conf.pack64(encoded_config))
1668  return false;
1669 
1670  if (!set_config(mgmd, args, encoded_config, reply))
1671  return false;
1672  return result_contains(reply, expected_result);
1673 }
1674 
1675 
1676 static bool
1677 check_set_config_invalid_content_type(NdbMgmd& mgmd)
1678 {
1679  Properties args;
1680  args.put("Content-Type", "illegal type");
1681  return set_config_result_contains(mgmd, args, BaseString(""),
1682  "Unhandled content type 'illegal type'");
1683 }
1684 
1685 static bool
1686 check_set_config_invalid_content_encoding(NdbMgmd& mgmd)
1687 {
1688  Properties args;
1689  args.put("Content-Transfer-Encoding", "illegal encoding");
1690  return set_config_result_contains(mgmd, args, BaseString(""),
1691  "Unhandled content encoding "
1692  "'illegal encoding'");
1693 }
1694 
1695 static bool
1696 check_set_config_too_large_content_length(NdbMgmd& mgmd)
1697 {
1698  Properties args;
1699  args.put("Content-Length", 1024*1024 + 1);
1700  return set_config_result_contains(mgmd, args, BaseString(""),
1701  "Illegal config length size 1048577");
1702 }
1703 
1704 static bool
1705 check_set_config_too_small_content_length(NdbMgmd& mgmd)
1706 {
1707  Properties args;
1708  args.put("Content-Length", (Uint32)0);
1709  return set_config_result_contains(mgmd, args, BaseString(""),
1710  "Illegal config length size 0");
1711 }
1712 
1713 static bool
1714 check_set_config_wrong_config_length(NdbMgmd& mgmd)
1715 {
1716 
1717  // Get the binary config
1718  Config conf;
1719  if (!mgmd.get_config(conf))
1720  return false;
1721 
1722  BaseString encoded_config;
1723  if (!conf.pack64(encoded_config))
1724  return false;
1725 
1726  Properties args;
1727  args.put("Content-Length", encoded_config.length() - 20);
1728  bool res = set_config_result_contains(mgmd, args, encoded_config,
1729  "Failed to unpack config");
1730 
1731  if (res){
1732  /*
1733  There are now additional 20 bytes of junk that has been
1734  sent to mgmd, reconnect to get rid of it
1735  */
1736  if (!mgmd.disconnect())
1737  return false;
1738  if (!mgmd.connect())
1739  return false;
1740  }
1741  return res;
1742 }
1743 
1744 static bool
1745 check_set_config_any_node(NDBT_Context* ctx, NDBT_Step* step, NdbMgmd& mgmd)
1746 {
1747 
1748  // Get the binary config
1749  Config conf;
1750  if (!mgmd.get_config(conf))
1751  return false;
1752 
1753  // Extract list of connectstrings to each mgmd
1754  BaseString connectstring;
1755  conf.getConnectString(connectstring, ";");
1756 
1757  Vector<BaseString> mgmds;
1758  connectstring.split(mgmds, ";");
1759 
1760  // Connect to each mgmd and check
1761  // they all have the same config
1762  for (size_t i = 0; i < mgmds.size(); i++)
1763  {
1764  NdbMgmd mgmd2;
1765  g_info << "Connecting to " << mgmds[i].c_str() << endl;
1766  if (!mgmd2.connect(mgmds[i].c_str()))
1767  return false;
1768 
1769  // Get the binary config
1770  Config conf2;
1771  if (!mgmd2.get_config(conf2))
1772  return false;
1773 
1774 #if 0
1775  // Change one value in the config
1776  if (!conf2.setValue(CFG_SECTION_NODE, 0,
1777  CFG_NODE_ARBIT_DELAY,
1778 #endif
1779 
1780  // Set the modified config
1781  if (!mgmd2.set_config(conf2))
1782  return false;
1783 
1784  // Check that all mgmds now have the new config
1785  if (runCheckConfig(ctx, step) != NDBT_OK)
1786  return false;
1787 
1788  }
1789 
1790  return true;
1791 }
1792 
1793 static bool
1794 check_set_config_fail_wrong_generation(NdbMgmd& mgmd)
1795 {
1796  // Get the binary config
1797  Config conf;
1798  if (!mgmd.get_config(conf))
1799  return false;
1800 
1801  // Change generation
1802  if (!conf.setGeneration(conf.getGeneration() + 10))
1803  return false;
1804 
1805  // Set the modified config
1806  return set_config_result_contains(mgmd, conf,
1807  "Invalid generation in");
1808 }
1809 
1810 static bool
1811 check_set_config_fail_wrong_name(NdbMgmd& mgmd)
1812 {
1813  // Get the binary config
1814  Config conf;
1815  if (!mgmd.get_config(conf))
1816  return false;
1817 
1818  // Change name
1819  if (!conf.setName("NEWNAME"))
1820  return false;
1821 
1822  // Set the modified config
1823  return set_config_result_contains(mgmd, conf,
1824  "Invalid configuration name");
1825 }
1826 
1827 static bool
1828 check_set_config_fail_wrong_primary(NdbMgmd& mgmd)
1829 {
1830  // Get the binary config
1831  Config conf;
1832  if (!mgmd.get_config(conf))
1833  return false;
1834 
1835  // Change primary and thus make this configuration invalid
1836  if (!conf.setPrimaryMgmNode(conf.getPrimaryMgmNode()+10))
1837  return false;
1838 
1839  // Set the modified config
1840  return set_config_result_contains(mgmd, conf,
1841  "Not primary mgm node");
1842 }
1843 
1844 int runTestSetConfig(NDBT_Context* ctx, NDBT_Step* step)
1845 {
1846  NdbMgmd mgmd;
1847 
1848  if (!mgmd.connect())
1849  return NDBT_FAILED;
1850 
1851  int result= NDBT_FAILED;
1852  if (
1853  check_set_config_invalid_content_type(mgmd) &&
1854  check_set_config_invalid_content_encoding(mgmd) &&
1855  check_set_config_too_large_content_length(mgmd) &&
1856  check_set_config_too_small_content_length(mgmd) &&
1857  check_set_config_wrong_config_length(mgmd) &&
1858  check_set_config_any_node(ctx, step, mgmd) &&
1859  check_set_config_fail_wrong_generation(mgmd) &&
1860  check_set_config_fail_wrong_name(mgmd) &&
1861  check_set_config_fail_wrong_primary(mgmd) &&
1862  true)
1863  result= NDBT_OK;
1864 
1865  if (!mgmd.end_session())
1866  result= NDBT_FAILED;
1867 
1868  return result;
1869 }
1870 
1871 int runTestSetConfigParallel(NDBT_Context* ctx, NDBT_Step* step)
1872 {
1873  NdbMgmd mgmd;
1874 
1875  if (!mgmd.connect())
1876  return NDBT_FAILED;
1877 
1878  int result = NDBT_OK;
1879  int loops = ctx->getNumLoops();
1880  int sucessful = 0;
1881 
1882  int invalid_generation = 0, config_change_ongoing = 0;
1883 
1884  /*
1885  continue looping until "loops" number of successful
1886  changes have been made from this thread
1887  */
1888  while (sucessful < loops &&
1889  !ctx->isTestStopped() &&
1890  result == NDBT_OK)
1891  {
1892  // Get the binary config
1893  Config conf;
1894  if (!mgmd.get_config(conf))
1895  return NDBT_FAILED;
1896 
1897  /* Set the config and check for valid errors */
1898  mgmd.verbose(false);
1899  if (mgmd.set_config(conf))
1900  {
1901  /* Config change suceeded */
1902  sucessful++;
1903  }
1904  else
1905  {
1906  /* Config change failed */
1907  if (mgmd.last_error() != NDB_MGM_CONFIG_CHANGE_FAILED)
1908  {
1909  g_err << "Config change failed with unexpected error: "
1910  << mgmd.last_error() << endl;
1911  result = NDBT_FAILED;
1912  continue;
1913  }
1914 
1915  BaseString error(mgmd.last_error_message());
1916  if (error == "Invalid generation in configuration")
1917  invalid_generation++;
1918  else
1919  if (error == "Config change ongoing")
1920  config_change_ongoing++;
1921  else
1922  {
1923  g_err << "Config change failed with unexpected error: '"
1924  << error << "'" << endl;
1925  result = NDBT_FAILED;
1926 
1927  }
1928  }
1929  }
1930 
1931  ndbout << "Thread " << step->getStepNo()
1932  << ", sucess: " << sucessful
1933  << ", ongoing: " << config_change_ongoing
1934  << ", invalid_generation: " << invalid_generation << endl;
1935  return result;
1936 }
1937 
1938 int runTestSetConfigParallelUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
1939 {
1940  int result= NDBT_OK;
1941  while(!ctx->isTestStopped() &&
1942  (result= runTestSetConfigParallel(ctx, step)) == NDBT_OK)
1943  ;
1944  return result;
1945 }
1946 
1947 
1948 
1949 static bool
1950 get_connection_parameter(NdbMgmd& mgmd,
1951  const Properties& args,
1952  Properties& reply)
1953 {
1954 
1955  // Fill in default values of other args
1956  Properties call_args(args);
1957  if (!call_args.contains("node1"))
1958  call_args.put("node1", 1);
1959  if (!call_args.contains("node2"))
1960  call_args.put("node2", 1);
1961  if (!call_args.contains("param"))
1962  call_args.put("param", CFG_CONNECTION_SERVER_PORT);
1963 
1964  if (!mgmd.call("get connection parameter", call_args,
1965  "get connection parameter reply", reply))
1966  {
1967  g_err << "get_connection_parameter: mgmd.call failed" << endl;
1968  return false;
1969  }
1970  return true;
1971 }
1972 
1973 
1974 static bool
1975 set_connection_parameter(NdbMgmd& mgmd,
1976  const Properties& args,
1977  Properties& reply)
1978 {
1979 
1980  // Fill in default values of other args
1981  Properties call_args(args);
1982  if (!call_args.contains("node1"))
1983  call_args.put("node1", 1);
1984  if (!call_args.contains("node2"))
1985  call_args.put("node2", 1);
1986  if (!call_args.contains("param"))
1987  call_args.put("param", CFG_CONNECTION_SERVER_PORT);
1988  if (!call_args.contains("value"))
1989  call_args.put("value", 37);
1990 
1991  if (!mgmd.call("set connection parameter", call_args,
1992  "set connection parameter reply", reply))
1993  {
1994  g_err << "set_connection_parameter: mgmd.call failed" << endl;
1995  return false;
1996  }
1997  return true;
1998 }
1999 
2000 
2001 static bool
2002 check_connection_parameter_invalid_nodeid(NdbMgmd& mgmd)
2003 {
2004  for (int nodeId = MAX_NODES; nodeId < MAX_NODES+2; nodeId++){
2005  g_info << "Testing invalid node " << nodeId << endl;;
2006 
2007  Properties args;
2008  args.put("node1", nodeId);
2009  args.put("node2", nodeId);
2010 
2011  Properties get_result;
2012  if (!get_connection_parameter(mgmd, args, get_result))
2013  return false;
2014 
2015  if (!result_contains(get_result,
2016  "Unable to find connection between nodes"))
2017  return false;
2018 
2019  Properties set_result;
2020  if (!set_connection_parameter(mgmd, args, set_result))
2021  return false;
2022 
2023  if (!failed(set_result))
2024  return false;
2025 
2026  if (!message_contains(set_result,
2027  "Unable to find connection between nodes"))
2028  return false;
2029  }
2030  return true;
2031 }
2032 
2033 
2034 static bool
2035 check_connection_parameter(NdbMgmd& mgmd)
2036 {
2037  // Find a NDB node with dynamic port
2038  Config conf;
2039  if (!mgmd.get_config(conf))
2040  return false;
2041 
2042  Uint32 nodeId1 = 0;
2043  for(Uint32 i= 1; i < MAX_NODES; i++){
2044  Uint32 nodeType;
2045  ConfigIter iter(&conf, CFG_SECTION_NODE);
2046  if (iter.find(CFG_NODE_ID, i) == 0 &&
2047  iter.get(CFG_TYPE_OF_SECTION, &nodeType) == 0 &&
2048  nodeType == NDB_MGM_NODE_TYPE_NDB){
2049  nodeId1 = i;
2050  break;
2051  }
2052  }
2053 
2054  NodeId otherNodeId = 0;
2055  BaseString original_value;
2056 
2057  // Get current value of first connection between mgmd and other node
2058  for (int nodeId = 1; nodeId < MAX_NODES; nodeId++){
2059 
2060  g_info << "Checking if connection between " << nodeId1
2061  << " and " << nodeId << " exists" << endl;
2062 
2063  Properties args;
2064  args.put("node1", nodeId1);
2065  args.put("node2", nodeId);
2066 
2067  Properties result;
2068  if (!get_connection_parameter(mgmd, args, result))
2069  return false;
2070 
2071  if (!ok(result))
2072  continue;
2073 
2074  result.print();
2075  // Get the nodeid
2076  otherNodeId = nodeId;
2077 
2078  // Get original value
2079  if (!result.get("value", original_value))
2080  {
2081  g_err << "Failed to get original value" << endl;
2082  return false;
2083  }
2084  break; // Done with the loop
2085  }
2086 
2087  if (otherNodeId == 0)
2088  {
2089  g_err << "Could not find a suitable connection for test" << endl;
2090  return false;
2091  }
2092 
2093  Properties get_args;
2094  get_args.put("node1", nodeId1);
2095  get_args.put("node2", otherNodeId);
2096 
2097  {
2098  g_info << "Set new value(37 by default)" << endl;
2099 
2100  Properties set_args(get_args);
2101  Properties set_result;
2102  if (!set_connection_parameter(mgmd, set_args, set_result))
2103  return false;
2104 
2105  if (!ok(set_result))
2106  return false;
2107  }
2108 
2109  {
2110  g_info << "Check new value" << endl;
2111 
2112  Properties get_result;
2113  if (!get_connection_parameter(mgmd, get_args, get_result))
2114  return false;
2115 
2116  if (!ok(get_result))
2117  return false;
2118 
2119  BaseString new_value;
2120  if (!get_result.get("value", new_value))
2121  {
2122  g_err << "Failed to get new value" << endl;
2123  return false;
2124  }
2125 
2126  g_info << "new_value: " << new_value << endl;
2127  if (new_value != "37")
2128  {
2129  g_err << "New value was not correct, expected 37, got "
2130  << new_value << endl;
2131  return false;
2132  }
2133  }
2134 
2135  {
2136  g_info << "Restore old value" << endl;
2137 
2138  Properties set_args(get_args);
2139  if (!set_args.put("value", original_value.c_str()))
2140  {
2141  g_err << "Failed to put original_value" << endl;
2142  return false;
2143  }
2144 
2145  Properties set_result;
2146  if (!set_connection_parameter(mgmd, set_args, set_result))
2147  return false;
2148 
2149  if (!ok(set_result))
2150  return false;
2151  }
2152 
2153  {
2154  g_info << "Check restored value" << endl;
2155  Properties get_result;
2156  if (!get_connection_parameter(mgmd, get_args, get_result))
2157  return false;
2158 
2159  if (!ok(get_result))
2160  return false;
2161 
2162  BaseString restored_value;
2163  if (!get_result.get("value", restored_value))
2164  {
2165  g_err << "Failed to get restored value" << endl;
2166  return false;
2167  }
2168 
2169  if (restored_value != original_value)
2170  {
2171  g_err << "Restored value was not correct, expected "
2172  << original_value << ", got "
2173  << restored_value << endl;
2174  return false;
2175  }
2176  g_info << "restored_value: " << restored_value << endl;
2177  }
2178 
2179  return true;
2180 
2181 }
2182 
2183 
2184 int runTestConnectionParameter(NDBT_Context* ctx, NDBT_Step* step)
2185 {
2186  NdbMgmd mgmd;
2187 
2188  if (!mgmd.connect())
2189  return NDBT_FAILED;
2190 
2191  int result= NDBT_FAILED;
2192  if (
2193  check_connection_parameter(mgmd) &&
2194  check_connection_parameter_invalid_nodeid(mgmd) &&
2195  true)
2196  result= NDBT_OK;
2197 
2198  if (!mgmd.end_session())
2199  result= NDBT_FAILED;
2200 
2201  return result;
2202 }
2203 
2204 
2205 int runTestConnectionParameterUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
2206 {
2207  int result= NDBT_OK;
2208  while(!ctx->isTestStopped() &&
2209  (result= runTestConnectionParameter(ctx, step)) == NDBT_OK)
2210  ;
2211  return result;
2212 }
2213 
2214 
2215 #ifdef NOT_YET
2216 static bool
2217 check_restart_connected(NdbMgmd& mgmd)
2218 {
2219  if (!mgmd.restart())
2220  return false;
2221  return true;
2222  }
2223 
2224 int runTestRestartMgmd(NDBT_Context* ctx, NDBT_Step* step)
2225 {
2226  NdbMgmd mgmd;
2227 
2228  if (!mgmd.connect())
2229  return NDBT_FAILED;
2230 
2231  int result= NDBT_FAILED;
2232  if (
2233  check_restart_connected(mgmd) &&
2234  true)
2235  result= NDBT_OK;
2236 
2237  if (!mgmd.end_session())
2238  result= NDBT_FAILED;
2239 
2240  return result;
2241 }
2242 #endif
2243 
2244 
2245 static bool
2246 set_logfilter(NdbMgmd& mgmd,
2247  enum ndb_mgm_event_severity severity,
2248  int enable)
2249 {
2250  struct ndb_mgm_reply reply;
2251  if (ndb_mgm_set_clusterlog_severity_filter(mgmd.handle(),
2252  severity,
2253  enable,
2254  &reply
2255  ) == -1)
2256  {
2257  g_err << "set_logfilter: ndb_mgm_set_clusterlog_severity_filter failed"
2258  << endl;
2259  return false;
2260  }
2261  return true;
2262 }
2263 
2264 static bool
2265 get_logfilter(NdbMgmd& mgmd,
2266  enum ndb_mgm_event_severity severity,
2267  unsigned int* value)
2268 {
2269 
2270  struct ndb_mgm_severity severity_struct;
2271  severity_struct.category = severity;
2272  if (ndb_mgm_get_clusterlog_severity_filter(mgmd.handle(),
2273  &severity_struct,
2274  1) != 1)
2275  {
2276  g_err << "get_logfilter: ndb_mgm_get_clusterlog_severity_filter failed"
2277  << endl;
2278  return false;
2279  }
2280 
2281  assert(value);
2282  *value = severity_struct.value;
2283 
2284  return true;
2285 }
2286 
2287 
2288 int runTestSetLogFilter(NDBT_Context* ctx, NDBT_Step* step)
2289 {
2290  NdbMgmd mgmd;
2291 
2292  if (!mgmd.connect())
2293  return NDBT_FAILED;
2294 
2295  for (int i = 0; i < (int)NDB_MGM_EVENT_SEVERITY_ALL; i++)
2296  {
2297  g_info << "severity: " << i << endl;
2299 
2300  // Get initial value of level
2301  unsigned int initial_value;
2302  if (!get_logfilter(mgmd, severity, &initial_value))
2303  return NDBT_FAILED;
2304 
2305  // Turn level off
2306  if (!set_logfilter(mgmd, severity, 0))
2307  return NDBT_FAILED;
2308 
2309  // Check it's off
2310  unsigned int curr_value;
2311  if (!get_logfilter(mgmd, severity, &curr_value))
2312  return NDBT_FAILED;
2313 
2314  if (curr_value != 0)
2315  {
2316  g_err << "Failed to turn off severity: " << severity << endl;
2317  return NDBT_FAILED;
2318  }
2319 
2320  // Turn level on
2321  if (!set_logfilter(mgmd, severity, 1))
2322  return NDBT_FAILED;
2323 
2324  // Check it's on
2325  if (!get_logfilter(mgmd, severity, &curr_value))
2326  return NDBT_FAILED;
2327 
2328  if (curr_value == 0)
2329  {
2330  g_err << "Filed to turn on severity: " << severity << endl;
2331  return NDBT_FAILED;
2332  }
2333 
2334  // Toggle, ie. turn off
2335  if (!set_logfilter(mgmd, severity, -1))
2336  return NDBT_FAILED;
2337 
2338  // Check it's off
2339  if (!get_logfilter(mgmd, severity, &curr_value))
2340  return NDBT_FAILED;
2341 
2342  if (curr_value != 0)
2343  {
2344  g_err << "Failed to toggle severity : " << severity << endl;
2345  return NDBT_FAILED;
2346  }
2347 
2348  // Set back initial value
2349  if (!set_logfilter(mgmd, severity, initial_value))
2350  return NDBT_FAILED;
2351 
2352  }
2353 
2354  return NDBT_OK;
2355 }
2356 
2357 
2358 int runTestBug40922(NDBT_Context* ctx, NDBT_Step* step)
2359 {
2360  NdbMgmd mgmd;
2361 
2362  if (!mgmd.connect())
2363  return NDBT_FAILED;
2364 
2365  int filter[] = {
2368  0
2369  };
2370  NdbLogEventHandle le_handle =
2371  ndb_mgm_create_logevent_handle(mgmd.handle(), filter);
2372  if (!le_handle)
2373  return NDBT_FAILED;
2374 
2375  g_info << "Calling ndb_log_event_get_next" << endl;
2376 
2377  struct ndb_logevent le_event;
2378  int r = ndb_logevent_get_next(le_handle,
2379  &le_event,
2380  2000);
2381  g_info << "ndb_log_event_get_next returned " << r << endl;
2382 
2383  int result = NDBT_FAILED;
2384  if (r == 0)
2385  {
2386  // Got timeout
2387  g_info << "ndb_logevent_get_next returned timeout" << endl;
2388  result = NDBT_OK;
2389  }
2390  else
2391  {
2392  if(r>0)
2393  g_err << "ERROR: Receieved unexpected event: "
2394  << le_event.type << endl;
2395  if(r<0)
2396  g_err << "ERROR: ndb_logevent_get_next returned error: "
2397  << r << endl;
2398  }
2399 
2400  ndb_mgm_destroy_logevent_handle(&le_handle);
2401 
2402  return result;
2403 }
2404 
2405 
2406 int runTestBug45497(NDBT_Context* ctx, NDBT_Step* step)
2407 {
2408  int result = NDBT_OK;
2409  int loops = ctx->getNumLoops();
2410  Vector<NdbMgmd*> mgmds;
2411 
2412  while(true)
2413  {
2414  NdbMgmd* mgmd = new NdbMgmd();
2415 
2416  // Set quite short timeout
2417  if (!mgmd->set_timeout(1000))
2418  {
2419  result = NDBT_FAILED;
2420  break;
2421  }
2422 
2423  if (mgmd->connect())
2424  {
2425  mgmds.push_back(mgmd);
2426  g_info << "connections: " << mgmds.size() << endl;
2427  continue;
2428  }
2429 
2430  g_err << "Failed to make another connection, connections: "
2431  << mgmds.size() << endl;
2432 
2433 
2434  // Disconnect some connections
2435  int to_disconnect = 10;
2436  while(mgmds.size() && to_disconnect--)
2437  {
2438  g_info << "disconnnect, connections: " << mgmds.size() << endl;
2439  NdbMgmd* mgmd = mgmds[0];
2440  mgmds.erase(0);
2441  delete mgmd;
2442  }
2443 
2444  if (loops-- == 0)
2445  break;
2446  }
2447 
2448  while(mgmds.size())
2449  {
2450  NdbMgmd* mgmd = mgmds[0];
2451  mgmds.erase(0);
2452  delete mgmd;
2453  }
2454 
2455  return result;
2456 }
2457 
2458 
2459 static int
2460 runTestGetVersion(NDBT_Context* ctx, NDBT_Step* step)
2461 {
2462 
2463  NdbMgmd mgmd;
2464 
2465  if (!mgmd.connect())
2466  return NDBT_FAILED;
2467 
2468  char verStr[64];
2469  int major, minor, build;
2470  if (ndb_mgm_get_version(mgmd.handle(),
2471  &major, &minor, &build,
2472  sizeof(verStr), verStr) != 1)
2473  {
2474  g_err << "ndb_mgm_get_version failed,"
2475  << "error: " << ndb_mgm_get_latest_error_msg(mgmd.handle())
2476  << "desc: " << ndb_mgm_get_latest_error_desc(mgmd.handle()) << endl;
2477  return NDBT_FAILED;
2478  }
2479 
2480  g_info << "Using major: " << major
2481  << " minor: " << minor
2482  << " build: " << build
2483  << " string: " << verStr << endl;
2484 
2485  int l = 0;
2486  int loops = ctx->getNumLoops();
2487  while(l < loops)
2488  {
2489  char verStr2[64];
2490  int major2, minor2, build2;
2491  if (ndb_mgm_get_version(mgmd.handle(),
2492  &major2, &minor2, &build2,
2493  sizeof(verStr2), verStr2) != 1)
2494  {
2495  g_err << "ndb_mgm_get_version failed,"
2496  << "error: " << ndb_mgm_get_latest_error_msg(mgmd.handle())
2497  << "desc: " << ndb_mgm_get_latest_error_desc(mgmd.handle()) << endl;
2498  return NDBT_FAILED;
2499  }
2500 
2501  if (major != major2)
2502  {
2503  g_err << "Got different major: " << major2
2504  << " excpected: " << major << endl;
2505  return NDBT_FAILED;
2506  }
2507 
2508  if (minor != minor2)
2509  {
2510  g_err << "Got different minor: " << minor2
2511  << " excpected: " << minor << endl;
2512  return NDBT_FAILED;
2513  }
2514 
2515  if (build != build2)
2516  {
2517  g_err << "Got different build: " << build2
2518  << " excpected: " << build << endl;
2519  return NDBT_FAILED;
2520  }
2521 
2522  if (strcmp(verStr, verStr2) != 0)
2523  {
2524  g_err << "Got different verStr: " << verStr2
2525  << " excpected: " << verStr << endl;
2526  return NDBT_FAILED;
2527  }
2528 
2529  l++;
2530  }
2531 
2532  return NDBT_OK;
2533 }
2534 
2535 
2536 static int
2537 runTestGetVersionUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
2538 {
2539  int result= NDBT_OK;
2540  while(!ctx->isTestStopped() &&
2541  (result= runTestGetVersion(ctx, step)) == NDBT_OK)
2542  ;
2543  return result;
2544 }
2545 
2546 
2547 int runTestDumpEvents(NDBT_Context* ctx, NDBT_Step* step)
2548 {
2549  NdbMgmd mgmd;
2550 
2551  if (!mgmd.connect())
2552  return NDBT_FAILED;
2553 
2554  // Test with unsupported logevent_type
2555  {
2556  const Ndb_logevent_type unsupported = NDB_LE_NDBStopForced;
2557  g_info << "ndb_mgm_dump_events(" << unsupported << ")" << endl;
2558 
2559  const struct ndb_mgm_events* events =
2560  ndb_mgm_dump_events(mgmd.handle(), unsupported, 0, 0);
2561  if (events != NULL)
2562  {
2563  g_err << "ndb_mgm_dump_events returned events "
2564  << "for unsupported Ndb_logevent_type" << endl;
2565  return NDBT_FAILED;
2566  }
2567 
2568  if (ndb_mgm_get_latest_error(mgmd.handle()) != NDB_MGM_USAGE_ERROR ||
2569  strcmp("ndb_logevent_type 59 not supported",
2570  ndb_mgm_get_latest_error_desc(mgmd.handle())))
2571  {
2572  g_err << "Unexpected error for unsupported logevent type, "
2573  << ndb_mgm_get_latest_error(mgmd.handle())
2574  << ", desc: " << ndb_mgm_get_latest_error_desc(mgmd.handle())
2575  << endl;
2576  return NDBT_FAILED;
2577  }
2578  }
2579 
2580  // Test with nodes >= MAX_NDB_NODES
2581  for (int i = MAX_NDB_NODES; i < MAX_NDB_NODES + 3; i++)
2582  {
2583  g_info << "ndb_mgm_dump_events(NDB_LE_MemoryUsage, 1, "
2584  << i << ")" << endl;
2585 
2586  const struct ndb_mgm_events* events =
2587  ndb_mgm_dump_events(mgmd.handle(), NDB_LE_MemoryUsage, 1, &i);
2588  if (events != NULL)
2589  {
2590  g_err << "ndb_mgm_dump_events returned events "
2591  << "for too large nodeid" << endl;
2592  return NDBT_FAILED;
2593  }
2594 
2595  int invalid_nodeid;
2596  if (ndb_mgm_get_latest_error(mgmd.handle()) != NDB_MGM_USAGE_ERROR ||
2597  sscanf(ndb_mgm_get_latest_error_desc(mgmd.handle()),
2598  "invalid nodes: '%d'", &invalid_nodeid) != 1 ||
2599  invalid_nodeid != i)
2600  {
2601  g_err << "Unexpected error for too large nodeid, "
2602  << ndb_mgm_get_latest_error(mgmd.handle())
2603  << ", desc: " << ndb_mgm_get_latest_error_desc(mgmd.handle())
2604  << endl;
2605  return NDBT_FAILED;
2606  }
2607 
2608  }
2609 
2610  int l = 0;
2611  int loops = ctx->getNumLoops();
2612  while (l<loops)
2613  {
2614  const Ndb_logevent_type supported[] =
2615  {
2619  };
2620 
2621  // Test with supported logevent_type
2622  for (int i = 0; supported[i]; i++)
2623  {
2624  g_info << "ndb_mgm_dump_events(" << supported[i] << ")" << endl;
2625 
2626  struct ndb_mgm_events* events =
2627  ndb_mgm_dump_events(mgmd.handle(), supported[i], 0, 0);
2628  if (events == NULL)
2629  {
2630  g_err << "ndb_mgm_dump_events failed, type: " << supported[i]
2631  << ", error: " << ndb_mgm_get_latest_error(mgmd.handle())
2632  << ", msg: " << ndb_mgm_get_latest_error_msg(mgmd.handle())
2633  << endl;
2634  return NDBT_FAILED;
2635  }
2636 
2637  if (events->no_of_events < 0)
2638  {
2639  g_err << "ndb_mgm_dump_events returned a negative number of events: "
2640  << events->no_of_events << endl;
2641  free(events);
2642  return NDBT_FAILED;
2643  }
2644 
2645  g_info << "Got " << events->no_of_events << " events" << endl;
2646  free(events);
2647  }
2648 
2649  l++;
2650  }
2651 
2652  return NDBT_OK;
2653 }
2654 
2655 int runTestStatusAfterStop(NDBT_Context* ctx, NDBT_Step* step)
2656 {
2657  NdbMgmd mgmd;
2658  mgmd.set_timeout(50); // Short timeout, should be upgraded
2659 
2660  if (!mgmd.connect())
2661  return NDBT_FAILED;
2662 
2664  node_types[2] = { NDB_MGM_NODE_TYPE_NDB,
2665  NDB_MGM_NODE_TYPE_UNKNOWN };
2666 
2667  // Test: get status, stop node, get status again
2668  printf("Getting status\n");
2669  ndb_mgm_cluster_state *cs = ndb_mgm_get_status2(mgmd.handle(), node_types);
2670  if (cs == NULL)
2671  {
2672  printf("%s (%d)\n", ndb_mgm_get_latest_error_msg(mgmd.handle()),
2673  ndb_mgm_get_latest_error(mgmd.handle()));
2674  return NDBT_FAILED;
2675  }
2676 
2677  int nodeId = 0;
2678  for(int i=0; i < cs->no_of_nodes; i++ )
2679  {
2680  ndb_mgm_node_state *ns = cs->node_states + i;
2681  printf("Node ID: %d status:%d\n", ns->node_id, ns->node_status);
2682  if (nodeId == 0 && ns->node_type == NDB_MGM_NODE_TYPE_NDB)
2683  nodeId = ns->node_id;
2684  }
2685  free(cs);
2686  cs = NULL;
2687 
2688  printf("Stopping data node\n");
2689  // We only stop 1 data node, in this case NodeId=2
2690  int nodes[1] = { nodeId };
2691  int stopped = ndb_mgm_restart2(mgmd.handle(), NDB_ARRAY_SIZE(nodes), nodes,
2692  0, 0, 1);
2693  if (stopped < 0)
2694  {
2695  printf("ndb_mgm_stop failed, '%s' (%d)\n",
2696  ndb_mgm_get_latest_error_msg(mgmd.handle()),
2697  ndb_mgm_get_latest_error(mgmd.handle()));
2698  return NDBT_FAILED;
2699  }
2700 
2701  printf("Stopped %d data node(s)\n", stopped);
2702 
2703  printf("Getting status\n");
2704  cs = ndb_mgm_get_status2(mgmd.handle(), node_types);
2705  if (cs == NULL)
2706  {
2707  printf("%s (%d)\n", ndb_mgm_get_latest_error_msg(mgmd.handle()),
2708  ndb_mgm_get_latest_error(mgmd.handle()));
2709  return NDBT_FAILED;
2710  }
2711  for(int i=0; i < cs->no_of_nodes; i++ )
2712  {
2713  ndb_mgm_node_state *ns = cs->node_states + i;
2714  printf("Node ID: %d status:%d\n", ns->node_id, ns->node_status);
2715  }
2716  free(cs);
2717 
2718  NdbRestarter res;
2719  res.startAll();
2720  res.waitClusterStarted();
2721 
2722  return NDBT_OK;
2723 }
2724 
2725 NDBT_TESTSUITE(testMgm);
2726 DRIVER(DummyDriver); /* turn off use of NdbApi */
2727 TESTCASE("ApiSessionFailure",
2728  "Test failures in MGMAPI session"){
2729  INITIALIZER(runTestApiSession);
2730 
2731 }
2732 TESTCASE("ApiConnectTimeout",
2733  "Connect timeout tests for MGMAPI"){
2734  INITIALIZER(runTestApiConnectTimeout);
2735 
2736 }
2737 TESTCASE("ApiTimeoutBasic",
2738  "Basic timeout tests for MGMAPI"){
2739  INITIALIZER(runTestApiTimeoutBasic);
2740 
2741 }
2742 TESTCASE("ApiGetStatusTimeout",
2743  "Test timeout for MGMAPI getStatus"){
2744  INITIALIZER(runTestApiGetStatusTimeout);
2745 
2746 }
2747 TESTCASE("ApiGetConfigTimeout",
2748  "Test timeouts for mgmapi get_configuration"){
2749  INITIALIZER(runTestMgmApiGetConfigTimeout);
2750 
2751 }
2752 TESTCASE("ApiMgmEventTimeout",
2753  "Test timeouts for mgmapi get_configuration"){
2754  INITIALIZER(runTestMgmApiEventTimeout);
2755 
2756 }
2757 TESTCASE("ApiMgmStructEventTimeout",
2758  "Test timeouts for mgmapi get_configuration"){
2759  INITIALIZER(runTestMgmApiStructEventTimeout);
2760 
2761 }
2762 TESTCASE("SetConfig",
2763  "Tests the ndb_mgm_set_configuration function"){
2764  INITIALIZER(runSetConfig);
2765 }
2766 TESTCASE("CheckConfig",
2767  "Connect to each ndb_mgmd and check they have the same configuration"){
2768  INITIALIZER(runCheckConfig);
2769 }
2770 TESTCASE("TestReloadConfig",
2771  "Test of 'reload config'"){
2772  INITIALIZER(runTestReloadConfig);
2773 }
2774 TESTCASE("TestSetConfig",
2775  "Test of 'set config'"){
2776  INITIALIZER(runTestSetConfig);
2777 }
2778 TESTCASE("TestSetConfigParallel",
2779  "Test of 'set config' from 5 threads"){
2780  STEPS(runTestSetConfigParallel, 5);
2781 }
2782 TESTCASE("GetConfig", "Run ndb_mgm_get_configuration in parallel"){
2783  STEPS(runGetConfig, 100);
2784 }
2785 TESTCASE("TestStatus",
2786  "Test status and status2"){
2787  INITIALIZER(runTestStatus);
2788 
2789 }
2790 TESTCASE("TestStatus200",
2791  "Test status and status2 with 200 threads"){
2792  STEPS(runTestStatus, 200);
2793 
2794 }
2795 TESTCASE("TestGetNodeId",
2796  "Test 'get nodeid'"){
2797  INITIALIZER(runTestGetNodeId);
2798 }
2799 TESTCASE("TestGetVersion",
2800  "Test 'get version' and 'ndb_mgm_get_version'"){
2801  STEPS(runTestGetVersion, 20);
2802 }
2803 TESTCASE("TestTransporterConnect",
2804  "Test 'transporter connect'"){
2805  INITIALIZER(runTestTransporterConnect);
2806 }
2807 TESTCASE("TestConnectionParameter",
2808  "Test 'get/set connection parameter'"){
2809  INITIALIZER(runTestConnectionParameter);
2810 }
2811 TESTCASE("TestSetLogFilter",
2812  "Test 'set logfilter' and 'get info clusterlog'"){
2813  INITIALIZER(runTestSetLogFilter);
2814 }
2815 #ifdef NOT_YET
2816 TESTCASE("TestRestartMgmd",
2817  "Test restart of ndb_mgmd(s)"){
2818  INITIALIZER(runTestRestartMgmd);
2819 }
2820 #endif
2821 TESTCASE("Bug40922",
2822  "Make sure that ndb_logevent_get_next returns when "
2823  "called with a timeout"){
2824  INITIALIZER(runTestBug40922);
2825 }
2826 TESTCASE("Stress",
2827  "Run everything while changing config"){
2828  STEP(runTestGetNodeIdUntilStopped);
2829  STEP(runSetConfigUntilStopped);
2830  STEPS(runGetConfigUntilStopped, 10);
2831  STEPS(runGetConfigFromNodeUntilStopped, 10);
2832  STEPS(runTestStatusUntilStopped, 10);
2833  STEPS(runTestGetVersionUntilStopped, 5);
2834  STEP(runSleepAndStop);
2835 }
2836 TESTCASE("Stress2",
2837  "Run everything while changing config in parallel"){
2838  STEP(runTestGetNodeIdUntilStopped);
2839  STEPS(runTestSetConfigParallelUntilStopped, 5);
2840  STEPS(runGetConfigUntilStopped, 10);
2841  STEPS(runGetConfigFromNodeUntilStopped, 10);
2842  STEPS(runTestStatusUntilStopped, 10);
2843  STEPS(runTestGetVersionUntilStopped, 5);
2844  STEP(runSleepAndStop);
2845 }
2846 TESTCASE("Bug45497",
2847  "Connect to ndb_mgmd until it can't handle more connections"){
2848  STEP(runTestBug45497);
2849 }
2850 TESTCASE("TestGetVersion",
2851  "Test 'get version' and 'ndb_mgm_get_version'"){
2852  STEPS(runTestGetVersion, 20);
2853 }
2854 TESTCASE("TestDumpEvents",
2855  "Test 'dump events'"){
2856  STEPS(runTestDumpEvents, 1);
2857 }
2858 TESTCASE("TestStatusAfterStop",
2859  "Test get status after stop "){
2860  STEPS(runTestStatusAfterStop, 1);
2861 }
2862 NDBT_TESTSUITE_END(testMgm);
2863 
2864 int main(int argc, const char** argv){
2865  ndb_init();
2866  NDBT_TESTSUITE_INSTANCE(testMgm);
2867  testMgm.setCreateTable(false);
2868  testMgm.setRunAllTables(true);
2869  return testMgm.execute(argc, argv);
2870 }
2871 
2872 template class Vector<NdbMgmd*>;