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