1 /* Copyright (c) 2003-2007 MySQL AB
2 Use is subject to license terms
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 as published by
6 the Free Software Foundation; version 2 of the License.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16
17 #include <NDBT.hpp>
18 #include <NDBT_Test.hpp>
19 #include <HugoTransactions.hpp>
20 #include <UtilTransactions.hpp>
21 #include <NdbRestarter.hpp>
22 #include <NdbRestarts.hpp>
23 #include <Vector.hpp>
24 #include <random.h>
25 #include <NdbTick.h>
26
27 #define MAX_NDB_OBJECTS 32678
28
29 #define CHECK(b) if (!(b)) { \
30 ndbout << "ERR: "<< step->getName() \
31 << " failed on line " << __LINE__ << endl; \
32 result = NDBT_FAILED; \
33 continue; }
34
35 #define CHECKE(b) if (!(b)) { \
36 errors++; \
37 ndbout << "ERR: "<< step->getName() \
38 << " failed on line " << __LINE__ << endl; \
39 result = NDBT_FAILED; \
40 continue; }
41
42
runTestMaxNdb(NDBT_Context * ctx,NDBT_Step * step)43 int runTestMaxNdb(NDBT_Context* ctx, NDBT_Step* step){
44 Uint32 loops = ctx->getNumLoops();
45 Uint32 l = 0;
46 int oldi = 0;
47 int result = NDBT_OK;
48
49 while (l < loops && result == NDBT_OK){
50 ndbout_c("loop %d", l + 1);
51 int errors = 0;
52 int maxErrors = 5;
53
54 Vector<Ndb*> ndbVector;
55 int i = 0;
56 int init = 0;
57 do {
58
59 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
60 if (pNdb == NULL){
61 ndbout << "pNdb == NULL" << endl;
62 errors++;
63 continue;
64
65 }
66 i++;
67
68 ndbVector.push_back(pNdb);
69
70 if (pNdb->init()){
71 ERR(pNdb->getNdbError());
72 errors++;
73 continue;
74 }
75
76 init++;
77
78 } while (errors == 0);
79
80 ndbout << i << " ndb objects created" << endl;
81
82 if (l > 0 && i != oldi && init != MAX_NDB_OBJECTS){
83 ndbout << l << ": not as manyNdb objects created" << endl
84 << i << " != " << oldi << endl;
85 result = NDBT_FAILED;
86 }
87
88 oldi = i;
89
90
91 for(size_t j = 0; j < ndbVector.size(); j++){
92 delete ndbVector[j];
93 if(((j+1) % 250) == 0){
94 ndbout << "Deleted " << (Uint64) j << " ndb objects " << endl;
95 }
96 }
97 ndbVector.clear();
98
99 l++;
100 }
101
102 return result;
103 }
104
runTestMaxTransaction(NDBT_Context * ctx,NDBT_Step * step)105 int runTestMaxTransaction(NDBT_Context* ctx, NDBT_Step* step){
106 Uint32 loops = ctx->getNumLoops();
107 Uint32 l = 0;
108 int oldi = 0;
109 int result = NDBT_OK;
110
111 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
112 if (pNdb == NULL){
113 ndbout << "pNdb == NULL" << endl;
114 return NDBT_FAILED;
115 }
116 if (pNdb->init(2048)){
117 ERR(pNdb->getNdbError());
118 delete pNdb;
119 return NDBT_FAILED;
120 }
121
122 const NdbDictionary::Table* pTab = ctx->getTab();
123 if (pTab == 0) abort();
124
125 while (l < loops && result == NDBT_OK){
126 int errors = 0;
127 int maxErrors = 5;
128
129 Vector<NdbConnection*> conVector;
130
131
132 int i = 0;
133 do {
134
135 NdbConnection* pCon;
136
137 int type = i%2;
138 switch (type){
139 case 0:
140 pCon = pNdb->startTransaction();
141 break;
142 case 1:
143 {
144 BaseString key;
145 key.appfmt("DATA-%d", i);
146 ndbout_c("%s", key.c_str());
147 pCon = pNdb->startTransaction(pTab,
148 key.c_str(),
149 key.length());
150 }
151 break;
152 default:
153 abort();
154 }
155
156 if (pCon == NULL){
157 ERR(pNdb->getNdbError());
158 errors++;
159 continue;
160 }
161
162 conVector.push_back(pCon);
163
164 i++;
165 } while (errors < maxErrors);
166
167 ndbout << i << " connections created" << endl;
168
169 if (l > 0 && i != oldi){
170 ndbout << l << ": not as many transactions created" << endl
171 << i << " != " << oldi << endl;
172 result = NDBT_FAILED;
173 }
174
175 oldi = i;
176
177
178 for(size_t j = 0; j < conVector.size(); j++){
179 pNdb->closeTransaction(conVector[j]);
180 }
181 conVector.clear();
182 l++;
183
184 }
185
186 // BONUS Test closeTransaction with null trans
187 pNdb->closeTransaction(NULL);
188
189 delete pNdb;
190
191
192 return result;
193 }
194
runTestMaxOperations(NDBT_Context * ctx,NDBT_Step * step)195 int runTestMaxOperations(NDBT_Context* ctx, NDBT_Step* step){
196 Uint32 l = 1;
197 int result = NDBT_OK;
198 int maxOpsLimit = 1;
199 const NdbDictionary::Table* pTab = ctx->getTab();
200
201 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
202 if (pNdb == NULL){
203 ndbout << "pNdb == NULL" << endl;
204 return NDBT_FAILED;
205 }
206 if (pNdb->init(2048)){
207 ERR(pNdb->getNdbError());
208 delete pNdb;
209 return NDBT_FAILED;
210 }
211
212 HugoOperations hugoOps(*pTab);
213
214 bool endTest = false;
215 while (!endTest && result == NDBT_OK){
216 int errors = 0;
217 int maxErrors = 5;
218
219 maxOpsLimit = l*1000;
220
221 if (hugoOps.startTransaction(pNdb) != NDBT_OK){
222 delete pNdb;
223 return NDBT_FAILED;
224 }
225
226 int i = 0;
227 while (errors < maxErrors){
228
229 if(hugoOps.pkReadRecord(pNdb,1, 1) != NDBT_OK){
230 errors++;
231 continue;
232 }
233
234 i++;
235
236 if (i >= maxOpsLimit){
237 errors = maxErrors;
238 }
239
240 }
241
242 ndbout << i << " operations used" << endl;
243
244 int execResult = hugoOps.execute_Commit(pNdb);
245 switch(execResult){
246 case NDBT_OK:
247 break;
248 case 233: // Out of operation records in transaction coordinator
249 // OK - end test
250 endTest = true;
251 break;
252 default:
253 result = NDBT_FAILED;
254 break;
255 }
256
257 hugoOps.closeTransaction(pNdb);
258
259 l++;
260
261 }
262
263 delete pNdb;
264
265 return result;
266 }
267
runTestGetValue(NDBT_Context * ctx,NDBT_Step * step)268 int runTestGetValue(NDBT_Context* ctx, NDBT_Step* step){
269
270 int result = NDBT_OK;
271 const NdbDictionary::Table* pTab = ctx->getTab();
272
273 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
274 if (pNdb == NULL){
275 ndbout << "pNdb == NULL" << endl;
276 return NDBT_FAILED;
277 }
278 if (pNdb->init(2048)){
279 ERR(pNdb->getNdbError());
280 delete pNdb;
281 return NDBT_FAILED;
282 }
283
284 HugoOperations hugoOps(*pTab);
285
286 for (int m = 1; m < 100; m++){
287 int errors = 0;
288 int maxErrors = 5;
289
290 NdbConnection* pCon = pNdb->startTransaction();
291 if (pCon == NULL){
292 delete pNdb;
293 return NDBT_FAILED;
294 }
295
296 NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
297 if (pOp == NULL){
298 pNdb->closeTransaction(pCon);
299 delete pNdb;
300 return NDBT_FAILED;
301 }
302
303 if (pOp->readTuple() != 0){
304 pNdb->closeTransaction(pCon);
305 delete pNdb;
306 return NDBT_FAILED;
307 }
308
309 for(int a = 0; a<pTab->getNoOfColumns(); a++){
310 if (pTab->getColumn(a)->getPrimaryKey() == true){
311 if(hugoOps.equalForAttr(pOp, a, 1) != 0){
312 ERR(pCon->getNdbError());
313 pNdb->closeTransaction(pCon);
314 delete pNdb;
315 return NDBT_FAILED;
316 }
317 }
318 }
319
320 int i = 0;
321 int maxLimit = 1000*m;
322 do {
323
324 if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
325 const NdbError err = pCon->getNdbError();
326 ERR(err);
327 if (err.code == 0)
328 result = NDBT_FAILED;
329 errors++;
330 continue;
331 }
332
333 i++;
334
335 } while (errors < maxErrors && i < maxLimit);
336
337 ndbout << i << " getValues called" << endl;
338
339
340 if (pCon->execute(Commit) != 0){
341 const NdbError err = pCon->getNdbError();
342 switch(err.code){
343 case 880: // TUP - Read too much
344 case 823: // TUP - Too much AI
345 case 4257: // NDBAPI - Too much AI
346 // OK errors
347 ERR(pCon->getNdbError());
348 break;
349 default:
350 ERR(pCon->getNdbError());
351 ndbout << "Illegal error" << endl;
352 result= NDBT_FAILED;
353 break;
354 }
355 }
356
357 pNdb->closeTransaction(pCon);
358
359 }// m
360
361
362 delete pNdb;
363
364 return result;
365 }
366
runTestEqual(NDBT_Context * ctx,NDBT_Step * step)367 int runTestEqual(NDBT_Context* ctx, NDBT_Step* step){
368 Uint32 loops = ctx->getNumLoops();
369 Uint32 l = 0;
370 int result = NDBT_OK;
371 const NdbDictionary::Table* pTab = ctx->getTab();
372
373 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
374 if (pNdb == NULL){
375 ndbout << "pNdb == NULL" << endl;
376 return NDBT_FAILED;
377 }
378 if (pNdb->init(2048)){
379 ERR(pNdb->getNdbError());
380 delete pNdb;
381 return NDBT_FAILED;
382 }
383
384 HugoOperations hugoOps(*pTab);
385
386 while (l < loops){
387 for(int m = 1; m < 10; m++){
388 int errors = 0;
389 int maxErrors = 5;
390
391 NdbConnection* pCon = pNdb->startTransaction();
392 if (pCon == NULL){
393 ndbout << "Could not start transaction" << endl;
394 delete pNdb;
395 return NDBT_FAILED;
396 }
397
398 NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
399 if (pOp == NULL){
400 ERR(pCon->getNdbError());
401 pNdb->closeTransaction(pCon);
402 delete pNdb;
403 return NDBT_FAILED;
404 }
405
406 if (pOp->readTuple() != 0){
407 ERR(pCon->getNdbError());
408 pNdb->closeTransaction(pCon);
409 delete pNdb;
410 return NDBT_FAILED;
411 }
412
413 int i = 0;
414 int maxLimit = 1000*m;
415 do {
416
417 if ((l%2)!=0){
418 // Forward
419 for(int a = 0; a<pTab->getNoOfColumns(); a++){
420 if (pTab->getColumn(a)->getPrimaryKey() == true){
421 if(hugoOps.equalForAttr(pOp, a, 1) != 0){
422 const NdbError err = pCon->getNdbError();
423 ERR(err);
424 if (err.code == 0)
425 result = NDBT_FAILED;
426 errors++;
427 }
428 }
429 }
430 } else {
431 // Backward
432 for(int a = pTab->getNoOfColumns()-1; a>=0; a--){
433 if (pTab->getColumn(a)->getPrimaryKey() == true){
434 if(hugoOps.equalForAttr(pOp, a, 1) != 0){
435 const NdbError err = pCon->getNdbError();
436 ERR(err);
437 if (err.code == 0)
438 result = NDBT_FAILED;
439 errors++;
440 }
441 }
442 }
443 }
444
445 i++;
446
447 } while (errors < maxErrors && i < maxLimit);
448
449 if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
450 const NdbError err = pCon->getNdbError();
451 ERR(pCon->getNdbError());
452 pNdb->closeTransaction(pCon);
453 delete pNdb;
454 if (err.code == 4225) {
455 return NDBT_OK;
456 } else {
457 return NDBT_FAILED;
458 }//if
459 }
460
461 ndbout << i << " equal called" << endl;
462
463
464 int check = pCon->execute(Commit);
465 if (check != 0){
466 ERR(pCon->getNdbError());
467 }
468
469 pNdb->closeTransaction(pCon);
470
471 }// m
472 l++;
473
474 }// l
475
476 delete pNdb;
477 return result;
478 }
479
runTestDeleteNdb(NDBT_Context * ctx,NDBT_Step * step)480 int runTestDeleteNdb(NDBT_Context* ctx, NDBT_Step* step){
481 Uint32 loops = ctx->getNumLoops();
482 Uint32 l = 0;
483 int result = NDBT_OK;
484 NdbRestarts restarts;
485 Vector<Ndb*> ndbVector;
486 const NdbDictionary::Table* pTab = ctx->getTab();
487 HugoTransactions hugoTrans(*pTab);
488 int records = ctx->getNumRecords();
489
490 while (l < loops && result == NDBT_OK){
491
492 // Create 5 ndb objects
493 for( int i = 0; i < 5; i++){
494 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
495 if (pNdb == NULL){
496 ndbout << "pNdb == NULL" << endl;
497 result = NDBT_FAILED;
498 goto end_test;
499 }
500 ndbVector.push_back(pNdb);
501
502 if (pNdb->init()){
503 ERR(pNdb->getNdbError());
504 result = NDBT_FAILED;
505 goto end_test;
506 }
507 if (pNdb->waitUntilReady() != 0){
508 ERR(pNdb->getNdbError());
509 result = NDBT_FAILED;
510 goto end_test;
511 }
512 if (hugoTrans.pkReadRecords(pNdb, records) != 0){
513 result = NDBT_FAILED;
514 goto end_test;
515 }
516 }
517
518 if ((l % 2) == 0){
519 // Restart random node
520 ndbout << "Restart random node " << endl;
521 if(restarts.executeRestart("RestartRandomNodeAbort", 120) != 0){
522 g_err << "Failed to executeRestart(RestartRandomNode)"<<endl;
523 result = NDBT_FAILED;
524 goto end_test;
525 }
526 } else {
527 // Restart all nodes
528 ndbout << "Restart all nodes " << endl;
529 if(restarts.executeRestart("RestartAllNodesAbort", 120) != 0){
530 g_err << "Failed to executeRestart(RestartAllNodes)"<<endl;
531 result = NDBT_FAILED;
532 goto end_test;
533 }
534 }
535
536 // Delete the ndb objects
537 for(size_t j = 0; j < ndbVector.size(); j++)
538 delete ndbVector[j];
539 ndbVector.clear();
540 l++;
541 }
542
543
544 end_test:
545
546 for(size_t i = 0; i < ndbVector.size(); i++)
547 delete ndbVector[i];
548 ndbVector.clear();
549
550 return result;
551 }
552
553
runClearTable(NDBT_Context * ctx,NDBT_Step * step)554 int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
555 int records = ctx->getNumRecords();
556
557 UtilTransactions utilTrans(*ctx->getTab());
558 if (utilTrans.clearTable2(GETNDB(step), records) != 0){
559 return NDBT_FAILED;
560 }
561 return NDBT_OK;
562 }
runLoadTable(NDBT_Context * ctx,NDBT_Step * step)563 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
564
565 int records = ctx->getNumRecords();
566 HugoTransactions hugoTrans(*ctx->getTab());
567 if (hugoTrans.loadTable(GETNDB(step), records) != 0){
568 return NDBT_FAILED;
569 }
570 return NDBT_OK;
571 }
572
runTestWaitUntilReady(NDBT_Context * ctx,NDBT_Step * step)573 int runTestWaitUntilReady(NDBT_Context* ctx, NDBT_Step* step){
574
575 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
576
577 // Forget about calling pNdb->init();
578
579 if (pNdb->waitUntilReady() == 0){
580 ndbout << "waitUntilReady returned OK" << endl;
581 delete pNdb;
582 return NDBT_FAILED;
583 }
584 const NdbError err = pNdb->getNdbError();
585 delete pNdb;
586
587 ERR(err);
588 if (err.code != 4256)
589 return NDBT_FAILED;
590
591 return NDBT_OK;
592 }
593
runGetNdbOperationNoTab(NDBT_Context * ctx,NDBT_Step * step)594 int runGetNdbOperationNoTab(NDBT_Context* ctx, NDBT_Step* step){
595
596 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
597 if (pNdb == NULL){
598 ndbout << "pNdb == NULL" << endl;
599 return NDBT_FAILED;
600 }
601 if (pNdb->init()){
602 ERR(pNdb->getNdbError());
603 delete pNdb;
604 return NDBT_FAILED;
605 }
606
607 NdbConnection* pCon = pNdb->startTransaction();
608 if (pCon == NULL){
609 delete pNdb;
610 return NDBT_FAILED;
611 }
612
613 // Call getNdbOperation on an unknown table
614 NdbOperation* pOp = pCon->getNdbOperation("HUPP76");
615 if (pOp == NULL){
616 NdbError err = pCon->getNdbError();
617 ERR(err);
618 if (err.code == 0){
619 pNdb->closeTransaction(pCon);
620 delete pNdb;
621 return NDBT_FAILED;
622 }
623 }
624
625 pNdb->closeTransaction(pCon);
626
627 delete pNdb;
628
629 return NDBT_OK;
630 }
631
runMissingOperation(NDBT_Context * ctx,NDBT_Step * step)632 int runMissingOperation(NDBT_Context* ctx, NDBT_Step* step){
633 int result = NDBT_OK;
634 const NdbDictionary::Table* pTab = ctx->getTab();
635
636
637 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
638 if (pNdb == NULL){
639 ndbout << "pNdb == NULL" << endl;
640 return NDBT_FAILED;
641 }
642 if (pNdb->init()){
643 ERR(pNdb->getNdbError());
644 delete pNdb;
645 return NDBT_FAILED;
646 }
647
648 NdbConnection* pCon = pNdb->startTransaction();
649 if (pCon == NULL){
650 pNdb->closeTransaction(pCon);
651 delete pNdb;
652 return NDBT_FAILED;
653 }
654
655 NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
656 if (pOp == NULL){
657 ERR(pCon->getNdbError());
658 pNdb->closeTransaction(pCon);
659 delete pNdb;
660 return NDBT_FAILED;
661 }
662
663 // Forget about calling pOp->insertTuple();
664
665 // Call getValue should not work
666 if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
667 const NdbError err = pCon->getNdbError();
668 ERR(err);
669 if (err.code == 0){
670 ndbout << "hupp" << endl;
671 result = NDBT_FAILED;
672 }
673 } else {
674 ndbout << "hupp2" << endl;
675 result = NDBT_FAILED;
676 }
677
678 pNdb->closeTransaction(pCon);
679 delete pNdb;
680
681 return result;
682 }
683
runGetValueInUpdate(NDBT_Context * ctx,NDBT_Step * step)684 int runGetValueInUpdate(NDBT_Context* ctx, NDBT_Step* step){
685 const NdbDictionary::Table* pTab = ctx->getTab();
686
687 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
688 if (pNdb == NULL){
689 ndbout << "pNdb == NULL" << endl;
690 return NDBT_FAILED;
691 }
692 if (pNdb->init()){
693 ERR(pNdb->getNdbError());
694 delete pNdb;
695 return NDBT_FAILED;
696 }
697
698 NdbConnection* pCon = pNdb->startTransaction();
699 if (pCon == NULL){
700 pNdb->closeTransaction(pCon);
701 delete pNdb;
702 return NDBT_FAILED;
703 }
704
705 NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
706 if (pOp == NULL){
707 ERR(pCon->getNdbError());
708 pNdb->closeTransaction(pCon);
709 delete pNdb;
710 return NDBT_FAILED;
711 }
712
713 if (pOp->updateTuple() != 0){
714 pNdb->closeTransaction(pCon);
715 delete pNdb;
716 return NDBT_FAILED;
717 }
718
719 // Call getValue should not work
720 if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
721 // It didn't work
722 const NdbError err = pCon->getNdbError();
723 ERR(err);
724 if (err.code == 0){
725 pNdb->closeTransaction(pCon);
726 delete pNdb;
727 return NDBT_FAILED;
728 }
729 } else {
730 // It worked, not good!
731 pNdb->closeTransaction(pCon);
732 delete pNdb;
733 return NDBT_FAILED;
734 }
735
736 int check = pCon->execute(Commit);
737 if (check != 0){
738 ERR(pCon->getNdbError());
739 }
740
741 pNdb->closeTransaction(pCon);
742 delete pNdb;
743
744 return NDBT_OK;
745 }
746
runUpdateWithoutValues(NDBT_Context * ctx,NDBT_Step * step)747 int runUpdateWithoutValues(NDBT_Context* ctx, NDBT_Step* step){
748 int result = NDBT_OK;
749 const NdbDictionary::Table* pTab = ctx->getTab();
750
751 HugoOperations hugoOps(*pTab);
752
753 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
754 if (pNdb == NULL){
755 ndbout << "pNdb == NULL" << endl;
756 return NDBT_FAILED;
757 }
758 if (pNdb->init()){
759 ERR(pNdb->getNdbError());
760 delete pNdb;
761 return NDBT_FAILED;
762 }
763
764 NdbConnection* pCon = pNdb->startTransaction();
765 if (pCon == NULL){
766 pNdb->closeTransaction(pCon);
767 delete pNdb;
768 return NDBT_FAILED;
769 }
770
771 NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
772 if (pOp == NULL){
773 ERR(pCon->getNdbError());
774 pNdb->closeTransaction(pCon);
775 delete pNdb;
776 return NDBT_FAILED;
777 }
778
779 if (pOp->updateTuple() != 0){
780 pNdb->closeTransaction(pCon);
781 ERR(pOp->getNdbError());
782 delete pNdb;
783 return NDBT_FAILED;
784 }
785
786 for(int a = 0; a<pTab->getNoOfColumns(); a++){
787 if (pTab->getColumn(a)->getPrimaryKey() == true){
788 if(hugoOps.equalForAttr(pOp, a, 1) != 0){
789 ERR(pCon->getNdbError());
790 pNdb->closeTransaction(pCon);
791 delete pNdb;
792 return NDBT_FAILED;
793 }
794 }
795 }
796
797 // Dont' call any setValues
798
799 // Execute should work
800 int check = pCon->execute(Commit);
801 if (check == 0){
802 ndbout << "execute worked" << endl;
803 } else {
804 ERR(pCon->getNdbError());
805 result = NDBT_FAILED;
806 }
807
808 pNdb->closeTransaction(pCon);
809 delete pNdb;
810
811 return result;
812 }
813
runUpdateWithoutKeys(NDBT_Context * ctx,NDBT_Step * step)814 int runUpdateWithoutKeys(NDBT_Context* ctx, NDBT_Step* step){
815 int result = NDBT_OK;
816 const NdbDictionary::Table* pTab = ctx->getTab();
817
818
819 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
820 if (pNdb == NULL){
821 ndbout << "pNdb == NULL" << endl;
822 return NDBT_FAILED;
823 }
824 if (pNdb->init()){
825 ERR(pNdb->getNdbError());
826 delete pNdb;
827 return NDBT_FAILED;
828 }
829
830 NdbConnection* pCon = pNdb->startTransaction();
831 if (pCon == NULL){
832 pNdb->closeTransaction(pCon);
833 delete pNdb;
834 return NDBT_FAILED;
835 }
836
837 NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
838 if (pOp == NULL){
839 ERR(pCon->getNdbError());
840 pNdb->closeTransaction(pCon);
841 delete pNdb;
842 return NDBT_FAILED;
843 }
844
845 if (pOp->updateTuple() != 0){
846 pNdb->closeTransaction(pCon);
847 ERR(pOp->getNdbError());
848 delete pNdb;
849 return NDBT_FAILED;
850 }
851
852 // Dont' call any equal or setValues
853
854 // Execute should not work
855 int check = pCon->execute(Commit);
856 if (check == 0){
857 ndbout << "execute worked" << endl;
858 result = NDBT_FAILED;
859 } else {
860 ERR(pCon->getNdbError());
861 }
862
863 pNdb->closeTransaction(pCon);
864 delete pNdb;
865
866 return result;
867 }
868
869
runReadWithoutGetValue(NDBT_Context * ctx,NDBT_Step * step)870 int runReadWithoutGetValue(NDBT_Context* ctx, NDBT_Step* step){
871 int result = NDBT_OK;
872 const NdbDictionary::Table* pTab = ctx->getTab();
873
874 HugoOperations hugoOps(*pTab);
875
876 Ndb* pNdb = GETNDB(step);
877 Uint32 lm;
878
879 for(Uint32 cm= 0; cm < 2; cm++)
880 {
881 for(lm= 0; lm <= NdbOperation::LM_CommittedRead; lm++)
882 {
883 NdbConnection* pCon = pNdb->startTransaction();
884 if (pCon == NULL){
885 pNdb->closeTransaction(pCon);
886 return NDBT_FAILED;
887 }
888
889 NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
890 if (pOp == NULL){
891 ERR(pCon->getNdbError());
892 pNdb->closeTransaction(pCon);
893 return NDBT_FAILED;
894 }
895
896 if (pOp->readTuple((NdbOperation::LockMode)lm) != 0){
897 pNdb->closeTransaction(pCon);
898 ERR(pOp->getNdbError());
899 return NDBT_FAILED;
900 }
901
902 for(int a = 0; a<pTab->getNoOfColumns(); a++){
903 if (pTab->getColumn(a)->getPrimaryKey() == true){
904 if(hugoOps.equalForAttr(pOp, a, 1) != 0){
905 ERR(pCon->getNdbError());
906 pNdb->closeTransaction(pCon);
907 return NDBT_FAILED;
908 }
909 }
910 }
911
912 // Dont' call any getValues
913
914 // Execute should work
915 int check = pCon->execute(cm == 0 ? NoCommit : Commit);
916 if (check == 0){
917 ndbout << "execute worked" << endl;
918 } else {
919 ERR(pCon->getNdbError());
920 result = NDBT_FAILED;
921 }
922
923 pNdb->closeTransaction(pCon);
924 }
925 }
926
927 /**
928 * Now test scans
929 */
930 for(lm= 0; lm <= NdbOperation::LM_CommittedRead; lm++)
931 {
932 NdbConnection* pCon = pNdb->startTransaction();
933 if (pCon == NULL){
934 pNdb->closeTransaction(pCon);
935 return NDBT_FAILED;
936 }
937
938 NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName());
939 if (pOp == NULL){
940 ERR(pCon->getNdbError());
941 pNdb->closeTransaction(pCon);
942 return NDBT_FAILED;
943 }
944
945 if ((pOp->readTuples((NdbOperation::LockMode)lm)) != 0){
946 pNdb->closeTransaction(pCon);
947 ERR(pOp->getNdbError());
948 return NDBT_FAILED;
949 }
950
951
952 // Dont' call any getValues
953
954 // Execute should work
955 int check = pCon->execute(NoCommit);
956 if (check == 0){
957 ndbout << "execute worked" << endl;
958 } else {
959 ERR(pCon->getNdbError());
960 result = NDBT_FAILED;
961 }
962
963 int res;
964 while((res = pOp->nextResult()) == 0);
965 pNdb->closeTransaction(pCon);
966
967 if(res != 1)
968 result = NDBT_FAILED;
969 }
970
971 return result;
972 }
973
974
runCheckGetNdbErrorOperation(NDBT_Context * ctx,NDBT_Step * step)975 int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){
976 int result = NDBT_OK;
977 const NdbDictionary::Table* pTab = ctx->getTab();
978
979 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
980 if (pNdb == NULL){
981 ndbout << "pNdb == NULL" << endl;
982 return NDBT_FAILED;
983 }
984 if (pNdb->init(2048)){
985 ERR(pNdb->getNdbError());
986 delete pNdb;
987 return NDBT_FAILED;
988 }
989
990 HugoOperations hugoOps(*pTab);
991
992
993 NdbConnection* pCon = pNdb->startTransaction();
994 if (pCon == NULL){
995 ndbout << "Could not start transaction" << endl;
996 delete pNdb;
997 return NDBT_FAILED;
998 }
999
1000 NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
1001 if (pOp == NULL){
1002 ERR(pCon->getNdbError());
1003 pNdb->closeTransaction(pCon);
1004 delete pNdb;
1005 return NDBT_FAILED;
1006 }
1007
1008 // Dont call readTuple here
1009 // That's the error!
1010
1011 for(int a = 0; a<pTab->getNoOfColumns(); a++){
1012 if (pTab->getColumn(a)->getPrimaryKey() == true){
1013 if(hugoOps.equalForAttr(pOp, a, 1) != 0){
1014 // An error has occured, check that
1015 // it's possible to get the NdbErrorOperation
1016 const NdbError err = pCon->getNdbError();
1017 ERR(err);
1018 if (err.code == 0)
1019 result = NDBT_FAILED;
1020
1021 NdbOperation* pOp2 = pCon->getNdbErrorOperation();
1022 if (pOp2 == NULL)
1023 result = NDBT_FAILED;
1024 else {
1025 const NdbError err2 = pOp2->getNdbError();
1026 ERR(err2);
1027 if (err.code == 0)
1028 result = NDBT_FAILED;
1029 }
1030 }
1031 }
1032 }
1033
1034 pNdb->closeTransaction(pCon);
1035
1036 delete pNdb;
1037 return result;
1038 }
1039
1040 #define C2(x) { int _x= (x); if(_x == 0){ ndbout << "line: " << __LINE__ << endl; return NDBT_FAILED;} }
1041
runBug_11133(NDBT_Context * ctx,NDBT_Step * step)1042 int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
1043 int result = NDBT_OK;
1044 const NdbDictionary::Table* pTab = ctx->getTab();
1045
1046 HugoOperations hugoOps(*pTab);
1047
1048 Ndb* pNdb = GETNDB(step);
1049 C2(hugoOps.startTransaction(pNdb) == 0);
1050 C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
1051 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1052 C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1053 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1054 C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1055 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1056 C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1057 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1058 C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1059 C2(hugoOps.execute_Commit(pNdb) == 0);
1060 C2(hugoOps.closeTransaction(pNdb) == 0);
1061
1062 C2(hugoOps.startTransaction(pNdb) == 0);
1063 C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
1064 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1065 C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1066 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1067 C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1068 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1069 C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1070 C2(hugoOps.execute_Commit(pNdb) == 0);
1071 C2(hugoOps.closeTransaction(pNdb) == 0);
1072
1073 C2(hugoOps.startTransaction(pNdb) == 0);
1074 C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
1075 C2(hugoOps.execute_Commit(pNdb) == 0);
1076 C2(hugoOps.closeTransaction(pNdb) == 0);
1077
1078 C2(hugoOps.startTransaction(pNdb) == 0);
1079 C2(hugoOps.pkReadRecord(pNdb, 0, 1, NdbOperation::LM_Exclusive) == 0);
1080 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1081 C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1082 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1083 C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1084 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1085 C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1086 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1087 C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1088 C2(hugoOps.execute_Commit(pNdb) == 0);
1089 C2(hugoOps.closeTransaction(pNdb) == 0);
1090
1091 Ndb ndb2(&ctx->m_cluster_connection, "TEST_DB");
1092 C2(ndb2.init() == 0);
1093 C2(ndb2.waitUntilReady() == 0);
1094 HugoOperations hugoOps2(*pTab);
1095
1096 C2(hugoOps.startTransaction(pNdb) == 0);
1097 C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
1098 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1099 C2(hugoOps2.startTransaction(&ndb2) == 0);
1100 C2(hugoOps2.pkWritePartialRecord(&ndb2, 0) == 0);
1101 C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
1102 C2(hugoOps.execute_Commit(pNdb) == 0);
1103 C2(hugoOps2.wait_async(&ndb2) == 0);
1104 C2(hugoOps.closeTransaction(pNdb) == 0);
1105 C2(hugoOps2.closeTransaction(&ndb2) == 0);
1106
1107 C2(hugoOps.startTransaction(pNdb) == 0);
1108 C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1109 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1110 C2(hugoOps2.startTransaction(&ndb2) == 0);
1111 C2(hugoOps2.pkWriteRecord(&ndb2, 0, 1) == 0);
1112 C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
1113 C2(hugoOps.execute_Commit(pNdb) == 0);
1114 C2(hugoOps2.wait_async(&ndb2) == 0);
1115 C2(hugoOps2.execute_Commit(pNdb) == 0);
1116 C2(hugoOps.closeTransaction(pNdb) == 0);
1117 C2(hugoOps2.closeTransaction(&ndb2) == 0);
1118
1119 C2(hugoOps.startTransaction(pNdb) == 0);
1120 C2(hugoOps.pkUpdateRecord(pNdb, 0, 1) == 0);
1121 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1122 C2(hugoOps2.startTransaction(&ndb2) == 0);
1123 C2(hugoOps2.pkWritePartialRecord(&ndb2, 0) == 0);
1124 C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
1125 C2(hugoOps.execute_Commit(pNdb) == 0);
1126 C2(hugoOps2.wait_async(&ndb2) == 0);
1127 C2(hugoOps.closeTransaction(pNdb) == 0);
1128 C2(hugoOps2.closeTransaction(&ndb2) == 0);
1129
1130 C2(hugoOps.startTransaction(pNdb) == 0);
1131 C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1132 C2(hugoOps.execute_NoCommit(pNdb) == 0);
1133 C2(hugoOps2.startTransaction(&ndb2) == 0);
1134 C2(hugoOps2.pkWritePartialRecord(&ndb2, 0) == 0);
1135 C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
1136 C2(hugoOps.execute_Commit(pNdb) == 0);
1137 C2(hugoOps2.wait_async(&ndb2) != 0);
1138 C2(hugoOps.closeTransaction(pNdb) == 0);
1139 C2(hugoOps2.closeTransaction(&ndb2) == 0);
1140
1141 return result;
1142 }
1143
runBug_WritePartialIgnoreError(NDBT_Context * ctx,NDBT_Step * step)1144 int runBug_WritePartialIgnoreError(NDBT_Context* ctx, NDBT_Step* step){
1145 int result = NDBT_OK;
1146 const NdbDictionary::Table* pTab = ctx->getTab();
1147
1148 HugoOperations hugoOps(*pTab);
1149
1150 Ndb* pNdb = GETNDB(step);
1151 C2(hugoOps.startTransaction(pNdb) == 0);
1152 C2(hugoOps.pkWritePartialRecord(pNdb, 0, 1) == 0);
1153 C2(hugoOps.execute_Commit(pNdb, AO_IgnoreError) == 839);
1154 C2(hugoOps.closeTransaction(pNdb) == 0);
1155
1156 return result;
1157 }
1158
runScan_4006(NDBT_Context * ctx,NDBT_Step * step)1159 int runScan_4006(NDBT_Context* ctx, NDBT_Step* step){
1160 int result = NDBT_OK;
1161 const Uint32 max= 5;
1162 const NdbDictionary::Table* pTab = ctx->getTab();
1163
1164 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
1165 if (pNdb == NULL){
1166 ndbout << "pNdb == NULL" << endl;
1167 return NDBT_FAILED;
1168 }
1169 if (pNdb->init(max)){
1170 ERR(pNdb->getNdbError());
1171 delete pNdb;
1172 return NDBT_FAILED;
1173 }
1174
1175 NdbConnection* pCon = pNdb->startTransaction();
1176 if (pCon == NULL){
1177 pNdb->closeTransaction(pCon);
1178 delete pNdb;
1179 return NDBT_FAILED;
1180 }
1181
1182 Uint32 i;
1183 Vector<NdbScanOperation*> scans;
1184 for(i = 0; i<10*max; i++)
1185 {
1186 NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName());
1187 if (pOp == NULL){
1188 ERR(pCon->getNdbError());
1189 pNdb->closeTransaction(pCon);
1190 delete pNdb;
1191 return NDBT_FAILED;
1192 }
1193
1194 if (pOp->readTuples() != 0){
1195 pNdb->closeTransaction(pCon);
1196 ERR(pOp->getNdbError());
1197 delete pNdb;
1198 return NDBT_FAILED;
1199 }
1200 scans.push_back(pOp);
1201 }
1202
1203 // Dont' call any equal or setValues
1204
1205 // Execute should not work
1206 int check = pCon->execute(NoCommit);
1207 if (check == 0){
1208 ndbout << "execute worked" << endl;
1209 } else {
1210 ERR(pCon->getNdbError());
1211 }
1212
1213 for(i= 0; i<scans.size(); i++)
1214 {
1215 NdbScanOperation* pOp= scans[i];
1216 while((check= pOp->nextResult()) == 0);
1217 if(check != 1)
1218 {
1219 ERR(pOp->getNdbError());
1220 pNdb->closeTransaction(pCon);
1221 delete pNdb;
1222 return NDBT_FAILED;
1223 }
1224 }
1225
1226 pNdb->closeTransaction(pCon);
1227
1228 Vector<NdbConnection*> cons;
1229 for(i= 0; i<10*max; i++)
1230 {
1231 pCon= pNdb->startTransaction();
1232 if(pCon)
1233 cons.push_back(pCon);
1234 else
1235 break;
1236 }
1237
1238 for(i= 0; i<cons.size(); i++)
1239 {
1240 cons[i]->close();
1241 }
1242
1243 if(cons.size() != max)
1244 {
1245 result= NDBT_FAILED;
1246 }
1247
1248 delete pNdb;
1249
1250 return result;
1251 }
1252
1253 char pkIdxName[255];
1254
createPkIndex(NDBT_Context * ctx,NDBT_Step * step)1255 int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){
1256 bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
1257
1258 const NdbDictionary::Table* pTab = ctx->getTab();
1259 Ndb* pNdb = GETNDB(step);
1260
1261 bool logged = ctx->getProperty("LoggedIndexes", 1);
1262
1263 // Create index
1264 BaseString::snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName());
1265 if (orderedIndex)
1266 ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "
1267 << pkIdxName << " (";
1268 else
1269 ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "
1270 << pkIdxName << " (";
1271
1272 NdbDictionary::Index pIdx(pkIdxName);
1273 pIdx.setTable(pTab->getName());
1274 if (orderedIndex)
1275 pIdx.setType(NdbDictionary::Index::OrderedIndex);
1276 else
1277 pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
1278 for (int c = 0; c< pTab->getNoOfColumns(); c++){
1279 const NdbDictionary::Column * col = pTab->getColumn(c);
1280 if(col->getPrimaryKey()){
1281 pIdx.addIndexColumn(col->getName());
1282 ndbout << col->getName() <<" ";
1283 }
1284 }
1285
1286 pIdx.setStoredIndex(logged);
1287 ndbout << ") ";
1288 if (pNdb->getDictionary()->createIndex(pIdx) != 0){
1289 ndbout << "FAILED!" << endl;
1290 const NdbError err = pNdb->getDictionary()->getNdbError();
1291 ERR(err);
1292 return NDBT_FAILED;
1293 }
1294
1295 ndbout << "OK!" << endl;
1296 return NDBT_OK;
1297 }
1298
createPkIndex_Drop(NDBT_Context * ctx,NDBT_Step * step)1299 int createPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){
1300 const NdbDictionary::Table* pTab = ctx->getTab();
1301 Ndb* pNdb = GETNDB(step);
1302
1303 // Drop index
1304 ndbout << "Dropping index " << pkIdxName << " ";
1305 if (pNdb->getDictionary()->dropIndex(pkIdxName,
1306 pTab->getName()) != 0){
1307 ndbout << "FAILED!" << endl;
1308 ERR(pNdb->getDictionary()->getNdbError());
1309 return NDBT_FAILED;
1310 } else {
1311 ndbout << "OK!" << endl;
1312 }
1313
1314 return NDBT_OK;
1315 }
1316
1317 static
1318 int
op_row(NdbTransaction * pTrans,HugoOperations & hugoOps,const NdbDictionary::Table * pTab,int op,int row)1319 op_row(NdbTransaction* pTrans, HugoOperations& hugoOps,
1320 const NdbDictionary::Table* pTab, int op, int row)
1321 {
1322 NdbOperation * pOp = 0;
1323 switch(op){
1324 case 0:
1325 case 1:
1326 case 2:
1327 case 3:
1328 case 4:
1329 case 5:
1330 pOp = pTrans->getNdbOperation(pTab->getName());
1331 break;
1332 case 9:
1333 return 0;
1334 case 6:
1335 case 7:
1336 case 8:
1337 case 10:
1338 case 11:
1339 pOp = pTrans->getNdbIndexOperation(pkIdxName, pTab->getName());
1340 default:
1341 break;
1342 }
1343
1344 switch(op){
1345 case 0:
1346 case 6:
1347 pOp->readTuple();
1348 break;
1349 case 1:
1350 case 7:
1351 pOp->committedRead();
1352 break;
1353 case 2:
1354 case 8:
1355 pOp->readTupleExclusive();
1356 break;
1357 case 3:
1358 case 9:
1359 pOp->insertTuple();
1360 break;
1361 case 4:
1362 case 10:
1363 pOp->updateTuple();
1364 break;
1365 case 5:
1366 case 11:
1367 pOp->deleteTuple();
1368 break;
1369 default:
1370 abort();
1371 }
1372
1373 for(int a = 0; a<pTab->getNoOfColumns(); a++){
1374 if (pTab->getColumn(a)->getPrimaryKey() == true){
1375 if(hugoOps.equalForAttr(pOp, a, row) != 0){
1376 return NDBT_FAILED;
1377 }
1378 }
1379 }
1380
1381 switch(op){
1382 case 0:
1383 case 1:
1384 case 2:
1385 case 6:
1386 case 7:
1387 case 8:
1388 for(int a = 0; a<pTab->getNoOfColumns(); a++){
1389 pOp->getValue(a);
1390 }
1391 break;
1392 case 3:
1393 case 4:
1394 case 10:
1395 for(int a = 0; a<pTab->getNoOfColumns(); a++){
1396 if (pTab->getColumn(a)->getPrimaryKey() == false){
1397 if(hugoOps.setValueForAttr(pOp, a, row, 2) != 0){
1398 return NDBT_FAILED;
1399 }
1400 }
1401 }
1402 break;
1403 case 5:
1404 case 11:
1405 pOp->deleteTuple();
1406 break;
1407 case 9:
1408 default:
1409 abort();
1410 }
1411
1412 return NDBT_OK;
1413 }
1414
print(int op)1415 static void print(int op)
1416 {
1417 const char * str = 0;
1418 switch(op){
1419 case 0: str = "pk read-sh"; break;
1420 case 1: str = "pk read-nl"; break;
1421 case 2: str = "pk read-ex"; break;
1422 case 3: str = "pk insert "; break;
1423 case 4: str = "pk update "; break;
1424 case 5: str = "pk delete "; break;
1425 case 6: str = "uk read-sh"; break;
1426 case 7: str = "uk read-nl"; break;
1427 case 8: str = "uk read-ex"; break;
1428 case 9: str = "noop "; break;
1429 case 10: str = "uk update "; break;
1430 case 11: str = "uk delete "; break;
1431 default:
1432 abort();
1433 }
1434 printf("%s ", str);
1435 }
1436
1437 int
runTestIgnoreError(NDBT_Context * ctx,NDBT_Step * step)1438 runTestIgnoreError(NDBT_Context* ctx, NDBT_Step* step)
1439 {
1440 int result = NDBT_OK;
1441 Uint32 loops = ctx->getNumRecords();
1442 const NdbDictionary::Table* pTab = ctx->getTab();
1443
1444 HugoOperations hugoOps(*pTab);
1445 HugoTransactions hugoTrans(*pTab);
1446
1447 Ndb* pNdb = GETNDB(step);
1448
1449 struct {
1450 ExecType et;
1451 AbortOption ao;
1452 } tests[] = {
1453 { Commit, AbortOnError },
1454 { Commit, AO_IgnoreError },
1455 { NoCommit, AbortOnError },
1456 { NoCommit, AO_IgnoreError },
1457 };
1458
1459 printf("case: <op1> <op2> c/nc ao/ie\n");
1460 Uint32 tno = 0;
1461 for (Uint32 op1 = 0; op1 < 12; op1++)
1462 {
1463 for (Uint32 op2 = op1; op2 < 12; op2++)
1464 {
1465 int ret;
1466 NdbTransaction* pTrans = 0;
1467
1468 for (Uint32 i = 0; i<4; i++, tno++)
1469 {
1470 if (loops != 1000 && loops != tno)
1471 continue;
1472 ExecType et = tests[i].et;
1473 AbortOption ao = tests[i].ao;
1474
1475 printf("%.3d : ", tno);
1476 print(op1);
1477 print(op2);
1478 switch(et){
1479 case Commit: printf("c "); break;
1480 case NoCommit: printf("nc "); break;
1481 }
1482 switch(ao){
1483 case AbortOnError: printf("aoe "); break;
1484 case AO_IgnoreError: printf("ie "); break;
1485 }
1486 printf(": ");
1487
1488
1489 hugoTrans.loadTable(pNdb, 1);
1490 pTrans = pNdb->startTransaction();
1491 op_row(pTrans, hugoOps, pTab, op1, 0);
1492 ret = pTrans->execute(et, ao);
1493 pTrans->close();
1494 printf("%d ", ret);
1495 hugoTrans.clearTable(pNdb);
1496
1497 hugoTrans.loadTable(pNdb, 1);
1498 pTrans = pNdb->startTransaction();
1499 op_row(pTrans, hugoOps, pTab, op1, 1);
1500 ret = pTrans->execute(et, ao);
1501 pTrans->close();
1502 printf("%d ", ret);
1503 hugoTrans.clearTable(pNdb);
1504
1505 hugoTrans.loadTable(pNdb, 1);
1506 pTrans = pNdb->startTransaction();
1507 op_row(pTrans, hugoOps, pTab, op1, 0);
1508 op_row(pTrans, hugoOps, pTab, op2, 1);
1509 ret = pTrans->execute(et, ao);
1510 pTrans->close();
1511 printf("%d\n", ret);
1512 hugoTrans.clearTable(pNdb);
1513
1514 hugoTrans.clearTable(pNdb);
1515 }
1516 }
1517 }
1518 return NDBT_OK;
1519 }
1520
1521 static void
testExecuteAsynchCallback(int res,NdbTransaction * con,void * data_ptr)1522 testExecuteAsynchCallback(int res, NdbTransaction *con, void *data_ptr)
1523 {
1524 int *res_ptr= (int *)data_ptr;
1525
1526 *res_ptr= res;
1527 }
1528
runTestExecuteAsynch(NDBT_Context * ctx,NDBT_Step * step)1529 int runTestExecuteAsynch(NDBT_Context* ctx, NDBT_Step* step){
1530 /* Test that NdbTransaction::executeAsynch() works (BUG#27495). */
1531 int result = NDBT_OK;
1532 const NdbDictionary::Table* pTab = ctx->getTab();
1533
1534 Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
1535 if (pNdb == NULL){
1536 ndbout << "pNdb == NULL" << endl;
1537 return NDBT_FAILED;
1538 }
1539 if (pNdb->init(2048)){
1540 ERR(pNdb->getNdbError());
1541 delete pNdb;
1542 return NDBT_FAILED;
1543 }
1544
1545 NdbConnection* pCon = pNdb->startTransaction();
1546 if (pCon == NULL){
1547 ERR(pNdb->getNdbError());
1548 delete pNdb;
1549 return NDBT_FAILED;
1550 }
1551
1552 NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName());
1553 if (pOp == NULL){
1554 ERR(pOp->getNdbError());
1555 pNdb->closeTransaction(pCon);
1556 delete pNdb;
1557 return NDBT_FAILED;
1558 }
1559
1560 if (pOp->readTuples() != 0){
1561 ERR(pOp->getNdbError());
1562 pNdb->closeTransaction(pCon);
1563 delete pNdb;
1564 return NDBT_FAILED;
1565 }
1566
1567 if (pOp->getValue(NdbDictionary::Column::FRAGMENT) == 0){
1568 ERR(pOp->getNdbError());
1569 pNdb->closeTransaction(pCon);
1570 delete pNdb;
1571 return NDBT_FAILED;
1572 }
1573 int res= 42;
1574 pCon->executeAsynch(NoCommit, testExecuteAsynchCallback, &res);
1575 while(pNdb->pollNdb(100000) == 0)
1576 ;
1577 if (res != 0){
1578 ERR(pCon->getNdbError());
1579 ndbout << "Error returned from execute: " << res << endl;
1580 result= NDBT_FAILED;
1581 }
1582
1583 pNdb->closeTransaction(pCon);
1584
1585 delete pNdb;
1586
1587 return result;
1588 }
1589
1590 template class Vector<NdbScanOperation*>;
1591
1592 int
runBug28443(NDBT_Context * ctx,NDBT_Step * step)1593 runBug28443(NDBT_Context* ctx, NDBT_Step* step)
1594 {
1595 int result = NDBT_OK;
1596 int records = ctx->getNumRecords();
1597
1598 NdbRestarter restarter;
1599
1600 restarter.insertErrorInAllNodes(9003);
1601
1602 for (Uint32 i = 0; i<ctx->getNumLoops(); i++)
1603 {
1604 HugoTransactions hugoTrans(*ctx->getTab());
1605 if (hugoTrans.loadTable(GETNDB(step), records, 2048) != 0)
1606 {
1607 result = NDBT_FAILED;
1608 goto done;
1609 }
1610 if (runClearTable(ctx, step) != 0)
1611 {
1612 result = NDBT_FAILED;
1613 goto done;
1614 }
1615 }
1616
1617 done:
1618 restarter.insertErrorInAllNodes(9003);
1619
1620 return result;
1621 }
1622
1623 NDBT_TESTSUITE(testNdbApi);
1624 TESTCASE("MaxNdb",
1625 "Create Ndb objects until no more can be created\n"){
1626 INITIALIZER(runTestMaxNdb);
1627 }
1628 TESTCASE("MaxTransactions",
1629 "Start transactions until no more can be created\n"){
1630 INITIALIZER(runTestMaxTransaction);
1631 }
1632 TESTCASE("MaxOperations",
1633 "Get operations until no more can be created\n"){
1634 INITIALIZER(runLoadTable);
1635 INITIALIZER(runTestMaxOperations);
1636 FINALIZER(runClearTable);
1637 }
1638 TESTCASE("MaxGetValue",
1639 "Call getValue loads of time\n"){
1640 INITIALIZER(runLoadTable);
1641 INITIALIZER(runTestGetValue);
1642 FINALIZER(runClearTable);
1643 }
1644 TESTCASE("MaxEqual",
1645 "Call equal loads of time\n"){
1646 INITIALIZER(runTestEqual);
1647 }
1648 TESTCASE("DeleteNdb",
1649 "Make sure that a deleted Ndb object is properly deleted\n"
1650 "and removed from transporter\n"){
1651 INITIALIZER(runLoadTable);
1652 INITIALIZER(runTestDeleteNdb);
1653 FINALIZER(runClearTable);
1654 }
1655 TESTCASE("WaitUntilReady",
1656 "Make sure you get an error message when calling waitUntilReady\n"
1657 "without an init'ed Ndb\n"){
1658 INITIALIZER(runTestWaitUntilReady);
1659 }
1660 TESTCASE("GetOperationNoTab",
1661 "Call getNdbOperation on a table that does not exist\n"){
1662 INITIALIZER(runGetNdbOperationNoTab);
1663 }
1664 TESTCASE("MissingOperation",
1665 "Missing operation request(insertTuple) should give an error code\n"){
1666 INITIALIZER(runMissingOperation);
1667 }
1668 TESTCASE("GetValueInUpdate",
1669 "Test that it's not possible to perform getValue in an update\n"){
1670 INITIALIZER(runLoadTable);
1671 INITIALIZER(runGetValueInUpdate);
1672 FINALIZER(runClearTable);
1673 }
1674 TESTCASE("UpdateWithoutKeys",
1675 "Test that it's not possible to perform update without setting\n"
1676 "PKs"){
1677 INITIALIZER(runLoadTable);
1678 INITIALIZER(runUpdateWithoutKeys);
1679 FINALIZER(runClearTable);
1680 }
1681 TESTCASE("UpdateWithoutValues",
1682 "Test that it's not possible to perform update without setValues\n"){
1683 INITIALIZER(runLoadTable);
1684 INITIALIZER(runUpdateWithoutValues);
1685 FINALIZER(runClearTable);
1686 }
1687 TESTCASE("NdbErrorOperation",
1688 "Test that NdbErrorOperation is properly set"){
1689 INITIALIZER(runCheckGetNdbErrorOperation);
1690 }
1691 TESTCASE("ReadWithoutGetValue",
1692 "Test that it's possible to perform read wo/ getvalue's\n"){
1693 INITIALIZER(runLoadTable);
1694 INITIALIZER(runReadWithoutGetValue);
1695 FINALIZER(runClearTable);
1696 }
1697 TESTCASE("Bug_11133",
1698 "Test ReadEx-Delete-Write\n"){
1699 INITIALIZER(runBug_11133);
1700 FINALIZER(runClearTable);
1701 }
1702 TESTCASE("Bug_WritePartialIgnoreError",
1703 "Test WritePartialIgnoreError\n"){
1704 INITIALIZER(runBug_WritePartialIgnoreError);
1705 FINALIZER(runClearTable);
1706 }
1707 TESTCASE("Scan_4006",
1708 "Check that getNdbScanOperation does not get 4006\n"){
1709 INITIALIZER(runLoadTable);
1710 INITIALIZER(runScan_4006);
1711 FINALIZER(runClearTable);
1712 }
1713 TESTCASE("IgnoreError", ""){
1714 INITIALIZER(createPkIndex);
1715 STEP(runTestIgnoreError);
1716 FINALIZER(runClearTable);
1717 FINALIZER(createPkIndex_Drop);
1718 }
1719 TESTCASE("ExecuteAsynch",
1720 "Check that executeAsync() works (BUG#27495)\n"){
1721 INITIALIZER(runTestExecuteAsynch);
1722 }
1723 TESTCASE("Bug28443",
1724 ""){
1725 INITIALIZER(runBug28443);
1726 }
1727 NDBT_TESTSUITE_END(testNdbApi);
1728
main(int argc,const char ** argv)1729 int main(int argc, const char** argv){
1730 ndb_init();
1731 // TABLE("T1");
1732 return testNdbApi.execute(argc, argv);
1733 }
1734
1735 template class Vector<Ndb*>;
1736 template class Vector<NdbConnection*>;
1737