1 /*
2    Copyright (c) 2003, 2021, Oracle and/or its affiliates.
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 "../../src/mgmapi/mgmapi_internal.h"
31 #include <InputStream.hpp>
32 #include <signaldata/EventReport.hpp>
33 #include <NdbRestarter.hpp>
34 #include <random.h>
35 
36 /*
37   Tests that only need the mgmd(s) started
38 
39   Start ndb_mgmd and set NDB_CONNECTSTRING pointing
40   to that/those ndb_mgmd(s), then run testMgm
41  */
42 
43 
runTestApiSession(NDBT_Context * ctx,NDBT_Step * step)44 int runTestApiSession(NDBT_Context* ctx, NDBT_Step* step)
45 {
46   NdbMgmd mgmd;
47   Uint64 session_id= 0;
48 
49   NdbMgmHandle h;
50   h= ndb_mgm_create_handle();
51   ndb_mgm_set_connectstring(h, mgmd.getConnectString());
52   ndb_mgm_connect(h,0,0,0);
53 #ifdef NDB_WIN
54   SOCKET s = ndb_mgm_get_fd(h);
55 #else
56   int s= ndb_mgm_get_fd(h);
57 #endif
58   session_id= ndb_mgm_get_session_id(h);
59   ndbout << "MGM Session id: " << session_id << endl;
60   send(s,"get",3,0);
61   ndb_mgm_disconnect(h);
62   ndb_mgm_destroy_handle(&h);
63 
64   struct NdbMgmSession sess;
65   int slen= sizeof(struct NdbMgmSession);
66 
67   h= ndb_mgm_create_handle();
68   ndb_mgm_set_connectstring(h, mgmd.getConnectString());
69   ndb_mgm_connect(h,0,0,0);
70 
71   NdbSleep_SecSleep(1);
72 
73   if(ndb_mgm_get_session(h,session_id,&sess,&slen))
74   {
75     ndbout << "Failed, session still exists" << endl;
76     ndb_mgm_disconnect(h);
77     ndb_mgm_destroy_handle(&h);
78     return NDBT_FAILED;
79   }
80   else
81   {
82     ndbout << "SUCCESS: session is gone" << endl;
83     ndb_mgm_disconnect(h);
84     ndb_mgm_destroy_handle(&h);
85     return NDBT_OK;
86   }
87 }
88 
runTestApiConnectTimeout(NDBT_Context * ctx,NDBT_Step * step)89 int runTestApiConnectTimeout(NDBT_Context* ctx, NDBT_Step* step)
90 {
91   NdbMgmd mgmd;
92 
93   g_info << "Check connect works with timeout 3000" << endl;
94   if (!mgmd.set_timeout(3000))
95     return NDBT_FAILED;
96 
97   if (!mgmd.connect(0, 0, 0))
98   {
99     g_err << "Connect failed with timeout 3000" << endl;
100     return NDBT_FAILED;
101   }
102 
103   if (!mgmd.disconnect())
104     return NDBT_FAILED;
105 
106   g_info << "Check connect to illegal host will timeout after 3000" << endl;
107   if (!mgmd.set_timeout(3000))
108     return NDBT_FAILED;
109   mgmd.setConnectString("1.1.1.1");
110 
111   const Uint64 tstart= NdbTick_CurrentMillisecond();
112   if (mgmd.connect(0, 0, 0))
113   {
114     g_err << "Connect to illegal host suceeded" << endl;
115     return NDBT_FAILED;
116   }
117 
118   const Uint64 msecs= NdbTick_CurrentMillisecond() - tstart;
119   ndbout << "Took about " << msecs <<" milliseconds"<<endl;
120 
121   if(msecs > 6000)
122   {
123     g_err << "The connect to illegal host timedout after much longer "
124           << "time than was expected, expected <= 6000, got " << msecs << endl;
125     return NDBT_FAILED;
126   }
127   return NDBT_OK;
128 }
129 
130 
runTestApiTimeoutBasic(NDBT_Context * ctx,NDBT_Step * step)131 int runTestApiTimeoutBasic(NDBT_Context* ctx, NDBT_Step* step)
132 {
133   NdbMgmd mgmd;
134   int result= NDBT_FAILED;
135   int cc= 0;
136   int mgmd_nodeid= 0;
137   ndb_mgm_reply reply;
138 
139   NdbMgmHandle h;
140   h= ndb_mgm_create_handle();
141   ndb_mgm_set_connectstring(h, mgmd.getConnectString());
142 
143   ndbout << "TEST timout check_connection" << endl;
144   int errs[] = { 1, 2, 3, -1};
145 
146   for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
147   {
148     int error_ins= errs[error_ins_no];
149     ndbout << "trying error " << error_ins << endl;
150     ndb_mgm_connect(h,0,0,0);
151 
152     if(ndb_mgm_check_connection(h) < 0)
153     {
154       result= NDBT_FAILED;
155       goto done;
156     }
157 
158     mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
159     if(mgmd_nodeid==0)
160     {
161       ndbout << "Failed to get mgmd node id to insert error" << endl;
162       result= NDBT_FAILED;
163       goto done;
164     }
165 
166     reply.return_code= 0;
167 
168     if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
169     {
170       ndbout << "failed to insert error " << endl;
171       result= NDBT_FAILED;
172       goto done;
173     }
174 
175     ndb_mgm_set_timeout(h,2500);
176 
177     cc= ndb_mgm_check_connection(h);
178     if(cc < 0)
179       result= NDBT_OK;
180     else
181       result= NDBT_FAILED;
182 
183     if(ndb_mgm_is_connected(h))
184     {
185       ndbout << "FAILED: still connected" << endl;
186       result= NDBT_FAILED;
187     }
188   }
189 
190   ndbout << "TEST get_mgmd_nodeid" << endl;
191   ndb_mgm_connect(h,0,0,0);
192 
193   if(ndb_mgm_insert_error(h, mgmd_nodeid, 0, &reply)< 0)
194   {
195     ndbout << "failed to remove inserted error " << endl;
196     result= NDBT_FAILED;
197     goto done;
198   }
199 
200   cc= ndb_mgm_get_mgmd_nodeid(h);
201   ndbout << "got node id: " << cc << endl;
202   if(cc==0)
203   {
204     ndbout << "FAILED: didn't get node id" << endl;
205     result= NDBT_FAILED;
206   }
207   else
208     result= NDBT_OK;
209 
210   ndbout << "TEST end_session" << endl;
211   ndb_mgm_connect(h,0,0,0);
212 
213   if(ndb_mgm_insert_error(h, mgmd_nodeid, 4, &reply)< 0)
214   {
215     ndbout << "FAILED: insert error 1" << endl;
216     result= NDBT_FAILED;
217     goto done;
218   }
219 
220   cc= ndb_mgm_end_session(h);
221   if(cc==0)
222   {
223     ndbout << "FAILED: success in calling end_session" << endl;
224     result= NDBT_FAILED;
225   }
226   else if(ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
227   {
228     ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
229            << " != expected " << ETIMEDOUT << ") desc: "
230            << ndb_mgm_get_latest_error_desc(h)
231            << " line: " << ndb_mgm_get_latest_error_line(h)
232            << " msg: " << ndb_mgm_get_latest_error_msg(h)
233            << endl;
234     result= NDBT_FAILED;
235   }
236   else
237     result= NDBT_OK;
238 
239   if(ndb_mgm_is_connected(h))
240   {
241     ndbout << "FAILED: is still connected after error" << endl;
242     result= NDBT_FAILED;
243   }
244 done:
245   ndb_mgm_disconnect(h);
246   ndb_mgm_destroy_handle(&h);
247 
248   return result;
249 }
250 
runTestApiGetStatusTimeout(NDBT_Context * ctx,NDBT_Step * step)251 int runTestApiGetStatusTimeout(NDBT_Context* ctx, NDBT_Step* step)
252 {
253   NdbMgmd mgmd;
254   int result= NDBT_OK;
255   int mgmd_nodeid= 0;
256 
257   NdbMgmHandle h;
258   h= ndb_mgm_create_handle();
259   ndb_mgm_set_connectstring(h, mgmd.getConnectString());
260 
261   int errs[] = { 0, 5, 6, 7, 8, 9, -1 };
262 
263   for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
264   {
265     int error_ins= errs[error_ins_no];
266     ndb_mgm_connect(h,0,0,0);
267 
268     if(ndb_mgm_check_connection(h) < 0)
269     {
270       result= NDBT_FAILED;
271       goto done;
272     }
273 
274     mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
275     if(mgmd_nodeid==0)
276     {
277       ndbout << "Failed to get mgmd node id to insert error" << endl;
278       result= NDBT_FAILED;
279       goto done;
280     }
281 
282     ndb_mgm_reply reply;
283     reply.return_code= 0;
284 
285     if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
286     {
287       ndbout << "failed to insert error " << error_ins << endl;
288       result= NDBT_FAILED;
289     }
290 
291     ndbout << "trying error: " << error_ins << endl;
292 
293     ndb_mgm_set_timeout(h,2500);
294 
295     struct ndb_mgm_cluster_state *cl= ndb_mgm_get_status(h);
296 
297     if(cl!=NULL)
298       free(cl);
299 
300     /*
301      * For whatever strange reason,
302      * get_status is okay with not having the last enter there.
303      * instead of "fixing" the api, let's have a special case
304      * so we don't break any behaviour
305      */
306 
307     if(error_ins!=0 && error_ins!=9 && cl!=NULL)
308     {
309       ndbout << "FAILED: got a ndb_mgm_cluster_state back" << endl;
310       result= NDBT_FAILED;
311     }
312 
313     if(error_ins!=0 && error_ins!=9 && ndb_mgm_is_connected(h))
314     {
315       ndbout << "FAILED: is still connected after error" << endl;
316       result= NDBT_FAILED;
317     }
318 
319     if(error_ins!=0 && error_ins!=9 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
320     {
321       ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
322              << " != expected " << ETIMEDOUT << ") desc: "
323              << ndb_mgm_get_latest_error_desc(h)
324              << " line: " << ndb_mgm_get_latest_error_line(h)
325              << " msg: " << ndb_mgm_get_latest_error_msg(h)
326              << endl;
327       result= NDBT_FAILED;
328     }
329   }
330 
331 done:
332   ndb_mgm_disconnect(h);
333   ndb_mgm_destroy_handle(&h);
334 
335   return result;
336 }
337 
runTestMgmApiGetConfigTimeout(NDBT_Context * ctx,NDBT_Step * step)338 int runTestMgmApiGetConfigTimeout(NDBT_Context* ctx, NDBT_Step* step)
339 {
340   NdbMgmd mgmd;
341   int result= NDBT_OK;
342   int mgmd_nodeid= 0;
343 
344   NdbMgmHandle h;
345   h= ndb_mgm_create_handle();
346   ndb_mgm_set_connectstring(h, mgmd.getConnectString());
347 
348   int errs[] = { 0, 1, 2, 3, -1 };
349 
350   for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
351   {
352     int error_ins= errs[error_ins_no];
353     ndb_mgm_connect(h,0,0,0);
354 
355     if(ndb_mgm_check_connection(h) < 0)
356     {
357       result= NDBT_FAILED;
358       goto done;
359     }
360 
361     mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
362     if(mgmd_nodeid==0)
363     {
364       ndbout << "Failed to get mgmd node id to insert error" << endl;
365       result= NDBT_FAILED;
366       goto done;
367     }
368 
369     ndb_mgm_reply reply;
370     reply.return_code= 0;
371 
372     if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
373     {
374       ndbout << "failed to insert error " << error_ins << endl;
375       result= NDBT_FAILED;
376     }
377 
378     ndbout << "trying error: " << error_ins << endl;
379 
380     ndb_mgm_set_timeout(h,2500);
381 
382     struct ndb_mgm_configuration *c= ndb_mgm_get_configuration(h,0);
383 
384     if(c!=NULL)
385       free(c);
386 
387     if(error_ins!=0 && c!=NULL)
388     {
389       ndbout << "FAILED: got a ndb_mgm_configuration back" << endl;
390       result= NDBT_FAILED;
391     }
392 
393     if(error_ins!=0 && ndb_mgm_is_connected(h))
394     {
395       ndbout << "FAILED: is still connected after error" << endl;
396       result= NDBT_FAILED;
397     }
398 
399     if(error_ins!=0 && ndb_mgm_get_latest_error(h)!=ETIMEDOUT)
400     {
401       ndbout << "FAILED: Incorrect error code (" << ndb_mgm_get_latest_error(h)
402              << " != expected " << ETIMEDOUT << ") desc: "
403              << ndb_mgm_get_latest_error_desc(h)
404              << " line: " << ndb_mgm_get_latest_error_line(h)
405              << " msg: " << ndb_mgm_get_latest_error_msg(h)
406              << endl;
407       result= NDBT_FAILED;
408     }
409   }
410 
411 done:
412   ndb_mgm_disconnect(h);
413   ndb_mgm_destroy_handle(&h);
414 
415   return result;
416 }
417 
runTestMgmApiEventTimeout(NDBT_Context * ctx,NDBT_Step * step)418 int runTestMgmApiEventTimeout(NDBT_Context* ctx, NDBT_Step* step)
419 {
420   NdbMgmd mgmd;
421   int result= NDBT_OK;
422   int mgmd_nodeid= 0;
423 
424   NdbMgmHandle h;
425   h= ndb_mgm_create_handle();
426   ndb_mgm_set_connectstring(h, mgmd.getConnectString());
427 
428   int errs[] = { 10000, 0, -1 };
429 
430   for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
431   {
432     int error_ins= errs[error_ins_no];
433     ndb_mgm_connect(h,0,0,0);
434 
435     if(ndb_mgm_check_connection(h) < 0)
436     {
437       result= NDBT_FAILED;
438       goto done;
439     }
440 
441     mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
442     if(mgmd_nodeid==0)
443     {
444       ndbout << "Failed to get mgmd node id to insert error" << endl;
445       result= NDBT_FAILED;
446       goto done;
447     }
448 
449     ndb_mgm_reply reply;
450     reply.return_code= 0;
451 
452     if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
453     {
454       ndbout << "failed to insert error " << error_ins << endl;
455       result= NDBT_FAILED;
456     }
457 
458     ndbout << "trying error: " << error_ins << endl;
459 
460     ndb_mgm_set_timeout(h,2500);
461 
462     int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
463                      1, NDB_MGM_EVENT_CATEGORY_STARTUP,
464                      0 };
465 
466     NDB_SOCKET_TYPE my_fd;
467 #ifdef NDB_WIN
468     SOCKET fd= ndb_mgm_listen_event(h, filter);
469     my_fd.s= fd;
470 #else
471     int fd= ndb_mgm_listen_event(h, filter);
472     my_fd.fd= fd;
473 #endif
474 
475     if(!my_socket_valid(my_fd))
476     {
477       ndbout << "FAILED: could not listen to event" << endl;
478       result= NDBT_FAILED;
479     }
480 
481     union {
482       Uint32 theData[25];
483       EventReport repData;
484     };
485     EventReport *fake_event = &repData;
486     fake_event->setEventType(NDB_LE_NDBStopForced);
487     fake_event->setNodeId(42);
488     theData[2]= 0;
489     theData[3]= 0;
490     theData[4]= 0;
491     theData[5]= 0;
492 
493     ndb_mgm_report_event(h, theData, 6);
494 
495     char *tmp= 0;
496     char buf[512];
497 
498     SocketInputStream in(my_fd,2000);
499     for(int i=0; i<20; i++)
500     {
501       if((tmp = in.gets(buf, sizeof(buf))))
502       {
503 //        const char ping_token[]="<PING>";
504 //        if(memcmp(ping_token,tmp,sizeof(ping_token)-1))
505           if(tmp && strlen(tmp))
506             ndbout << tmp;
507       }
508       else
509       {
510         if(in.timedout())
511         {
512           ndbout << "TIMED OUT READING EVENT at iteration " << i << endl;
513           break;
514         }
515       }
516     }
517 
518     /*
519      * events go through a *DIFFERENT* socket than the NdbMgmHandle
520      * so we should still be connected (and be able to check_connection)
521      *
522      */
523 
524     if(ndb_mgm_check_connection(h) && !ndb_mgm_is_connected(h))
525     {
526       ndbout << "FAILED: is still connected after error" << endl;
527       result= NDBT_FAILED;
528     }
529 
530     ndb_mgm_disconnect(h);
531   }
532 
533 done:
534   ndb_mgm_disconnect(h);
535   ndb_mgm_destroy_handle(&h);
536 
537   return result;
538 }
539 
runTestMgmApiStructEventTimeout(NDBT_Context * ctx,NDBT_Step * step)540 int runTestMgmApiStructEventTimeout(NDBT_Context* ctx, NDBT_Step* step)
541 {
542   NdbMgmd mgmd;
543   int result= NDBT_OK;
544   int mgmd_nodeid= 0;
545 
546   NdbMgmHandle h;
547   h= ndb_mgm_create_handle();
548   ndb_mgm_set_connectstring(h, mgmd.getConnectString());
549 
550   int errs[] = { 10000, 0, -1 };
551 
552   for(int error_ins_no=0; errs[error_ins_no]!=-1; error_ins_no++)
553   {
554     int error_ins= errs[error_ins_no];
555     ndb_mgm_connect(h,0,0,0);
556 
557     if(ndb_mgm_check_connection(h) < 0)
558     {
559       result= NDBT_FAILED;
560       goto done;
561     }
562 
563     mgmd_nodeid= ndb_mgm_get_mgmd_nodeid(h);
564     if(mgmd_nodeid==0)
565     {
566       ndbout << "Failed to get mgmd node id to insert error" << endl;
567       result= NDBT_FAILED;
568       goto done;
569     }
570 
571     ndb_mgm_reply reply;
572     reply.return_code= 0;
573 
574     if(ndb_mgm_insert_error(h, mgmd_nodeid, error_ins, &reply)< 0)
575     {
576       ndbout << "failed to insert error " << error_ins << endl;
577       result= NDBT_FAILED;
578     }
579 
580     ndbout << "trying error: " << error_ins << endl;
581 
582     ndb_mgm_set_timeout(h,2500);
583 
584     int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_BACKUP,
585                      1, NDB_MGM_EVENT_CATEGORY_STARTUP,
586                      0 };
587     NdbLogEventHandle le_handle= ndb_mgm_create_logevent_handle(h, filter);
588 
589     struct ndb_logevent le;
590     for(int i=0; i<20; i++)
591     {
592       if(error_ins==0 || (error_ins!=0 && i<5))
593       {
594         union {
595 	  Uint32 theData[25];
596 	  EventReport repData;
597 	};
598         EventReport *fake_event = &repData;
599         fake_event->setEventType(NDB_LE_NDBStopForced);
600         fake_event->setNodeId(42);
601         theData[2]= 0;
602         theData[3]= 0;
603         theData[4]= 0;
604         theData[5]= 0;
605 
606         ndb_mgm_report_event(h, theData, 6);
607       }
608       int r= ndb_logevent_get_next(le_handle, &le, 2500);
609       if(r>0)
610       {
611         ndbout << "Receieved event" << endl;
612       }
613       else if(r<0)
614       {
615         ndbout << "ERROR" << endl;
616       }
617       else // no event
618       {
619         ndbout << "TIMED OUT READING EVENT at iteration " << i << endl;
620         if(error_ins==0)
621           result= NDBT_FAILED;
622         else
623           result= NDBT_OK;
624         break;
625       }
626     }
627 
628     /*
629      * events go through a *DIFFERENT* socket than the NdbMgmHandle
630      * so we should still be connected (and be able to check_connection)
631      *
632      */
633 
634     if(ndb_mgm_check_connection(h) && !ndb_mgm_is_connected(h))
635     {
636       ndbout << "FAILED: is still connected after error" << endl;
637       result= NDBT_FAILED;
638     }
639 
640     ndb_mgm_disconnect(h);
641   }
642 
643 done:
644   ndb_mgm_disconnect(h);
645   ndb_mgm_destroy_handle(&h);
646 
647   return result;
648 }
649 
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   require((Uint32)ns->node_type == (Uint32)type);
747   require(ns->node_id != 0);
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 myChoice = myRandom48(2);
822   ndb_mgm_node_type randomAllowedType = (myChoice) ?
823                                         NDB_MGM_NODE_TYPE_API :
824                                         NDB_MGM_NODE_TYPE_MGM;
825   int nodeId = 0;
826   if (get_nodeid_of_type(mgmd, randomAllowedType, &nodeId))
827   {
828     return get_config_from_illegal_node(mgmd, nodeId);
829   }
830   // No API/MGM nodes found.
831   return true;
832 }
833 
834 /* Find management node or a random data node, and get config from it.
835  * Also ensure failure when getting config from
836  * an illegal node (a non-NDB/MGM type, nodeid not defined,
837  * or nodeid > MAX_NODES).
838  */
runGetConfigFromNode(NDBT_Context * ctx,NDBT_Step * step)839 int runGetConfigFromNode(NDBT_Context* ctx, NDBT_Step* step)
840 {
841   NdbMgmd mgmd;
842   if (!mgmd.connect())
843     return NDBT_FAILED;
844 
845   if (!check_get_config_wrong_type(mgmd) ||
846       !check_get_config_illegal_node(mgmd) ||
847       !get_config_from_illegal_node(mgmd, MAX_NODES + 2))
848   {
849     return NDBT_FAILED;
850   }
851 
852   int loops= ctx->getNumLoops();
853   for (int l= 0; l < loops; l++)
854   {
855     /* Get config from a node of type: * NDB_MGM_NODE_TYPE_NDB
856      */
857     int nodeId = 0;
858     if (get_nodeid_of_type(mgmd,  NDB_MGM_NODE_TYPE_NDB, &nodeId))
859     {
860       struct ndb_mgm_configuration* conf =
861         ndb_mgm_get_configuration_from_node(mgmd.handle(), nodeId);
862       if (!conf)
863       {
864         g_err << "ndb_mgm_get_configuration_from_node "
865               << nodeId << " failed, error: "
866               << ndb_mgm_get_latest_error(mgmd.handle()) << " "
867               << ndb_mgm_get_latest_error_msg(mgmd.handle()) << endl;
868         return NDBT_FAILED;
869       }
870       free(conf);
871     }
872     else
873     {
874       // ignore
875     }
876   }
877   return NDBT_OK;
878 }
879 
880 
runGetConfigFromNodeUntilStopped(NDBT_Context * ctx,NDBT_Step * step)881 int runGetConfigFromNodeUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
882 {
883   int result= NDBT_OK;
884   while(!ctx->isTestStopped() &&
885         (result= runGetConfigFromNode(ctx, step)) == NDBT_OK)
886     ;
887   return result;
888 }
889 
890 
runTestStatus(NDBT_Context * ctx,NDBT_Step * step)891 int runTestStatus(NDBT_Context* ctx, NDBT_Step* step)
892 {
893   ndb_mgm_node_type types[2] = {
894     NDB_MGM_NODE_TYPE_NDB,
895     NDB_MGM_NODE_TYPE_UNKNOWN
896   };
897 
898   NdbMgmd mgmd;
899   struct ndb_mgm_cluster_state *state;
900   int iterations = ctx->getNumLoops();
901 
902   if (!mgmd.connect())
903     return NDBT_FAILED;
904 
905   int result= NDBT_OK;
906   while (iterations-- != 0 && result == NDBT_OK)
907   {
908     state = ndb_mgm_get_status(mgmd.handle());
909     if(state == NULL) {
910       ndbout_c("Could not get status!");
911       result= NDBT_FAILED;
912       continue;
913     }
914     free(state);
915 
916     state = ndb_mgm_get_status2(mgmd.handle(), types);
917     if(state == NULL){
918       ndbout_c("Could not get status2!");
919       result= NDBT_FAILED;
920       continue;
921     }
922     free(state);
923 
924     state = ndb_mgm_get_status2(mgmd.handle(), 0);
925     if(state == NULL){
926       ndbout_c("Could not get status2 second time!");
927       result= NDBT_FAILED;
928       continue;
929     }
930     free(state);
931   }
932   return result;
933 }
934 
935 
runTestStatusUntilStopped(NDBT_Context * ctx,NDBT_Step * step)936 int runTestStatusUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
937 {
938   int result= NDBT_OK;
939   while(!ctx->isTestStopped() &&
940         (result= runTestStatus(ctx, step)) == NDBT_OK)
941     ;
942   return result;
943 }
944 
945 
946 static bool
get_nodeid(NdbMgmd & mgmd,const Properties & args,Properties & reply)947 get_nodeid(NdbMgmd& mgmd,
948            const Properties& args,
949            Properties& reply)
950 {
951   // Fill in default values of other args
952   Properties call_args(args);
953   if (!call_args.contains("version"))
954     call_args.put("version", 1);
955   if (!call_args.contains("nodetype"))
956     call_args.put("nodetype", 1);
957   if (!call_args.contains("nodeid"))
958     call_args.put("nodeid", 1);
959   if (!call_args.contains("user"))
960     call_args.put("user", "mysqld");
961   if (!call_args.contains("password"))
962     call_args.put("password", "mysqld");
963   if (!call_args.contains("public key"))
964   call_args.put("public key", "a public key");
965   if (!call_args.contains("name"))
966     call_args.put("name", "testMgm");
967   if (!call_args.contains("log_event"))
968     call_args.put("log_event", 1);
969   if (!call_args.contains("timeout"))
970     call_args.put("timeout", 100);
971 
972   if (!call_args.contains("endian"))
973   {
974     union { long l; char c[sizeof(long)]; } endian_check;
975     endian_check.l = 1;
976     call_args.put("endian", (endian_check.c[sizeof(long)-1])?"big":"little");
977   }
978 
979   if (!mgmd.call("get nodeid", call_args,
980                  "get nodeid reply", reply))
981   {
982     g_err << "get_nodeid: mgmd.call failed" << endl;
983     return false;
984   }
985 
986   // reply.print();
987   return true;
988 }
989 
990 
991 static const char*
get_result(const Properties & reply)992 get_result(const Properties& reply)
993 {
994   const char* result;
995   if (!reply.get("result", &result)){
996     ndbout_c("result: no 'result' found in reply");
997     return NULL;
998   }
999   return result;
1000 }
1001 
1002 
result_contains(const Properties & reply,const char * expected_result)1003 static bool result_contains(const Properties& reply,
1004                             const char* expected_result)
1005 {
1006   BaseString result(get_result(reply));
1007   if (strstr(result.c_str(), expected_result) == NULL){
1008     ndbout_c("result_contains: result string '%s' "
1009              "didn't contain expected result '%s'",
1010              result.c_str(), expected_result);
1011     return false;
1012   }
1013   g_info << " result: " << result << endl;
1014   return true;
1015 }
1016 
1017 
ok(const Properties & reply)1018 static bool ok(const Properties& reply)
1019 {
1020   BaseString result(get_result(reply));
1021   if (result == "Ok")
1022     return true;
1023   return false;
1024 }
1025 
failed(const Properties & reply)1026 static bool failed(const Properties& reply)
1027 {
1028   BaseString result(get_result(reply));
1029   if (result == "Failed")
1030     return true;
1031   return false;
1032 }
1033 
1034 static const char*
get_message(const Properties & reply)1035 get_message(const Properties& reply)
1036 {
1037   const char* message;
1038   if (!reply.get("message", &message)){
1039     ndbout_c("message: no 'message' found in reply");
1040     return NULL;
1041   }
1042   return message;
1043 }
1044 
1045 
message_contains(const Properties & reply,const char * expected_message)1046 static bool message_contains(const Properties& reply,
1047                             const char* expected_message)
1048 {
1049   BaseString message(get_message(reply));
1050   if (strstr(message.c_str(), expected_message) == NULL){
1051     ndbout_c("message_contains: message string '%s' "
1052              "didn't contain expected message '%s'",
1053              message.c_str(), expected_message);
1054     return false;
1055   }
1056   g_info << " message: " << message << endl;
1057   return true;
1058 }
1059 
1060 
get_nodeid_result_contains(NdbMgmd & mgmd,const Properties & args,const char * expected_result)1061 static bool get_nodeid_result_contains(NdbMgmd& mgmd,
1062                                        const Properties& args,
1063                                        const char* expected_result)
1064 {
1065   Properties reply;
1066   if (!get_nodeid(mgmd, args, reply))
1067     return false;
1068   return result_contains(reply, expected_result);
1069 }
1070 
1071 
1072 
1073 static bool
check_get_nodeid_invalid_endian1(NdbMgmd & mgmd)1074 check_get_nodeid_invalid_endian1(NdbMgmd& mgmd)
1075 {
1076   union { long l; char c[sizeof(long)]; } endian_check;
1077   endian_check.l = 1;
1078   Properties args;
1079   /* Set endian to opposite value */
1080   args.put("endian", (endian_check.c[sizeof(long)-1])?"little":"big");
1081   return get_nodeid_result_contains(mgmd, args,
1082                                     "Node does not have the same endian");
1083 }
1084 
1085 
1086 static bool
check_get_nodeid_invalid_endian2(NdbMgmd & mgmd)1087 check_get_nodeid_invalid_endian2(NdbMgmd& mgmd)
1088 {
1089   Properties args;
1090   /* Set endian to weird value */
1091   args.put("endian", "hepp");
1092   return get_nodeid_result_contains(mgmd, args,
1093                                     "Node does not have the same endian");
1094 }
1095 
1096 
1097 static bool
check_get_nodeid_invalid_nodetype1(NdbMgmd & mgmd)1098 check_get_nodeid_invalid_nodetype1(NdbMgmd& mgmd)
1099 {
1100   Properties args;
1101   args.put("nodetype", 37);
1102   return get_nodeid_result_contains(mgmd, args,
1103                                     "unknown nodetype 37");
1104 }
1105 
1106 static bool
check_get_nodeid_invalid_nodeid(NdbMgmd & mgmd)1107 check_get_nodeid_invalid_nodeid(NdbMgmd& mgmd)
1108 {
1109   for (int nodeId = MAX_NODES; nodeId < MAX_NODES+2; nodeId++){
1110     g_info << "Testing invalid node " << nodeId << endl;;
1111 
1112     Properties args;
1113     args.put("nodeid", nodeId);
1114     BaseString expected;
1115     expected.assfmt("illegal nodeid %d", nodeId);
1116     if (!get_nodeid_result_contains(mgmd, args, expected.c_str()))
1117       return false;
1118   }
1119   return true;
1120 }
1121 
1122 static bool
check_get_nodeid_dynamic_nodeid(NdbMgmd & mgmd)1123 check_get_nodeid_dynamic_nodeid(NdbMgmd& mgmd)
1124 {
1125   bool result = true;
1126   Uint32 nodeId= 0; // Get dynamic node id
1127   for (int nodeType = NDB_MGM_NODE_TYPE_MIN;
1128        nodeType < NDB_MGM_NODE_TYPE_MAX; nodeType++){
1129     while(true)
1130     {
1131       g_info << "Testing dynamic nodeid " << nodeId
1132              << ", nodeType: " << nodeType << endl;
1133 
1134       Properties args;
1135       args.put("nodeid", nodeId);
1136       args.put("nodetype", nodeType);
1137       Properties reply;
1138       if (!get_nodeid(mgmd, args, reply))
1139         return false;
1140 
1141       /*
1142         Continue to get dynamic id's until
1143         an error "there is no more nodeid" occur
1144       */
1145       if (!ok(reply)){
1146         BaseString expected1;
1147         expected1.assfmt("No free node id found for %s",
1148                         NdbMgmd::NodeType(nodeType).c_str());
1149         BaseString expected2;
1150         expected2.assfmt("Connection done from wrong host");
1151         if (!(result_contains(reply, expected1.c_str()) ||
1152               result_contains(reply, expected2.c_str())))
1153           result= false; // Got wrong error message
1154         break;
1155       }
1156     }
1157   }
1158   return result;
1159 }
1160 
1161 
1162 static bool
check_get_nodeid_nonode(NdbMgmd & mgmd)1163 check_get_nodeid_nonode(NdbMgmd& mgmd)
1164 {
1165   // Find a node that does not exist
1166   Config conf;
1167   if (!mgmd.get_config(conf))
1168     return false;
1169 
1170   Uint32 nodeId = 0;
1171   for(Uint32 i= 1; i < MAX_NODES; i++){
1172     ConfigIter iter(&conf, CFG_SECTION_NODE);
1173     if (iter.find(CFG_NODE_ID, i) != 0){
1174       nodeId = i;
1175       break;
1176     }
1177   }
1178   if (nodeId == 0)
1179     return true; // All nodes probably defined
1180 
1181   g_info << "Testing nonexisting node " << nodeId << endl;;
1182 
1183   Properties args;
1184   args.put("nodeid", nodeId);
1185   BaseString expected;
1186   expected.assfmt("No node defined with id=%d", nodeId);
1187   return get_nodeid_result_contains(mgmd, args, expected.c_str());
1188 }
1189 
1190 #if 0
1191 static bool
1192 check_get_nodeid_nodeid1(NdbMgmd& mgmd)
1193 {
1194   // Find a node that does exist
1195   Config conf;
1196   if (!mgmd.get_config(conf))
1197     return false;
1198 
1199   Uint32 nodeId = 0;
1200   Uint32 nodeType = NDB_MGM_NODE_TYPE_UNKNOWN;
1201   for(Uint32 i= 1; i < MAX_NODES; i++){
1202     ConfigIter iter(&conf, CFG_SECTION_NODE);
1203     if (iter.find(CFG_NODE_ID, i) == 0){
1204       nodeId = i;
1205       iter.get(CFG_TYPE_OF_SECTION, &nodeType);
1206       break;
1207     }
1208   }
1209   require(nodeId);
1210   require(nodeType != (Uint32)NDB_MGM_NODE_TYPE_UNKNOWN);
1211 
1212   Properties args, reply;
1213   args.put("nodeid",nodeId);
1214   args.put("nodetype",nodeType);
1215   if (!get_nodeid(mgmd, args, reply))
1216   {
1217     g_err << "check_get_nodeid_nodeid1: failed for "
1218           << "nodeid: " << nodeId << ", nodetype: " << nodeType << endl;
1219     return false;
1220   }
1221   reply.print();
1222   return ok(reply);
1223 }
1224 #endif
1225 
1226 static bool
check_get_nodeid_wrong_nodetype(NdbMgmd & mgmd)1227 check_get_nodeid_wrong_nodetype(NdbMgmd& mgmd)
1228 {
1229   // Find a node that does exist
1230   Config conf;
1231   if (!mgmd.get_config(conf))
1232     return false;
1233 
1234   Uint32 nodeId = 0;
1235   Uint32 nodeType = NDB_MGM_NODE_TYPE_UNKNOWN;
1236   for(Uint32 i= 1; i < MAX_NODES; i++){
1237     ConfigIter iter(&conf, CFG_SECTION_NODE);
1238     if (iter.find(CFG_NODE_ID, i) == 0){
1239       nodeId = i;
1240       iter.get(CFG_TYPE_OF_SECTION, &nodeType);
1241       break;
1242     }
1243   }
1244   require(nodeId);
1245   require(nodeType != (Uint32)NDB_MGM_NODE_TYPE_UNKNOWN);
1246 
1247   nodeType = (nodeType + 1) / NDB_MGM_NODE_TYPE_MAX;
1248   require((int)nodeType >= (int)NDB_MGM_NODE_TYPE_MIN &&
1249           (int)nodeType <= (int)NDB_MGM_NODE_TYPE_MAX);
1250 
1251   Properties args, reply;
1252   args.put("nodeid",nodeId);
1253   args.put("nodeid",nodeType);
1254   if (!get_nodeid(mgmd, args, reply))
1255   {
1256     g_err << "check_get_nodeid_nodeid1: failed for "
1257           << "nodeid: " << nodeId << ", nodetype: " << nodeType << endl;
1258     return false;
1259   }
1260   BaseString expected;
1261   expected.assfmt("Id %d configured as", nodeId);
1262   return result_contains(reply, expected.c_str());
1263 }
1264 
1265 
1266 
runTestGetNodeId(NDBT_Context * ctx,NDBT_Step * step)1267 int runTestGetNodeId(NDBT_Context* ctx, NDBT_Step* step)
1268 {
1269   NdbMgmd mgmd;
1270 
1271   if (!mgmd.connect())
1272     return NDBT_FAILED;
1273 
1274   int result= NDBT_FAILED;
1275   if (
1276       check_get_nodeid_invalid_endian1(mgmd) &&
1277       check_get_nodeid_invalid_endian2(mgmd) &&
1278       check_get_nodeid_invalid_nodetype1(mgmd) &&
1279       check_get_nodeid_invalid_nodeid(mgmd) &&
1280       check_get_nodeid_dynamic_nodeid(mgmd) &&
1281       check_get_nodeid_nonode(mgmd) &&
1282 //      check_get_nodeid_nodeid1(mgmd) &&
1283       check_get_nodeid_wrong_nodetype(mgmd) &&
1284       true)
1285     result= NDBT_OK;
1286 
1287   if (!mgmd.end_session())
1288     result= NDBT_FAILED;
1289 
1290   return result;
1291 }
1292 
1293 
runTestGetNodeIdUntilStopped(NDBT_Context * ctx,NDBT_Step * step)1294 int runTestGetNodeIdUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
1295 {
1296   int result= NDBT_OK;
1297   while(!ctx->isTestStopped() &&
1298         (result= runTestGetNodeId(ctx, step)) == NDBT_OK)
1299     ;
1300   return result;
1301 }
1302 
1303 
runSleepAndStop(NDBT_Context * ctx,NDBT_Step * step)1304 int runSleepAndStop(NDBT_Context* ctx, NDBT_Step* step)
1305 {
1306   int counter= 3*ctx->getNumLoops();
1307 
1308   while(!ctx->isTestStopped() && counter--)
1309     NdbSleep_SecSleep(1);;
1310   ctx->stopTest();
1311   return NDBT_OK;
1312 }
1313 
1314 
1315 static bool
check_connection(NdbMgmd & mgmd)1316 check_connection(NdbMgmd& mgmd)
1317 {
1318   Properties args, reply;
1319   mgmd.verbose(false); // Verbose off
1320   bool result= mgmd.call("check connection", args,
1321                          "check connection reply", reply);
1322   mgmd.verbose(); // Verbose on
1323   return result;
1324 }
1325 
1326 
1327 static bool
check_transporter_connect(NdbMgmd & mgmd,const char * hello)1328 check_transporter_connect(NdbMgmd& mgmd, const char * hello)
1329 {
1330   SocketOutputStream out(mgmd.socket());
1331 
1332   // Call 'transporter connect'
1333   if (out.println("transporter connect\n"))
1334   {
1335     g_err << "Send failed" << endl;
1336     return false;
1337   }
1338 
1339   // Send the 'hello'
1340   g_info << "Client hello: '" << hello << "'" << endl;
1341   if (out.println("%s", hello))
1342   {
1343     g_err << "Send hello '" << hello << "' failed" << endl;
1344     return false;
1345   }
1346 
1347   // Should not be possible to read a reply now, socket
1348   // should have been closed
1349   if (check_connection(mgmd)){
1350     g_err << "not disconnected" << endl;
1351     return false;
1352   }
1353 
1354   // disconnect and connect again
1355   if (!mgmd.disconnect())
1356     return false;
1357   if (!mgmd.connect())
1358     return false;
1359 
1360   return true;
1361 }
1362 
1363 
runTestTransporterConnect(NDBT_Context * ctx,NDBT_Step * step)1364 int runTestTransporterConnect(NDBT_Context* ctx, NDBT_Step* step)
1365 {
1366   NdbMgmd mgmd;
1367 
1368   if (!mgmd.connect())
1369     return NDBT_FAILED;
1370 
1371   int result = NDBT_FAILED;
1372   if (
1373       // Junk hello strings
1374       check_transporter_connect(mgmd, "hello") &&
1375       check_transporter_connect(mgmd, "hello again") &&
1376 
1377       // "Blow" the buffer
1378       check_transporter_connect(mgmd, "string_longer_than_buf_1234567890") &&
1379 
1380       // Out of range nodeid
1381       check_transporter_connect(mgmd, "-1") &&
1382       check_transporter_connect(mgmd, "-2 2") &&
1383       check_transporter_connect(mgmd, "10000") &&
1384       check_transporter_connect(mgmd, "99999 8") &&
1385 
1386       // Valid nodeid, invalid transporter type
1387       // Valid nodeid and transporter type, state != CONNECTING
1388       // ^These are only possible to test by finding an existing
1389       //  NDB node that are not started and use its setting(s)
1390 
1391       true)
1392    result = NDBT_OK;
1393 
1394   return result;
1395 }
1396 
1397 
1398 static bool
show_config(NdbMgmd & mgmd,const Properties & args,Properties & reply)1399 show_config(NdbMgmd& mgmd,
1400             const Properties& args,
1401             Properties& reply)
1402 {
1403   if (!mgmd.call("show config", args,
1404                  "show config reply", reply, NULL, false))
1405   {
1406     g_err << "show_config: mgmd.call failed" << endl;
1407     return false;
1408   }
1409 
1410   // reply.print();
1411   return true;
1412 }
1413 
1414 
runCheckConfig(NDBT_Context * ctx,NDBT_Step * step)1415 int runCheckConfig(NDBT_Context* ctx, NDBT_Step* step)
1416 {
1417   NdbMgmd mgmd;
1418 
1419   // Connect to any mgmd and get the config
1420   if (!mgmd.connect())
1421     return NDBT_FAILED;
1422 
1423   Properties args1;
1424   Properties config1;
1425   if (!show_config(mgmd, args1, config1))
1426     return NDBT_FAILED;
1427 
1428   // Get the binary config
1429   Config conf;
1430   if (!mgmd.get_config(conf))
1431     return NDBT_FAILED;
1432 
1433   // Extract list of connectstrings to each mgmd
1434   BaseString connectstring;
1435   conf.getConnectString(connectstring, ";");
1436 
1437   Vector<BaseString> mgmds;
1438   connectstring.split(mgmds, ";");
1439 
1440   // Connect to each mgmd and check
1441   // they all have the same config
1442   for (unsigned i = 0; i < mgmds.size(); i++)
1443   {
1444     NdbMgmd mgmd2;
1445     g_info << "Connecting to " << mgmds[i].c_str() << endl;
1446     if (!mgmd2.connect(mgmds[i].c_str()))
1447       return NDBT_FAILED;
1448 
1449     Properties args2;
1450     Properties config2;
1451     if (!show_config(mgmd, args2, config2))
1452       return NDBT_FAILED;
1453 
1454     // Compare config1 and config2 line by line
1455     Uint32 line = 1;
1456     const char* value1;
1457     const char* value2;
1458     while (true)
1459     {
1460       if (config1.get("line", line, &value1))
1461       {
1462         // config1 had line, so should config2
1463         if (config2.get("line", line, &value2))
1464         {
1465           // both configs had line, check they are equal
1466           if (strcmp(value1, value2) != 0)
1467           {
1468             g_err << "the value on line " << line << "didn't match!" << endl;
1469             g_err << "config1, value: " << value1 << endl;
1470             g_err << "config2, value: " << value2 << endl;
1471             return NDBT_FAILED;
1472           }
1473           // g_info << line << ": " << value1 << " = " << value2 << endl;
1474         }
1475         else
1476         {
1477           g_err << "config2 didn't have line " << line << "!" << endl;
1478           return NDBT_FAILED;
1479         }
1480       }
1481       else
1482       {
1483         // Make sure config2 does not have this line either and end loop
1484         if (config2.get("line", line, &value2))
1485         {
1486           g_err << "config2 had line " << line << " not in config1!" << endl;
1487           return NDBT_FAILED;
1488         }
1489 
1490         // End of loop
1491         g_info << "There was " << line << " lines in config" << endl;
1492         break;
1493       }
1494       line++;
1495     }
1496     if (line == 0)
1497     {
1498       g_err << "FAIL: config should have lines!" << endl;
1499       return NDBT_FAILED;
1500     }
1501 
1502     // Compare the binary config
1503     Config conf2;
1504     if (!mgmd.get_config(conf2))
1505       return NDBT_FAILED;
1506 
1507     if (!conf.equal(&conf2))
1508     {
1509       g_err << "The binary config was different! host: " << mgmds[i] << endl;
1510       return NDBT_FAILED;
1511     }
1512 
1513   }
1514 
1515   return NDBT_OK;
1516 }
1517 
1518 
1519 static bool
reload_config(NdbMgmd & mgmd,const Properties & args,Properties & reply)1520 reload_config(NdbMgmd& mgmd,
1521               const Properties& args,
1522               Properties& reply)
1523 {
1524   if (!mgmd.call("reload config", args,
1525                  "reload config reply", reply))
1526   {
1527     g_err << "reload config: mgmd.call failed" << endl;
1528     return false;
1529   }
1530 
1531   //reply.print();
1532   return true;
1533 }
1534 
1535 
reload_config_result_contains(NdbMgmd & mgmd,const Properties & args,const char * expected_result)1536 static bool reload_config_result_contains(NdbMgmd& mgmd,
1537                                           const Properties& args,
1538                                           const char* expected_result)
1539 {
1540   Properties reply;
1541   if (!reload_config(mgmd, args, reply))
1542     return false;
1543   return result_contains(reply, expected_result);
1544 }
1545 
1546 
1547 static bool
check_reload_config_both_config_and_mycnf(NdbMgmd & mgmd)1548 check_reload_config_both_config_and_mycnf(NdbMgmd& mgmd)
1549 {
1550   Properties args;
1551   // Send reload command with both config_filename and mycnf set
1552   args.put("config_filename", "some filename");
1553   args.put("mycnf", 1);
1554   return reload_config_result_contains(mgmd, args,
1555                                        "ERROR: Both mycnf and config_filename");
1556 }
1557 
1558 
1559 static bool
show_variables(NdbMgmd & mgmd,Properties & reply)1560 show_variables(NdbMgmd& mgmd, Properties& reply)
1561 {
1562   if (!mgmd.call("show variables", "",
1563                  "show variables reply", reply))
1564   {
1565     g_err << "show_variables: mgmd.call failed" << endl;
1566     return false;
1567   }
1568   return true;
1569 }
1570 
1571 
1572 static bool
check_reload_config_invalid_config_filename(NdbMgmd & mgmd,bool mycnf)1573 check_reload_config_invalid_config_filename(NdbMgmd& mgmd, bool mycnf)
1574 {
1575 
1576   BaseString expected("Could not load configuration from 'nonexisting_file");
1577   if (mycnf)
1578   {
1579     // Differing error message if started from my.cnf
1580     expected.assign("Can't switch to use config.ini 'nonexisting_file' "
1581                     "when node was started from my.cnf");
1582   }
1583 
1584   Properties args;
1585   // Send reload command with an invalid config_filename
1586   args.put("config_filename", "nonexisting_file");
1587   return reload_config_result_contains(mgmd, args, expected.c_str());
1588 }
1589 
1590 
runTestReloadConfig(NDBT_Context * ctx,NDBT_Step * step)1591 int runTestReloadConfig(NDBT_Context* ctx, NDBT_Step* step)
1592 {
1593   NdbMgmd mgmd;
1594 
1595   if (!mgmd.connect())
1596     return NDBT_FAILED;
1597 
1598   Properties variables;
1599   if (!show_variables(mgmd, variables))
1600     return NDBT_FAILED;
1601 
1602   variables.print();
1603 
1604   const char* mycnf_str;
1605   if (!variables.get("mycnf", &mycnf_str))
1606     abort();
1607   bool uses_mycnf = (strcmp(mycnf_str, "yes") == 0);
1608 
1609   int result= NDBT_FAILED;
1610   if (
1611       check_reload_config_both_config_and_mycnf(mgmd) &&
1612       check_reload_config_invalid_config_filename(mgmd, uses_mycnf) &&
1613       true)
1614     result= NDBT_OK;
1615 
1616   if (!mgmd.end_session())
1617     result= NDBT_FAILED;
1618 
1619   return result;
1620 }
1621 
1622 
1623 static bool
set_config(NdbMgmd & mgmd,const Properties & args,BaseString encoded_config,Properties & reply)1624 set_config(NdbMgmd& mgmd,
1625            const Properties& args,
1626            BaseString encoded_config,
1627            Properties& reply)
1628 {
1629 
1630   // Fill in default values of other args
1631   Properties call_args(args);
1632   if (!call_args.contains("Content-Type"))
1633     call_args.put("Content-Type", "ndbconfig/octet-stream");
1634   if (!call_args.contains("Content-Transfer-Encoding"))
1635     call_args.put("Content-Transfer-Encoding", "base64");
1636   if (!call_args.contains("Content-Length"))
1637     call_args.put("Content-Length",
1638                   encoded_config.length() ? encoded_config.length() - 1 : 1);
1639 
1640   if (!mgmd.call("set config", call_args,
1641                  "set config reply", reply,
1642                  encoded_config.c_str()))
1643   {
1644     g_err << "set config: mgmd.call failed" << endl;
1645     return false;
1646   }
1647 
1648   //reply.print();
1649   return true;
1650 }
1651 
1652 
set_config_result_contains(NdbMgmd & mgmd,const Properties & args,const BaseString & encoded_config,const char * expected_result)1653 static bool set_config_result_contains(NdbMgmd& mgmd,
1654                                        const Properties& args,
1655                                        const BaseString& encoded_config,
1656                                        const char* expected_result)
1657 {
1658   Properties reply;
1659   if (!set_config(mgmd, args, encoded_config, reply))
1660     return false;
1661   return result_contains(reply, expected_result);
1662 }
1663 
1664 
set_config_result_contains(NdbMgmd & mgmd,const Config & conf,const char * expected_result)1665 static bool set_config_result_contains(NdbMgmd& mgmd,
1666                                        const Config& conf,
1667                                        const char* expected_result)
1668 {
1669   Properties reply;
1670   Properties args;
1671 
1672   BaseString encoded_config;
1673   if (!conf.pack64(encoded_config))
1674     return false;
1675 
1676   if (!set_config(mgmd, args, encoded_config, reply))
1677     return false;
1678   return result_contains(reply, expected_result);
1679 }
1680 
1681 
1682 static bool
check_set_config_invalid_content_type(NdbMgmd & mgmd)1683 check_set_config_invalid_content_type(NdbMgmd& mgmd)
1684 {
1685   Properties args;
1686   args.put("Content-Type", "illegal type");
1687   return set_config_result_contains(mgmd, args, BaseString(""),
1688                                     "Unhandled content type 'illegal type'");
1689 }
1690 
1691 static bool
check_set_config_invalid_content_encoding(NdbMgmd & mgmd)1692 check_set_config_invalid_content_encoding(NdbMgmd& mgmd)
1693 {
1694   Properties args;
1695   args.put("Content-Transfer-Encoding", "illegal encoding");
1696   return set_config_result_contains(mgmd, args, BaseString(""),
1697                                     "Unhandled content encoding "
1698                                     "'illegal encoding'");
1699 }
1700 
1701 static bool
check_set_config_too_large_content_length(NdbMgmd & mgmd)1702 check_set_config_too_large_content_length(NdbMgmd& mgmd)
1703 {
1704   Properties args;
1705   args.put("Content-Length", 1024*1024 + 1);
1706   return set_config_result_contains(mgmd, args, BaseString(""),
1707                                     "Illegal config length size 1048577");
1708 }
1709 
1710 static bool
check_set_config_too_small_content_length(NdbMgmd & mgmd)1711 check_set_config_too_small_content_length(NdbMgmd& mgmd)
1712 {
1713   Properties args;
1714   args.put("Content-Length", (Uint32)0);
1715   return set_config_result_contains(mgmd, args, BaseString(""),
1716                                     "Illegal config length size 0");
1717 }
1718 
1719 static bool
check_set_config_wrong_config_length(NdbMgmd & mgmd)1720 check_set_config_wrong_config_length(NdbMgmd& mgmd)
1721 {
1722 
1723   // Get the binary config
1724   Config conf;
1725   if (!mgmd.get_config(conf))
1726     return false;
1727 
1728   BaseString encoded_config;
1729   if (!conf.pack64(encoded_config))
1730     return false;
1731 
1732   Properties args;
1733   args.put("Content-Length", encoded_config.length() - 20);
1734   bool res = set_config_result_contains(mgmd, args, encoded_config,
1735                                         "Failed to unpack config");
1736 
1737   if (res){
1738     /*
1739       There are now additional 20 bytes of junk that has been
1740       sent to mgmd, reconnect to get rid of it
1741     */
1742     if (!mgmd.disconnect())
1743       return false;
1744     if (!mgmd.connect())
1745        return false;
1746   }
1747   return res;
1748 }
1749 
1750 static bool
check_set_config_any_node(NDBT_Context * ctx,NDBT_Step * step,NdbMgmd & mgmd)1751 check_set_config_any_node(NDBT_Context* ctx, NDBT_Step* step, NdbMgmd& mgmd)
1752 {
1753 
1754   // Get the binary config
1755   Config conf;
1756   if (!mgmd.get_config(conf))
1757     return false;
1758 
1759   // Extract list of connectstrings to each mgmd
1760   BaseString connectstring;
1761   conf.getConnectString(connectstring, ";");
1762 
1763   Vector<BaseString> mgmds;
1764   connectstring.split(mgmds, ";");
1765 
1766   // Connect to each mgmd and check
1767   // they all have the same config
1768   for (unsigned i = 0; i < mgmds.size(); i++)
1769   {
1770     NdbMgmd mgmd2;
1771     g_info << "Connecting to " << mgmds[i].c_str() << endl;
1772     if (!mgmd2.connect(mgmds[i].c_str()))
1773       return false;
1774 
1775     // Get the binary config
1776     Config conf2;
1777     if (!mgmd2.get_config(conf2))
1778       return false;
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
check_set_config_fail_wrong_generation(NdbMgmd & mgmd)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
check_set_config_fail_wrong_name(NdbMgmd & mgmd)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
check_set_config_fail_wrong_primary(NdbMgmd & mgmd)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 
runTestSetConfig(NDBT_Context * ctx,NDBT_Step * step)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 
runTestSetConfigParallel(NDBT_Context * ctx,NDBT_Step * step)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 
runTestSetConfigParallelUntilStopped(NDBT_Context * ctx,NDBT_Step * step)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
get_connection_parameter(NdbMgmd & mgmd,const Properties & args,Properties & reply)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
set_connection_parameter(NdbMgmd & mgmd,const Properties & args,Properties & reply)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
check_connection_parameter_invalid_nodeid(NdbMgmd & mgmd)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
check_connection_parameter(NdbMgmd & mgmd)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 
runTestConnectionParameter(NDBT_Context * ctx,NDBT_Step * step)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 
runTestConnectionParameterUntilStopped(NDBT_Context * ctx,NDBT_Step * step)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 
2212   return result;
2213 }
2214 
2215 
2216 static bool
set_ports(NdbMgmd & mgmd,const Properties & args,const char * bulk_arg,Properties & reply)2217 set_ports(NdbMgmd& mgmd,
2218           const Properties& args, const char* bulk_arg,
2219           Properties& reply)
2220 {
2221   if (!mgmd.call("set ports", args,
2222                  "set ports reply", reply, bulk_arg))
2223   {
2224     g_err << "set_ports: mgmd.call failed" << endl;
2225     return false;
2226   }
2227   return true;
2228 }
2229 
2230 static bool
check_set_ports_invalid_nodeid(NdbMgmd & mgmd)2231 check_set_ports_invalid_nodeid(NdbMgmd& mgmd)
2232 {
2233   for (int nodeId = MAX_NODES; nodeId < MAX_NODES+2; nodeId++)
2234   {
2235     g_err << "Testing invalid node " << nodeId << endl;
2236 
2237     Properties args;
2238     args.put("node", nodeId);
2239     args.put("num_ports", 2);
2240 
2241     Properties set_result;
2242     if (!set_ports(mgmd, args, "", set_result))
2243       return false;
2244 
2245     if (ok(set_result))
2246       return false;
2247 
2248     if (!result_contains(set_result, "Illegal value for argument node"))
2249       return false;
2250   }
2251   return true;
2252 }
2253 
2254 static bool
check_set_ports_invalid_num_ports(NdbMgmd & mgmd)2255 check_set_ports_invalid_num_ports(NdbMgmd& mgmd)
2256 {
2257   g_err << "Testing invalid number of ports "<< endl;
2258 
2259   Properties args;
2260   args.put("node", 1);
2261   args.put("num_ports", MAX_NODES + 37);
2262 
2263   Properties set_result;
2264   if (!set_ports(mgmd, args, "", set_result))
2265     return false;
2266 
2267   if (ok(set_result))
2268     return false;
2269 
2270   if (!result_contains(set_result, "Illegal value for argument num_ports"))
2271     return false;
2272 
2273   return true;
2274 }
2275 
2276 
2277 
2278 static bool
check_set_ports_invalid_mismatch_num_port_1(NdbMgmd & mgmd)2279 check_set_ports_invalid_mismatch_num_port_1(NdbMgmd& mgmd)
2280 {
2281   g_err << "Testing invalid num port 1"<< endl;
2282 
2283   Properties args;
2284   args.put("node", 1);
2285   args.put("num_ports", 1);
2286   // Intend to send 1   ^ but passes two below
2287 
2288   Properties set_result;
2289   if (!set_ports(mgmd, args, "1=-37\n2=-38\n", set_result))
2290     return false;
2291 
2292   if (ok(set_result))
2293     return false;
2294   set_result.print();
2295 
2296   if (!result_contains(set_result, "expected empty line"))
2297     return false;
2298 
2299   return true;
2300 }
2301 
2302 static bool
check_set_ports_invalid_mismatch_num_port_2(NdbMgmd & mgmd)2303 check_set_ports_invalid_mismatch_num_port_2(NdbMgmd& mgmd)
2304 {
2305   g_err << "Testing invalid num port 2"<< endl;
2306 
2307   Properties args;
2308   args.put("node", 1);
2309   args.put("num_ports", 2);
2310   // Intend to send 2   ^ but pass only one line below
2311 
2312   Properties set_result;
2313   if (!set_ports(mgmd, args, "1=-37\n", set_result))
2314     return false;
2315 
2316   if (ok(set_result))
2317     return false;
2318   set_result.print();
2319 
2320   if (!result_contains(set_result, "expected name=value pair"))
2321     return false;
2322 
2323   return true;
2324 }
2325 
2326 
2327 static bool
check_set_ports_invalid_port_list(NdbMgmd & mgmd)2328 check_set_ports_invalid_port_list(NdbMgmd& mgmd)
2329 {
2330   g_err << "Testing invalid port list"<< endl;
2331 
2332   Properties args;
2333   args.put("node", 1);
2334   // No connection from 1 -> 1 exist
2335   args.put("num_ports", 1);
2336 
2337   Properties set_result;
2338   if (!set_ports(mgmd, args, "1=-37\n", set_result))
2339     return false;
2340   set_result.print();
2341 
2342   if (ok(set_result))
2343     return false;
2344 
2345   if (!result_contains(set_result,
2346                        "Unable to find connection between nodes 1 -> 1"))
2347     return false;
2348 
2349   return true;
2350 }
2351 
check_mgmapi_err(NdbMgmd & mgmd,int return_code,int expected_error,const char * expected_message)2352 static bool check_mgmapi_err(NdbMgmd& mgmd,
2353                              int return_code,
2354                              int expected_error,
2355                              const char* expected_message)
2356 {
2357   if (return_code != -1)
2358   {
2359     ndbout_c("check_mgmapi_error: unexpected return code: %d", return_code);
2360     return false;
2361   }
2362   if (mgmd.last_error() != expected_error)
2363   {
2364      ndbout_c("check_mgmapi_error: unexpected error code: %d "
2365               "expected %d", mgmd.last_error(), expected_error);
2366     return false;
2367   }
2368   if (strstr(mgmd.last_error_message(), expected_message) == NULL)
2369   {
2370     ndbout_c("check_mgmapi_error: last_error_message '%s' "
2371              "didn't contain expected message '%s'",
2372              mgmd.last_error_message(), expected_message);
2373     return false;
2374   }
2375   return true;
2376 
2377 }
2378 
2379 static bool
check_set_ports_mgmapi(NdbMgmd & mgmd)2380 check_set_ports_mgmapi(NdbMgmd& mgmd)
2381 {
2382   g_err << "Testing mgmapi"<< endl;
2383 
2384   int ret;
2385   int nodeid = 1;
2386   unsigned num_ports = 1;
2387   ndb_mgm_dynamic_port ports[MAX_NODES * 10];
2388   compile_time_assert(MAX_NODES < NDB_ARRAY_SIZE(ports));
2389   ports[0].nodeid = 1;
2390   ports[0].port = -1;
2391 
2392   {
2393     ndbout_c("No handle");
2394     NdbMgmd no_handle;
2395     ret = ndb_mgm_set_dynamic_ports(no_handle.handle(), nodeid,
2396                                     ports, num_ports);
2397     if (ret != -1)
2398       return false;
2399   }
2400   {
2401     ndbout_c("Not connected");
2402     NdbMgmd no_con;
2403     no_con.verbose(false);
2404     if (no_con.connect("no_such_host:12345", 0, 1))
2405     {
2406       // Connect should not suceed!
2407       return false;
2408     }
2409 
2410     ret = ndb_mgm_set_dynamic_ports(no_con.handle(), nodeid,
2411                                     ports, num_ports);
2412     if (!check_mgmapi_err(no_con, ret, NDB_MGM_SERVER_NOT_CONNECTED, ""))
2413       return false;
2414   }
2415 
2416   ndbout_c("Invalid number of ports");
2417   num_ports = 0; // <<
2418   ret = ndb_mgm_set_dynamic_ports(mgmd.handle(), nodeid,
2419                                   ports, num_ports);
2420   if (!check_mgmapi_err(mgmd, ret, NDB_MGM_USAGE_ERROR,
2421                         "Illegal number of dynamic ports"))
2422     return false;
2423 
2424   ndbout_c("Invalid nodeid");
2425   nodeid = 0; // <<
2426   num_ports = 1;
2427   ret = ndb_mgm_set_dynamic_ports(mgmd.handle(), nodeid,
2428                                   ports, num_ports);
2429   if (!check_mgmapi_err(mgmd, ret, NDB_MGM_USAGE_ERROR,
2430                         "Illegal value for argument node: 0"))
2431     return false;
2432 
2433   ndbout_c("Invalid port in list");
2434   nodeid = 1;
2435   ports[0].nodeid = 1;
2436   ports[0].port = 1; // <<
2437   ret = ndb_mgm_set_dynamic_ports(mgmd.handle(), nodeid,
2438                                   ports, num_ports);
2439   if (!check_mgmapi_err(mgmd, ret, NDB_MGM_USAGE_ERROR,
2440                         "Illegal port specfied in ports array"))
2441     return false;
2442 
2443 
2444   ndbout_c("Invalid nodeid in list");
2445   nodeid = 1;
2446   ports[0].nodeid = 0; // <<
2447   ports[0].port = -11;
2448   ret = ndb_mgm_set_dynamic_ports(mgmd.handle(), nodeid,
2449                                   ports, num_ports);
2450   if (!check_mgmapi_err(mgmd, ret, NDB_MGM_USAGE_ERROR,
2451                         "Illegal nodeid specfied in ports array"))
2452     return false;
2453 
2454   ndbout_c("Max number of ports exceeded");
2455   nodeid = 1;
2456   num_ports = MAX_NODES; // <<
2457   for (unsigned i = 0; i < num_ports; i++)
2458   {
2459     ports[i].nodeid = i+1;
2460     ports[i].port = -37;
2461   }
2462   ret = ndb_mgm_set_dynamic_ports(mgmd.handle(), nodeid,
2463                                   ports, num_ports);
2464   if (!check_mgmapi_err(mgmd, ret, NDB_MGM_USAGE_ERROR,
2465                         "Illegal value for argument num_ports"))
2466     return false;
2467 
2468   ndbout_c("Many many ports");
2469   nodeid = 1;
2470   num_ports = NDB_ARRAY_SIZE(ports); // <<
2471   for (unsigned i = 0; i < num_ports; i++)
2472   {
2473     ports[i].nodeid = i+1;
2474     ports[i].port = -37;
2475   }
2476   ret = ndb_mgm_set_dynamic_ports(mgmd.handle(), nodeid,
2477                                   ports, num_ports);
2478   if (!check_mgmapi_err(mgmd, ret, NDB_MGM_USAGE_ERROR,
2479                         "Illegal value for argument num_ports"))
2480     return false;
2481 
2482   return true;
2483 }
2484 
2485 // Return name value pair of nodeid/ports which can be sent
2486 // verbatim back to ndb_mgmd
2487 static bool
get_all_ports(NdbMgmd & mgmd,Uint32 nodeId1,BaseString & values)2488 get_all_ports(NdbMgmd& mgmd, Uint32 nodeId1, BaseString& values)
2489 {
2490   for (int nodeId = 1; nodeId < MAX_NODES; nodeId++)
2491   {
2492     Properties args;
2493     args.put("node1", nodeId1);
2494     args.put("node2", nodeId);
2495 
2496     Properties result;
2497     if (!get_connection_parameter(mgmd, args, result))
2498       return false;
2499 
2500     if (!ok(result))
2501       continue;
2502 
2503     // Get value
2504     BaseString value;
2505     if (!result.get("value", value))
2506     {
2507       g_err << "Failed to get value" << endl;
2508       return false;
2509     }
2510     values.appfmt("%d=%s\n", nodeId, value.c_str());
2511   }
2512   return true;
2513 }
2514 
2515 
2516 static bool
check_set_ports(NdbMgmd & mgmd)2517 check_set_ports(NdbMgmd& mgmd)
2518 {
2519   // Find a NDB node with dynamic port
2520   Config conf;
2521   if (!mgmd.get_config(conf))
2522     return false;
2523 
2524   Uint32 nodeId1 = 0;
2525   for(Uint32 i= 1; i < MAX_NODES; i++){
2526     Uint32 nodeType;
2527     ConfigIter iter(&conf, CFG_SECTION_NODE);
2528     if (iter.find(CFG_NODE_ID, i) == 0 &&
2529         iter.get(CFG_TYPE_OF_SECTION, &nodeType) == 0 &&
2530         nodeType == NDB_MGM_NODE_TYPE_NDB){
2531       nodeId1 = i;
2532       break;
2533     }
2534   }
2535 
2536   g_err << "Using NDB node with id: " << nodeId1 << endl;
2537 
2538   g_err << "Get original values of dynamic ports" << endl;
2539   BaseString original_values;
2540   if (!get_all_ports(mgmd, nodeId1, original_values))
2541   {
2542     g_err << "Failed to get all original values" << endl;
2543     return false;
2544   }
2545   ndbout_c("original values: %s", original_values.c_str());
2546 
2547   g_err << "Set new values for all dynamic ports" << endl;
2548   BaseString new_values;
2549   {
2550     Vector<BaseString> port_pairs;
2551     original_values.split(port_pairs, "\n");
2552     // Remove last empty line
2553     require(port_pairs[port_pairs.size()-1] == "");
2554     port_pairs.erase(port_pairs.size()-1);
2555 
2556     // Generate new portnumbers
2557     for (unsigned i = 0; i < port_pairs.size(); i++)
2558     {
2559       int nodeid, port;
2560       if (sscanf(port_pairs[i].c_str(), "%d=%d", &nodeid, &port) != 2)
2561       {
2562         g_err << "Failed to parse port_pairs[" << i << "]: '"
2563               << port_pairs[i] << "'" << endl;
2564         return false;
2565       }
2566       const int new_port = -(int)(i + 37);
2567       new_values.appfmt("%d=%d\n", nodeid, new_port);
2568     }
2569 
2570     Properties args;
2571     args.put("node", nodeId1);
2572     args.put("num_ports", port_pairs.size());
2573 
2574     Properties set_result;
2575     if (!set_ports(mgmd, args, new_values.c_str(), set_result))
2576       return false;
2577 
2578     if (!ok(set_result))
2579     {
2580       g_err << "Unexpected result received from set_ports" << endl;
2581       set_result.print();
2582       return false;
2583     }
2584   }
2585 
2586   g_err << "Compare new values of dynamic ports" << endl;
2587   {
2588     BaseString current_values;
2589     if (!get_all_ports(mgmd, nodeId1, current_values))
2590     {
2591       g_err << "Failed to get all current values" << endl;
2592       return false;
2593     }
2594     ndbout_c("current values: %s", current_values.c_str());
2595 
2596     if (current_values != new_values)
2597     {
2598       g_err << "Set values was not correct, expected "
2599             << new_values << ", got "
2600             << current_values << endl;
2601       return false;
2602     }
2603   }
2604 
2605   g_err << "Restore old values" << endl;
2606   {
2607     Vector<BaseString> port_pairs;
2608     original_values.split(port_pairs, "\n");
2609     // Remove last empty line
2610     require(port_pairs[port_pairs.size()-1] == "");
2611     port_pairs.erase(port_pairs.size()-1);
2612 
2613     Properties args;
2614     args.put("node", nodeId1);
2615     args.put("num_ports", port_pairs.size());
2616 
2617     Properties set_result;
2618     if (!set_ports(mgmd, args, original_values.c_str(), set_result))
2619       return false;
2620 
2621     if (!ok(set_result))
2622     {
2623       g_err << "Unexpected result received from set_ports" << endl;
2624       set_result.print();
2625       return false;
2626     }
2627   }
2628 
2629   g_err << "Check restored values" << endl;
2630   {
2631     BaseString current_values;
2632     if (!get_all_ports(mgmd, nodeId1, current_values))
2633     {
2634       g_err << "Failed to get all current values" << endl;
2635       return false;
2636     }
2637     ndbout_c("current values: %s", current_values.c_str());
2638 
2639     if (current_values != original_values)
2640     {
2641       g_err << "Restored values was not correct, expected "
2642             << original_values << ", got "
2643             << current_values << endl;
2644       return false;
2645     }
2646   }
2647 
2648   return true;
2649 }
2650 
2651 
runTestSetPorts(NDBT_Context * ctx,NDBT_Step * step)2652 int runTestSetPorts(NDBT_Context* ctx, NDBT_Step* step)
2653 {
2654   NdbMgmd mgmd;
2655 
2656   if (!mgmd.connect())
2657     return NDBT_FAILED;
2658 
2659   int result= NDBT_FAILED;
2660   if (
2661       check_set_ports(mgmd) &&
2662       check_set_ports_invalid_nodeid(mgmd) &&
2663       check_set_ports_invalid_num_ports(mgmd) &&
2664       check_set_ports_invalid_mismatch_num_port_1(mgmd) &&
2665       check_set_ports_invalid_mismatch_num_port_2(mgmd) &&
2666       check_set_ports_invalid_port_list(mgmd) &&
2667       check_set_ports_mgmapi(mgmd) &&
2668       true)
2669     result= NDBT_OK;
2670 
2671   if (!mgmd.end_session())
2672     result= NDBT_FAILED;
2673 
2674   return result;
2675 }
2676 
2677 
2678 #ifdef NOT_YET
2679 static bool
check_restart_connected(NdbMgmd & mgmd)2680 check_restart_connected(NdbMgmd& mgmd)
2681 {
2682   if (!mgmd.restart())
2683     return false;
2684   return true;
2685  }
2686 
runTestRestartMgmd(NDBT_Context * ctx,NDBT_Step * step)2687 int runTestRestartMgmd(NDBT_Context* ctx, NDBT_Step* step)
2688 {
2689   NdbMgmd mgmd;
2690 
2691   if (!mgmd.connect())
2692     return NDBT_FAILED;
2693 
2694   int result= NDBT_FAILED;
2695   if (
2696       check_restart_connected(mgmd) &&
2697       true)
2698     result= NDBT_OK;
2699 
2700   if (!mgmd.end_session())
2701     result= NDBT_FAILED;
2702 
2703   return result;
2704 }
2705 #endif
2706 
2707 
2708 static bool
set_logfilter(NdbMgmd & mgmd,enum ndb_mgm_event_severity severity,int enable)2709 set_logfilter(NdbMgmd& mgmd,
2710               enum ndb_mgm_event_severity severity,
2711               int enable)
2712 {
2713   struct ndb_mgm_reply reply;
2714   if (ndb_mgm_set_clusterlog_severity_filter(mgmd.handle(),
2715 					     severity,
2716 					     enable,
2717                                              &reply
2718                                              ) == -1)
2719   {
2720     g_err << "set_logfilter: ndb_mgm_set_clusterlog_severity_filter failed"
2721           << endl;
2722     return false;
2723   }
2724   return true;
2725 }
2726 
2727 static bool
get_logfilter(NdbMgmd & mgmd,enum ndb_mgm_event_severity severity,unsigned int * value)2728 get_logfilter(NdbMgmd& mgmd,
2729               enum ndb_mgm_event_severity severity,
2730               unsigned int* value)
2731 {
2732 
2733   struct ndb_mgm_severity severity_struct;
2734   severity_struct.category = severity;
2735   if (ndb_mgm_get_clusterlog_severity_filter(mgmd.handle(),
2736 					     &severity_struct,
2737 					     1) != 1)
2738   {
2739     g_err << "get_logfilter: ndb_mgm_get_clusterlog_severity_filter failed"
2740           << endl;
2741     return false;
2742   }
2743 
2744   require(value);
2745   *value = severity_struct.value;
2746 
2747   return true;
2748 }
2749 
2750 
runTestSetLogFilter(NDBT_Context * ctx,NDBT_Step * step)2751 int runTestSetLogFilter(NDBT_Context* ctx, NDBT_Step* step)
2752 {
2753   NdbMgmd mgmd;
2754 
2755   if (!mgmd.connect())
2756     return NDBT_FAILED;
2757 
2758   for (int i = 0; i < (int)NDB_MGM_EVENT_SEVERITY_ALL; i++)
2759   {
2760     g_info << "severity: " << i << endl;
2761     ndb_mgm_event_severity severity = (ndb_mgm_event_severity)i;
2762 
2763     // Get initial value of level
2764     unsigned int initial_value;
2765     if (!get_logfilter(mgmd, severity, &initial_value))
2766       return NDBT_FAILED;
2767 
2768     // Turn level off
2769     if (!set_logfilter(mgmd, severity, 0))
2770       return NDBT_FAILED;
2771 
2772     // Check it's off
2773     unsigned int curr_value;
2774     if (!get_logfilter(mgmd, severity, &curr_value))
2775       return NDBT_FAILED;
2776 
2777     if (curr_value != 0)
2778     {
2779       g_err << "Failed to turn off severity: "  << severity << endl;
2780       return NDBT_FAILED;
2781     }
2782 
2783     // Turn level on
2784     if (!set_logfilter(mgmd, severity, 1))
2785       return NDBT_FAILED;
2786 
2787     // Check it's on
2788     if (!get_logfilter(mgmd, severity, &curr_value))
2789       return NDBT_FAILED;
2790 
2791     if (curr_value == 0)
2792     {
2793       g_err << "Filed to turn on severity: "  << severity << endl;
2794       return NDBT_FAILED;
2795     }
2796 
2797     // Toggle, ie. turn off
2798     if (!set_logfilter(mgmd, severity, -1))
2799       return NDBT_FAILED;
2800 
2801     // Check it's off
2802     if (!get_logfilter(mgmd, severity, &curr_value))
2803       return NDBT_FAILED;
2804 
2805     if (curr_value != 0)
2806     {
2807       g_err << "Failed to toggle severity : "  << severity << endl;
2808       return NDBT_FAILED;
2809     }
2810 
2811     // Set back initial value
2812     if (!set_logfilter(mgmd, severity, initial_value))
2813       return NDBT_FAILED;
2814 
2815   }
2816 
2817   return NDBT_OK;
2818 }
2819 
2820 
runTestBug40922(NDBT_Context * ctx,NDBT_Step * step)2821 int runTestBug40922(NDBT_Context* ctx, NDBT_Step* step)
2822 {
2823   NdbMgmd mgmd;
2824 
2825   if (!mgmd.connect())
2826     return NDBT_FAILED;
2827 
2828   int filter[] = {
2829     15, NDB_MGM_EVENT_CATEGORY_BACKUP,
2830     1, NDB_MGM_EVENT_CATEGORY_STARTUP,
2831     0
2832   };
2833   NdbLogEventHandle le_handle =
2834     ndb_mgm_create_logevent_handle(mgmd.handle(), filter);
2835   if (!le_handle)
2836     return NDBT_FAILED;
2837 
2838   g_info << "Calling ndb_log_event_get_next" << endl;
2839 
2840   struct ndb_logevent le_event;
2841   int r = ndb_logevent_get_next(le_handle,
2842                                 &le_event,
2843                                 2000);
2844   g_info << "ndb_log_event_get_next returned " << r << endl;
2845 
2846   int result = NDBT_FAILED;
2847   if (r == 0)
2848   {
2849     // Got timeout
2850     g_info << "ndb_logevent_get_next returned timeout" << endl;
2851     result = NDBT_OK;
2852   }
2853   else
2854   {
2855     if(r>0)
2856       g_err << "ERROR: Receieved unexpected event: "
2857             << le_event.type << endl;
2858     if(r<0)
2859       g_err << "ERROR: ndb_logevent_get_next returned error: "
2860             << r << endl;
2861   }
2862 
2863   ndb_mgm_destroy_logevent_handle(&le_handle);
2864 
2865   return result;
2866 }
2867 
2868 
runTestBug45497(NDBT_Context * ctx,NDBT_Step * step)2869 int runTestBug45497(NDBT_Context* ctx, NDBT_Step* step)
2870 {
2871   int result = NDBT_OK;
2872   int loops = ctx->getNumLoops();
2873   Vector<NdbMgmd*> mgmds;
2874 
2875   while(true)
2876   {
2877     NdbMgmd* mgmd = new NdbMgmd();
2878 
2879     // Set quite short timeout
2880     if (!mgmd->set_timeout(1000))
2881     {
2882       result = NDBT_FAILED;
2883       break;
2884     }
2885 
2886     if (mgmd->connect())
2887     {
2888       mgmds.push_back(mgmd);
2889       g_info << "connections: " << mgmds.size() << endl;
2890       continue;
2891     }
2892 
2893     g_err << "Failed to make another connection, connections: "
2894           << mgmds.size() << endl;
2895 
2896 
2897     // Disconnect some connections
2898     int to_disconnect = 10;
2899     while(mgmds.size() && to_disconnect--)
2900     {
2901       g_info << "disconnnect, connections: " << mgmds.size() << endl;
2902       NdbMgmd* mgmd = mgmds[0];
2903       mgmds.erase(0);
2904       delete mgmd;
2905     }
2906 
2907     if (loops-- == 0)
2908       break;
2909   }
2910 
2911   while(mgmds.size())
2912   {
2913     NdbMgmd* mgmd = mgmds[0];
2914     mgmds.erase(0);
2915     delete mgmd;
2916   }
2917 
2918   return result;
2919 }
2920 
2921 
isCategoryValid(struct ndb_logevent * le)2922 bool isCategoryValid(struct ndb_logevent* le)
2923 {
2924   switch (le->category)
2925   {
2926   case NDB_MGM_EVENT_CATEGORY_BACKUP:
2927   case NDB_MGM_EVENT_CATEGORY_STARTUP:
2928   case NDB_MGM_EVENT_CATEGORY_NODE_RESTART:
2929   case NDB_MGM_EVENT_CATEGORY_CONNECTION:
2930   case NDB_MGM_EVENT_CATEGORY_STATISTIC:
2931   case NDB_MGM_EVENT_CATEGORY_CHECKPOINT:
2932     return true;
2933   default:
2934     return false;
2935   }
2936 }
2937 
runTestBug16723708(NDBT_Context * ctx,NDBT_Step * step)2938 int runTestBug16723708(NDBT_Context* ctx, NDBT_Step* step)
2939 {
2940   NdbMgmd mgmd;
2941   int loops = ctx->getNumLoops();
2942   int result = NDBT_FAILED;
2943 
2944   if (!mgmd.connect())
2945     return NDBT_FAILED;
2946 
2947   int filter[] = {
2948     15, NDB_MGM_EVENT_CATEGORY_BACKUP,
2949     15, NDB_MGM_EVENT_CATEGORY_STARTUP,
2950     15, NDB_MGM_EVENT_CATEGORY_NODE_RESTART,
2951     15, NDB_MGM_EVENT_CATEGORY_CONNECTION,
2952     15, NDB_MGM_EVENT_CATEGORY_STATISTIC,
2953     15, NDB_MGM_EVENT_CATEGORY_CHECKPOINT,
2954     0
2955   };
2956   NdbLogEventHandle le_handle =
2957     ndb_mgm_create_logevent_handle(mgmd.handle(), filter);
2958   if (!le_handle)
2959     return NDBT_FAILED;
2960   NdbLogEventHandle le_handle2 =
2961     ndb_mgm_create_logevent_handle(mgmd.handle(), filter);
2962   if (!le_handle2)
2963     return NDBT_FAILED;
2964 
2965   for(int l=0; l<loops; l++)
2966   {
2967     g_info << "Calling ndb_log_event_get_next" << endl;
2968 
2969     struct ndb_logevent le_event;
2970     int r = ndb_logevent_get_next(le_handle,
2971                                   &le_event,
2972                                   2000);
2973     g_info << "ndb_log_event_get_next returned " << r << endl;
2974 
2975     struct ndb_logevent le_event2;
2976     int r2 = ndb_logevent_get_next2(le_handle2,
2977                                     &le_event2,
2978                                     2000);
2979     g_info << "ndb_log_event_get_next2 returned " << r2 << endl;
2980 
2981     result = NDBT_OK;
2982     if ((r == 0) || (r2 == 0))
2983     {
2984       // Got timeout
2985       g_info << "ndb_logevent_get_next[2] returned timeout" << endl;
2986     }
2987     else
2988     {
2989       if(r>0)
2990       {
2991         g_info << "next() ndb_logevent type : " << le_event.type
2992                << " category : " << le_event.category
2993                << " " << ndb_mgm_get_event_category_string(le_event.category)
2994                << endl;
2995         if (isCategoryValid(&le_event))
2996         {
2997           g_err << "ERROR: ndb_logevent_get_next() returned valid category! "
2998                 << le_event.category << endl;
2999           result = NDBT_FAILED;
3000         }
3001       }
3002       else
3003       {
3004         g_err << "ERROR: ndb_logevent_get_next returned error: "
3005               << r << endl;
3006       }
3007 
3008       if(r2>0)
3009       {
3010         g_info << "next2() ndb_logevent type : " << le_event2.type
3011                << " category : " << le_event2.category
3012                << " " << ndb_mgm_get_event_category_string(le_event2.category)
3013                << endl;
3014 
3015         if (!isCategoryValid(&le_event2))
3016         {
3017           g_err << "ERROR: ndb_logevent_get_next2() returned invalid category! "
3018                 << le_event2.category << endl;
3019           result = NDBT_FAILED;
3020         }
3021       }
3022       else
3023       {
3024         g_err << "ERROR: ndb_logevent_get_next2 returned error: "
3025               << r << endl;
3026         result = NDBT_FAILED;
3027       }
3028     }
3029     if(result == NDBT_FAILED)
3030       break;
3031   }
3032   ndb_mgm_destroy_logevent_handle(&le_handle2);
3033   ndb_mgm_destroy_logevent_handle(&le_handle);
3034 
3035   return result;
3036 }
3037 
3038 
3039 static int
runTestGetVersion(NDBT_Context * ctx,NDBT_Step * step)3040 runTestGetVersion(NDBT_Context* ctx, NDBT_Step* step)
3041 {
3042 
3043   NdbMgmd mgmd;
3044 
3045   if (!mgmd.connect())
3046     return NDBT_FAILED;
3047 
3048   char verStr[64];
3049   int major, minor, build;
3050   if (ndb_mgm_get_version(mgmd.handle(),
3051                           &major, &minor, &build,
3052                           sizeof(verStr), verStr) != 1)
3053   {
3054     g_err << "ndb_mgm_get_version failed,"
3055           << "error: " << ndb_mgm_get_latest_error_msg(mgmd.handle())
3056           << "desc: " << ndb_mgm_get_latest_error_desc(mgmd.handle()) << endl;
3057     return NDBT_FAILED;
3058   }
3059 
3060   g_info << "Using major: " << major
3061          << " minor: " << minor
3062          << " build: " << build
3063          << " string: " << verStr << endl;
3064 
3065   int l = 0;
3066   int loops = ctx->getNumLoops();
3067   while(l < loops)
3068   {
3069     char verStr2[64];
3070     int major2, minor2, build2;
3071     if (ndb_mgm_get_version(mgmd.handle(),
3072                             &major2, &minor2, &build2,
3073                             sizeof(verStr2), verStr2) != 1)
3074     {
3075       g_err << "ndb_mgm_get_version failed,"
3076             << "error: " << ndb_mgm_get_latest_error_msg(mgmd.handle())
3077             << "desc: " << ndb_mgm_get_latest_error_desc(mgmd.handle()) << endl;
3078       return NDBT_FAILED;
3079     }
3080 
3081     if (major != major2)
3082     {
3083       g_err << "Got different major: " << major2
3084             << " excpected: " << major << endl;
3085       return NDBT_FAILED;
3086     }
3087 
3088     if (minor != minor2)
3089     {
3090       g_err << "Got different minor: " << minor2
3091             << " excpected: " << minor << endl;
3092       return NDBT_FAILED;
3093     }
3094 
3095     if (build != build2)
3096     {
3097       g_err << "Got different build: " << build2
3098             << " excpected: " << build << endl;
3099       return NDBT_FAILED;
3100     }
3101 
3102     if (strcmp(verStr, verStr2) != 0)
3103     {
3104       g_err << "Got different verStr: " << verStr2
3105             << " excpected: " << verStr << endl;
3106       return NDBT_FAILED;
3107     }
3108 
3109     l++;
3110   }
3111 
3112   return NDBT_OK;
3113 }
3114 
3115 
3116 static int
runTestGetVersionUntilStopped(NDBT_Context * ctx,NDBT_Step * step)3117 runTestGetVersionUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
3118 {
3119   int result= NDBT_OK;
3120   while(!ctx->isTestStopped() &&
3121         (result= runTestGetVersion(ctx, step)) == NDBT_OK)
3122     ;
3123   return result;
3124 }
3125 
3126 
runTestDumpEvents(NDBT_Context * ctx,NDBT_Step * step)3127 int runTestDumpEvents(NDBT_Context* ctx, NDBT_Step* step)
3128 {
3129   NdbMgmd mgmd;
3130 
3131   if (!mgmd.connect())
3132     return NDBT_FAILED;
3133 
3134   // Test with unsupported logevent_type
3135   {
3136     const Ndb_logevent_type unsupported = NDB_LE_NDBStopForced;
3137     g_info << "ndb_mgm_dump_events(" << unsupported << ")" << endl;
3138 
3139     const struct ndb_mgm_events* events =
3140       ndb_mgm_dump_events(mgmd.handle(), unsupported, 0, 0);
3141     if (events != NULL)
3142     {
3143       g_err << "ndb_mgm_dump_events returned events "
3144             << "for unsupported Ndb_logevent_type" << endl;
3145       return NDBT_FAILED;
3146     }
3147 
3148     if (ndb_mgm_get_latest_error(mgmd.handle()) != NDB_MGM_USAGE_ERROR ||
3149         strcmp("ndb_logevent_type 59 not supported",
3150                ndb_mgm_get_latest_error_desc(mgmd.handle())))
3151     {
3152       g_err << "Unexpected error for unsupported logevent type, "
3153             << ndb_mgm_get_latest_error(mgmd.handle())
3154             << ", desc: " << ndb_mgm_get_latest_error_desc(mgmd.handle())
3155             << endl;
3156       return NDBT_FAILED;
3157     }
3158   }
3159 
3160   // Test with nodes >= MAX_NDB_NODES
3161   for (int i = MAX_NDB_NODES; i < MAX_NDB_NODES + 3; i++)
3162   {
3163     g_info << "ndb_mgm_dump_events(NDB_LE_MemoryUsage, 1, "
3164            << i << ")" << endl;
3165 
3166     const struct ndb_mgm_events* events =
3167       ndb_mgm_dump_events(mgmd.handle(), NDB_LE_MemoryUsage, 1, &i);
3168     if (events != NULL)
3169     {
3170       g_err << "ndb_mgm_dump_events returned events "
3171             << "for too large nodeid" << endl;
3172       return NDBT_FAILED;
3173     }
3174 
3175     int invalid_nodeid;
3176     if (ndb_mgm_get_latest_error(mgmd.handle()) != NDB_MGM_USAGE_ERROR ||
3177         sscanf(ndb_mgm_get_latest_error_desc(mgmd.handle()),
3178                "invalid nodes: '%d'", &invalid_nodeid) != 1 ||
3179         invalid_nodeid != i)
3180     {
3181       g_err << "Unexpected error for too large nodeid, "
3182             << ndb_mgm_get_latest_error(mgmd.handle())
3183             << ", desc: " << ndb_mgm_get_latest_error_desc(mgmd.handle())
3184             << endl;
3185       return NDBT_FAILED;
3186     }
3187 
3188   }
3189 
3190   int l = 0;
3191   int loops = ctx->getNumLoops();
3192   while (l<loops)
3193   {
3194     const Ndb_logevent_type supported[] =
3195       {
3196         NDB_LE_MemoryUsage,
3197         NDB_LE_BackupStatus,
3198         (Ndb_logevent_type)0
3199       };
3200 
3201     // Test with supported logevent_type
3202     for (int i = 0; supported[i]; i++)
3203     {
3204       g_info << "ndb_mgm_dump_events(" << supported[i] << ")" << endl;
3205 
3206       struct ndb_mgm_events* events =
3207         ndb_mgm_dump_events(mgmd.handle(), supported[i], 0, 0);
3208       if (events == NULL)
3209       {
3210         g_err << "ndb_mgm_dump_events failed, type: " << supported[i]
3211               << ", error: " << ndb_mgm_get_latest_error(mgmd.handle())
3212               << ", msg: " << ndb_mgm_get_latest_error_msg(mgmd.handle())
3213               << endl;
3214         return NDBT_FAILED;
3215       }
3216 
3217       if (events->no_of_events < 0)
3218       {
3219         g_err << "ndb_mgm_dump_events returned a negative number of events: "
3220               << events->no_of_events << endl;
3221         free(events);
3222         return NDBT_FAILED;
3223       }
3224 
3225       g_info << "Got " << events->no_of_events << " events" << endl;
3226       free(events);
3227     }
3228 
3229     l++;
3230   }
3231 
3232   return NDBT_OK;
3233 }
3234 
runTestStatusAfterStop(NDBT_Context * ctx,NDBT_Step * step)3235 int runTestStatusAfterStop(NDBT_Context* ctx, NDBT_Step* step)
3236 {
3237   NdbMgmd mgmd;
3238 
3239   if (!mgmd.connect())
3240     return NDBT_FAILED;
3241 
3242   ndb_mgm_node_type
3243     node_types[2] = { NDB_MGM_NODE_TYPE_NDB,
3244                       NDB_MGM_NODE_TYPE_UNKNOWN };
3245 
3246   // Test: get status, stop node, get status again
3247   printf("Getting status\n");
3248   ndb_mgm_cluster_state *cs = ndb_mgm_get_status2(mgmd.handle(), node_types);
3249   if (cs == NULL)
3250   {
3251     printf("%s (%d)\n", ndb_mgm_get_latest_error_msg(mgmd.handle()),
3252            ndb_mgm_get_latest_error(mgmd.handle()));
3253     return NDBT_FAILED;
3254   }
3255 
3256   int nodeId = 0;
3257   for(int i=0; i < cs->no_of_nodes; i++ )
3258   {
3259     ndb_mgm_node_state *ns = cs->node_states + i;
3260     printf("Node ID: %d  status:%d\n", ns->node_id, ns->node_status);
3261     if (nodeId == 0 && ns->node_type == NDB_MGM_NODE_TYPE_NDB)
3262       nodeId = ns->node_id;
3263   }
3264   free(cs);
3265   cs = NULL;
3266 
3267   printf("Stopping data node\n");
3268   // We only stop 1 data node, in this case NodeId=2
3269   int nodes[1] =  { nodeId };
3270   int stopped = ndb_mgm_restart2(mgmd.handle(), NDB_ARRAY_SIZE(nodes), nodes,
3271                                  0, 0, 1);
3272   if (stopped < 0)
3273   {
3274     printf("ndb_mgm_stop failed, '%s' (%d)\n",
3275            ndb_mgm_get_latest_error_msg(mgmd.handle()),
3276            ndb_mgm_get_latest_error(mgmd.handle()));
3277     return NDBT_FAILED;
3278   }
3279 
3280   printf("Stopped %d data node(s)\n", stopped);
3281 
3282   printf("Getting status\n");
3283   cs = ndb_mgm_get_status2(mgmd.handle(), node_types);
3284   if (cs == NULL)
3285   {
3286     printf("%s (%d)\n", ndb_mgm_get_latest_error_msg(mgmd.handle()),
3287            ndb_mgm_get_latest_error(mgmd.handle()));
3288     return NDBT_FAILED;
3289   }
3290   for(int i=0; i < cs->no_of_nodes; i++ )
3291   {
3292     ndb_mgm_node_state *ns = cs->node_states + i;
3293     printf("Node ID: %d  status:%d\n", ns->node_id, ns->node_status);
3294   }
3295   free(cs);
3296 
3297   NdbRestarter res;
3298   res.startAll();
3299   res.waitClusterStarted();
3300 
3301   return NDBT_OK;
3302 }
3303 
3304 int
sort_ng(const void * _e0,const void * _e1)3305 sort_ng(const void * _e0, const void * _e1)
3306 {
3307   const struct ndb_mgm_node_state * e0 = (const struct ndb_mgm_node_state*)_e0;
3308   const struct ndb_mgm_node_state * e1 = (const struct ndb_mgm_node_state*)_e1;
3309   if (e0->node_group != e1->node_group)
3310     return e0->node_group - e1->node_group;
3311 
3312   return e0->node_id - e1->node_id;
3313 }
3314 
3315 int
runBug12928429(NDBT_Context * ctx,NDBT_Step * step)3316 runBug12928429(NDBT_Context* ctx, NDBT_Step* step)
3317 {
3318   NdbMgmd mgmd;
3319 
3320   if (!mgmd.connect())
3321   {
3322     return NDBT_FAILED;
3323   }
3324 
3325   ndb_mgm_node_type node_types[2] =
3326     { NDB_MGM_NODE_TYPE_NDB, NDB_MGM_NODE_TYPE_UNKNOWN };
3327 
3328   ndb_mgm_cluster_state * cs = ndb_mgm_get_status2(mgmd.handle(), node_types);
3329   if (cs == NULL)
3330   {
3331     printf("%s (%d)\n", ndb_mgm_get_latest_error_msg(mgmd.handle()),
3332            ndb_mgm_get_latest_error(mgmd.handle()));
3333     return NDBT_FAILED;
3334   }
3335 
3336   /**
3337    * sort according to node-group
3338    */
3339   qsort(cs->node_states, cs->no_of_nodes,
3340         sizeof(cs->node_states[0]), sort_ng);
3341 
3342   int ng = cs->node_states[0].node_group;
3343   int replicas = 1;
3344   for (int i = 1; i < cs->no_of_nodes; i++)
3345   {
3346     if (cs->node_states[i].node_status != NDB_MGM_NODE_STATUS_STARTED)
3347     {
3348       ndbout_c("node %u is not started!!!", cs->node_states[i].node_id);
3349       free(cs);
3350       return NDBT_OK;
3351     }
3352     if (cs->node_states[i].node_group == ng)
3353     {
3354       replicas++;
3355     }
3356     else
3357     {
3358       break;
3359     }
3360   }
3361 
3362   if (replicas == 1)
3363   {
3364     free(cs);
3365     return NDBT_OK;
3366   }
3367 
3368   int nodes[MAX_NODES];
3369   int cnt = 0;
3370   for (int i = 0; i < cs->no_of_nodes; i += replicas)
3371   {
3372     printf("%u ", cs->node_states[i].node_id);
3373     nodes[cnt++] = cs->node_states[i].node_id;
3374   }
3375   printf("\n");
3376 
3377   int initial = 0;
3378   int nostart = 1;
3379   int abort = 0;
3380   int force = 1;
3381   int disconnnect = 0;
3382 
3383   /**
3384    * restart half of the node...should be only restart half of the nodes
3385    */
3386   int res = ndb_mgm_restart4(mgmd.handle(), cnt, nodes,
3387                              initial, nostart, abort, force, &disconnnect);
3388 
3389   if (res == -1)
3390   {
3391     ndbout_c("%u res: %u ndb_mgm_get_latest_error: %u line: %u msg: %s",
3392              __LINE__,
3393              res,
3394              ndb_mgm_get_latest_error(mgmd.handle()),
3395              ndb_mgm_get_latest_error_line(mgmd.handle()),
3396              ndb_mgm_get_latest_error_msg(mgmd.handle()));
3397     return NDBT_FAILED;
3398   }
3399 
3400   {
3401     ndb_mgm_cluster_state * cs2 = ndb_mgm_get_status2(mgmd.handle(),node_types);
3402     if (cs2 == NULL)
3403     {
3404       printf("%s (%d)\n", ndb_mgm_get_latest_error_msg(mgmd.handle()),
3405              ndb_mgm_get_latest_error(mgmd.handle()));
3406       return NDBT_FAILED;
3407     }
3408 
3409     for (int i = 0; i < cs2->no_of_nodes; i++)
3410     {
3411       int node_id = cs2->node_states[i].node_id;
3412       int expect = NDB_MGM_NODE_STATUS_STARTED;
3413       for (int c = 0; c < cnt; c++)
3414       {
3415         if (node_id == nodes[c])
3416         {
3417           expect = NDB_MGM_NODE_STATUS_NOT_STARTED;
3418           break;
3419         }
3420       }
3421       if (cs2->node_states[i].node_status != expect)
3422       {
3423         ndbout_c("%u node %u expect: %u found: %u",
3424                  __LINE__,
3425                  cs2->node_states[i].node_id,
3426                  expect,
3427                  cs2->node_states[i].node_status);
3428         return NDBT_FAILED;
3429       }
3430     }
3431     free(cs2);
3432   }
3433 
3434   NdbRestarter restarter;
3435   restarter.startAll();
3436   restarter.waitClusterStarted();
3437 
3438   /**
3439    * restart half of the node...and all nodes in one node group
3440    *   should restart cluster
3441    */
3442   cnt = 0;
3443   for (int i = 0; i < replicas; i++)
3444   {
3445     printf("%u ", cs->node_states[i].node_id);
3446     nodes[cnt++] = cs->node_states[i].node_id;
3447   }
3448   for (int i = replicas; i < cs->no_of_nodes; i += replicas)
3449   {
3450     printf("%u ", cs->node_states[i].node_id);
3451     nodes[cnt++] = cs->node_states[i].node_id;
3452   }
3453   printf("\n");
3454 
3455   res = ndb_mgm_restart4(mgmd.handle(), cnt, nodes,
3456                          initial, nostart, abort, force, &disconnnect);
3457 
3458   if (res == -1)
3459   {
3460     ndbout_c("%u res: %u ndb_mgm_get_latest_error: %u line: %u msg: %s",
3461              __LINE__,
3462              res,
3463              ndb_mgm_get_latest_error(mgmd.handle()),
3464              ndb_mgm_get_latest_error_line(mgmd.handle()),
3465              ndb_mgm_get_latest_error_msg(mgmd.handle()));
3466     return NDBT_FAILED;
3467   }
3468 
3469   {
3470     ndb_mgm_cluster_state * cs2 = ndb_mgm_get_status2(mgmd.handle(),node_types);
3471     if (cs2 == NULL)
3472     {
3473       printf("%s (%d)\n", ndb_mgm_get_latest_error_msg(mgmd.handle()),
3474              ndb_mgm_get_latest_error(mgmd.handle()));
3475       return NDBT_FAILED;
3476     }
3477 
3478     for (int i = 0; i < cs2->no_of_nodes; i++)
3479     {
3480       int expect = NDB_MGM_NODE_STATUS_NOT_STARTED;
3481       if (cs2->node_states[i].node_status != expect)
3482       {
3483         ndbout_c("%u node %u expect: %u found: %u",
3484                  __LINE__,
3485                  cs2->node_states[i].node_id,
3486                  expect,
3487                  cs2->node_states[i].node_status);
3488         return NDBT_FAILED;
3489       }
3490     }
3491     free(cs2);
3492   }
3493 
3494   restarter.startAll();
3495   restarter.waitClusterStarted();
3496 
3497   free(cs);
3498   return NDBT_OK;
3499 }
3500 
runTestNdbApiConfig(NDBT_Context * ctx,NDBT_Step * step)3501 int runTestNdbApiConfig(NDBT_Context* ctx, NDBT_Step* step)
3502 {
3503   NdbMgmd mgmd;
3504 
3505   if (!mgmd.connect())
3506     return NDBT_FAILED;
3507 
3508   struct test_parameter
3509   {
3510     Uint32 key;
3511     Uint32 NdbApiConfig::*ptr;
3512     Uint32 values[2];
3513   } parameters[] =
3514   {
3515     { CFG_MAX_SCAN_BATCH_SIZE,                   &NdbApiConfig::m_scan_batch_size, { 10, 1000 } },
3516     { CFG_BATCH_BYTE_SIZE,                       &NdbApiConfig::m_batch_byte_size, { 10, 1000 } },
3517     { CFG_BATCH_SIZE,                            &NdbApiConfig::m_batch_size,      { 10, 1000 } },
3518     // Skip test of m_waitfor_timeout since it is not configurable in API-section
3519     { CFG_DEFAULT_OPERATION_REDO_PROBLEM_ACTION, &NdbApiConfig::m_default_queue_option,
3520       { OPERATION_REDO_PROBLEM_ACTION_ABORT, OPERATION_REDO_PROBLEM_ACTION_QUEUE } },
3521     { CFG_DEFAULT_HASHMAP_SIZE,                  &NdbApiConfig::m_default_hashmap_size, { 240, 3840 } },
3522   };
3523   // Catch if new members are added to NdbApiConfig,
3524   // if so add tests and adjust expected size
3525   NDB_STATIC_ASSERT(sizeof(NdbApiConfig) == 6 * sizeof(Uint32));
3526 
3527   Config savedconf;
3528   if (!mgmd.get_config(savedconf))
3529     return NDBT_FAILED;
3530 
3531   for (size_t i = 0; i < NDB_ARRAY_SIZE(parameters[0].values) ; i ++)
3532   {
3533     /**
3534      * Setup configuration
3535      */
3536 
3537     // Get the binary config
3538     Config conf;
3539     if (!mgmd.get_config(conf))
3540       return NDBT_FAILED;
3541 
3542     ConfigValues::Iterator iter(conf.m_configValues->m_config);
3543     for (Uint32 nodeid = 1; nodeid < MAX_NODES; nodeid ++)
3544     {
3545       Uint32 type;
3546       if (!iter.openSection(CFG_SECTION_NODE, nodeid))
3547         continue;
3548 
3549       if (iter.get(CFG_TYPE_OF_SECTION, &type) &&
3550           type == NDB_MGM_NODE_TYPE_API)
3551       {
3552         for (size_t param = 0; param < NDB_ARRAY_SIZE(parameters) ; param ++)
3553         {
3554           iter.set(parameters[param].key, parameters[param].values[i]);
3555         }
3556       }
3557 
3558       iter.closeSection();
3559     }
3560 
3561     // Set the modified config
3562     if (!mgmd.set_config(conf))
3563       return NDBT_FAILED;
3564 
3565     /**
3566      * Connect api
3567      */
3568 
3569     Ndb_cluster_connection con(mgmd.getConnectString());
3570 
3571     const int retries = 12;
3572     const int retry_delay = 5;
3573     const int verbose = 1;
3574     if (con.connect(retries, retry_delay, verbose) != 0)
3575     {
3576       g_err << "Ndb_cluster_connection.connect failed" << endl;
3577       return NDBT_FAILED;
3578     }
3579 
3580     /**
3581      * Check api configuration
3582      */
3583 
3584     NDBT_Context conctx(con);
3585     int failures = 0;
3586 
3587     for (size_t param = 0; param < NDB_ARRAY_SIZE(parameters) ; param ++)
3588     {
3589       Uint32 expected = parameters[param].values[i];
3590       Uint32 got = conctx.getConfig().*parameters[param].ptr;
3591       if (got != expected)
3592       {
3593         int j;
3594         for(j = 0; j < ConfigInfo::m_NoOfParams ; j ++)
3595         {
3596           if (ConfigInfo::m_ParamInfo[j]._paramId == parameters[param].key)
3597             break;
3598         }
3599         g_err << "Parameter ";
3600         if (j < ConfigInfo::m_NoOfParams)
3601           g_err << ConfigInfo::m_ParamInfo[j]._fname << " (" << parameters[param].key << ")";
3602         else
3603           g_err << "Unknown (" << parameters[param].key << ")";
3604         g_err << ": Expected " << expected << " got " << got << endl;
3605         failures++;
3606       }
3607       if (failures > 0)
3608         return NDBT_FAILED;
3609     }
3610   }
3611 
3612   // Restore conf after upgrading config generation
3613   Config conf;
3614   if (!mgmd.get_config(conf))
3615     return NDBT_FAILED;
3616 
3617   savedconf.setGeneration(conf.getGeneration());
3618 
3619   if (!mgmd.set_config(savedconf))
3620   {
3621     g_err << "Failed to restore config." << endl;
3622     return NDBT_FAILED;
3623   }
3624 
3625   return NDBT_OK;
3626 }
3627 
3628 
3629 static
runTestCreateLogEvent(NDBT_Context * ctx,NDBT_Step * step)3630 int runTestCreateLogEvent(NDBT_Context* ctx, NDBT_Step* step)
3631 {
3632   NdbMgmd mgmd;
3633   int loops = ctx->getNumLoops();
3634 
3635   if (!mgmd.connect())
3636     return NDBT_FAILED;
3637 
3638   int filter[] = {
3639     15, NDB_MGM_EVENT_CATEGORY_BACKUP,
3640     0
3641   };
3642 
3643   for(int l=0; l<loops; l++)
3644   {
3645     g_info << "Creating log event handle " << l << endl;
3646     NdbLogEventHandle le_handle =
3647         ndb_mgm_create_logevent_handle(mgmd.handle(), filter);
3648     if (!le_handle)
3649       return NDBT_FAILED;
3650 
3651     ndb_mgm_destroy_logevent_handle(&le_handle);
3652   }
3653   return NDBT_OK;
3654 }
3655 
3656 NDBT_TESTSUITE(testMgm);
3657 DRIVER(DummyDriver); /* turn off use of NdbApi */
3658 TESTCASE("ApiSessionFailure",
3659 	 "Test failures in MGMAPI session"){
3660   INITIALIZER(runTestApiSession);
3661 
3662 }
3663 TESTCASE("ApiConnectTimeout",
3664 	 "Connect timeout tests for MGMAPI"){
3665   INITIALIZER(runTestApiConnectTimeout);
3666 
3667 }
3668 TESTCASE("ApiTimeoutBasic",
3669 	 "Basic timeout tests for MGMAPI"){
3670   INITIALIZER(runTestApiTimeoutBasic);
3671 
3672 }
3673 TESTCASE("ApiGetStatusTimeout",
3674 	 "Test timeout for MGMAPI getStatus"){
3675   INITIALIZER(runTestApiGetStatusTimeout);
3676 
3677 }
3678 TESTCASE("ApiGetConfigTimeout",
3679 	 "Test timeouts for mgmapi get_configuration"){
3680   INITIALIZER(runTestMgmApiGetConfigTimeout);
3681 
3682 }
3683 TESTCASE("ApiMgmEventTimeout",
3684 	 "Test timeouts for mgmapi get_configuration"){
3685   INITIALIZER(runTestMgmApiEventTimeout);
3686 
3687 }
3688 TESTCASE("ApiMgmStructEventTimeout",
3689 	 "Test timeouts for mgmapi get_configuration"){
3690   INITIALIZER(runTestMgmApiStructEventTimeout);
3691 
3692 }
3693 TESTCASE("SetConfig",
3694 	 "Tests the ndb_mgm_set_configuration function"){
3695   INITIALIZER(runSetConfig);
3696 }
3697 TESTCASE("CheckConfig",
3698 	 "Connect to each ndb_mgmd and check they have the same configuration"){
3699   INITIALIZER(runCheckConfig);
3700 }
3701 TESTCASE("TestReloadConfig",
3702 	 "Test of 'reload config'"){
3703   INITIALIZER(runTestReloadConfig);
3704 }
3705 TESTCASE("TestSetConfig",
3706 	 "Test of 'set config'"){
3707   INITIALIZER(runTestSetConfig);
3708 }
3709 TESTCASE("TestSetConfigParallel",
3710 	 "Test of 'set config' from 5 threads"){
3711   STEPS(runTestSetConfigParallel, 5);
3712 }
3713 TESTCASE("GetConfig", "Run ndb_mgm_get_configuration in parallel"){
3714   STEPS(runGetConfig, 64);
3715 }
3716 TESTCASE("TestStatus",
3717 	 "Test status and status2"){
3718   INITIALIZER(runTestStatus);
3719 
3720 }
3721 TESTCASE("TestStatusMultiple",
3722 	 "Test status and status2 with 64 threads"){
3723   /**
3724    * For this and other tests we are limited in how much TCP backlog
3725    * the MGM server socket has. It is currently set to a maximum of
3726    * 64, so if we need to test more than 64 threads in parallel we
3727    * need to introduce some sort of wait state to ensure that we
3728    * don't get all threads sending TCP connect at the same time.
3729    */
3730   STEPS(runTestStatus, 64);
3731 
3732 }
3733 TESTCASE("TestGetNodeId",
3734 	 "Test 'get nodeid'"){
3735   INITIALIZER(runTestGetNodeId);
3736 }
3737 TESTCASE("TestGetVersion",
3738  	 "Test 'get version' and 'ndb_mgm_get_version'"){
3739   STEPS(runTestGetVersion, 20);
3740 }
3741 TESTCASE("TestTransporterConnect",
3742 	 "Test 'transporter connect'"){
3743   INITIALIZER(runTestTransporterConnect);
3744 }
3745 TESTCASE("TestConnectionParameter",
3746 	 "Test 'get/set connection parameter'"){
3747   INITIALIZER(runTestConnectionParameter);
3748 }
3749 TESTCASE("TestSetLogFilter",
3750 	 "Test 'set logfilter' and 'get info clusterlog'"){
3751   INITIALIZER(runTestSetLogFilter);
3752 }
3753 #ifdef NOT_YET
3754 TESTCASE("TestRestartMgmd",
3755         "Test restart of ndb_mgmd(s)"){
3756   INITIALIZER(runTestRestartMgmd);
3757 }
3758 #endif
3759 TESTCASE("Bug40922",
3760 	 "Make sure that ndb_logevent_get_next returns when "
3761          "called with a timeout"){
3762   INITIALIZER(runTestBug40922);
3763 }
3764 TESTCASE("Bug16723708",
3765 	 "Check that ndb_logevent_get_next returns events "
3766          "which have valid category values"){
3767   INITIALIZER(runTestBug16723708);
3768 }
3769 TESTCASE("Stress",
3770 	 "Run everything while changing config"){
3771   STEP(runTestGetNodeIdUntilStopped);
3772   STEP(runSetConfigUntilStopped);
3773   STEPS(runGetConfigUntilStopped, 10);
3774   STEPS(runGetConfigFromNodeUntilStopped, 10);
3775   STEPS(runTestStatusUntilStopped, 10);
3776   STEPS(runTestGetVersionUntilStopped, 5);
3777   STEP(runSleepAndStop);
3778 }
3779 TESTCASE("Stress2",
3780 	 "Run everything while changing config in parallel"){
3781   STEP(runTestGetNodeIdUntilStopped);
3782   STEPS(runTestSetConfigParallelUntilStopped, 5);
3783   STEPS(runGetConfigUntilStopped, 10);
3784   STEPS(runGetConfigFromNodeUntilStopped, 10);
3785   STEPS(runTestStatusUntilStopped, 10);
3786   STEPS(runTestGetVersionUntilStopped, 5);
3787   STEP(runSleepAndStop);
3788 }
3789 X_TESTCASE("Bug45497",
3790          "Connect to ndb_mgmd until it can't handle more connections"){
3791   STEP(runTestBug45497);
3792 }
3793 TESTCASE("TestGetVersion",
3794  	 "Test 'get version' and 'ndb_mgm_get_version'"){
3795   STEPS(runTestGetVersion, 20);
3796 }
3797 TESTCASE("TestDumpEvents",
3798  	 "Test 'dump events'"){
3799   STEPS(runTestDumpEvents, 1);
3800 }
3801 TESTCASE("TestStatusAfterStop",
3802  	 "Test get status after stop "){
3803   STEPS(runTestStatusAfterStop, 1);
3804 }
3805 TESTCASE("Bug12928429", "")
3806 {
3807   STEP(runBug12928429);
3808 }
3809 TESTCASE("TestNdbApiConfig", "")
3810 {
3811   STEP(runTestNdbApiConfig);
3812 }
3813 TESTCASE("TestSetPorts",
3814          "Test 'set ports'"){
3815   INITIALIZER(runTestSetPorts);
3816 }
3817 TESTCASE("TestCreateLogEvent", "Test ndb_mgm_create_log_event_handle"){
3818   STEPS(runTestCreateLogEvent, 5);
3819 }
3820 NDBT_TESTSUITE_END(testMgm);
3821 
main(int argc,const char ** argv)3822 int main(int argc, const char** argv){
3823   ndb_init();
3824   NDBT_TESTSUITE_INSTANCE(testMgm);
3825   testMgm.setCreateTable(false);
3826   testMgm.setRunAllTables(true);
3827   return testMgm.execute(argc, argv);
3828 }
3829 
3830 template class Vector<NdbMgmd*>;
3831