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