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