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