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