19 #include "NDBT_Test.hpp"
20 #include "NDBT_ReturnCodes.h"
21 #include "HugoTransactions.hpp"
22 #include "UtilTransactions.hpp"
23 #include <NdbRestarter.hpp>
49 {
"ReadRead",
true,
"READ", 0, 0,
"READ", 0, 0, 0, 0 },
50 {
"ReadReadEx",
true,
"READ", 0, 0,
"READ-EX", 0, 0, 0, 0 },
51 {
"ReadSimpleRead",
true,
"READ", 0, 0,
"S-READ", 0, 0, 0, 0 },
52 {
"ReadDirtyRead",
true,
"READ", 0, 0,
"D-READ", 0, 0, 0, 0 },
53 {
"ReadInsert",
true,
"READ", 0, 0,
"INSERT", 630, 1, 0, 0 },
54 {
"ReadUpdate",
true,
"READ", 0, 0,
"UPDATE", 0, 1, 0, 1 },
55 {
"ReadDelete",
true,
"READ", 0, 0,
"DELETE", 0, 0, 626, 0 },
57 {
"FReadRead",
false,
"READ", 626, 0,
"READ", 626, 0, 626, 0 },
58 {
"FReadReadEx",
false,
"READ", 626, 0,
"READ-EX", 626, 0, 626, 0 },
59 {
"FReadSimpleRead",
false,
"READ", 626, 0,
"S-READ", 626, 0, 626, 0 },
60 {
"FReadDirtyRead",
false,
"READ", 626, 0,
"D-READ", 626, 0, 626, 0 },
61 {
"FReadInsert",
false,
"READ", 626, 0,
"INSERT", 0, 1, 0, 1 },
62 {
"FReadUpdate",
false,
"READ", 626, 0,
"UPDATE", 626, 0, 626, 0 },
63 {
"FReadDelete",
false,
"READ", 626, 0,
"DELETE", 626, 0, 626, 0 },
65 {
"FSimpleReadRead",
false,
"S-READ", 626, 0,
"READ", 626, 0, 626, 0 },
66 {
"FSimpleReadReadEx",
67 false,
"S-READ", 626, 0,
"READ-EX", 626, 0, 626, 0 },
68 {
"FSimpleReadSimpleRead",
69 false,
"S-READ", 626, 0,
"S-READ", 626, 0, 626, 0 },
70 {
"FSimpleReadDirtyRead",
71 false,
"S-READ", 626, 0,
"D-READ", 626, 0, 626, 0 },
72 {
"FSimpleReadInsert",
73 false,
"S-READ", 626, 0,
"INSERT", 0, 1, 0, 1 },
74 {
"FSimpleReadUpdate",
75 false,
"S-READ", 626, 0,
"UPDATE", 626, 0, 626, 0 },
76 {
"FSimpleReadDelete",
77 false,
"S-READ", 626, 0,
"DELETE", 626, 0, 626, 0 },
79 {
"ReadExRead",
true,
"READ-EX", 0, 0,
"READ", 0, 0, 0, 0 },
80 {
"ReadExReadEx",
true,
"READ-EX", 0, 0,
"READ-EX", 0, 0, 0, 0 },
81 {
"ReadExSimpleRead",
true,
"READ-EX", 0, 0,
"S-READ", 0, 0, 0, 0 },
82 {
"ReadExDirtyRead",
true,
"READ-EX", 0, 0,
"D-READ", 0, 0, 0, 0 },
83 {
"ReadExInsert",
true,
"READ-EX", 0, 0,
"INSERT", 630, 1, 0, 0 },
84 {
"ReadExUpdate",
true,
"READ-EX", 0, 0,
"UPDATE", 0, 1, 0, 1 },
85 {
"ReadExDelete",
true,
"READ-EX", 0, 0,
"DELETE", 0, 0, 626, 0 },
87 {
"InsertRead",
false,
"INSERT", 0, 0,
"READ", 0, 0, 0, 0 },
88 {
"InsertReadEx",
false,
"INSERT", 0, 0,
"READ-EX", 0, 0, 0, 0 },
89 {
"InsertSimpleRead",
false,
"INSERT", 0, 0,
"S-READ", 0, 0, 0, 0 },
90 {
"InsertDirtyRead",
false,
"INSERT", 0, 0,
"D-READ", 0, 0, 0, 0 },
91 {
"InsertInsert",
false,
"INSERT", 0, 0,
"INSERT", 630, 0, 626, 0 },
92 {
"InsertUpdate",
false,
"INSERT", 0, 0,
"UPDATE", 0, 1, 0, 1 },
93 {
"InsertDelete",
false,
"INSERT", 0, 0,
"DELETE", 0, 0, 626, 0 },
95 {
"UpdateRead",
true,
"UPDATE", 0, 1,
"READ", 0, 1, 0, 1 },
96 {
"UpdateReadEx",
true,
"UPDATE", 0, 1,
"READ-EX", 0, 1, 0, 1 },
97 {
"UpdateSimpleRead",
true,
"UPDATE", 0, 1,
"S-READ", 0, 1, 0, 1 },
98 {
"UpdateDirtyRead",
true,
"UPDATE", 0, 1,
"D-READ", 0, 1, 0, 1 },
99 {
"UpdateInsert",
true,
"UPDATE", 0, 1,
"INSERT", 630, 0, 0, 0 },
100 {
"UpdateUpdate",
true,
"UPDATE", 0, 1,
"UPDATE", 0, 2, 0, 2 },
101 {
"UpdateDelete",
true,
"UPDATE", 0, 1,
"DELETE", 0, 0, 626, 0 },
103 {
"DeleteRead",
true,
"DELETE", 0, 0,
"READ", 626, 0, 0, 0 },
104 {
"DeleteReadEx",
true,
"DELETE", 0, 0,
"READ-EX", 626, 0, 0, 0 },
105 {
"DeleteSimpleRead",
true,
"DELETE", 0, 0,
"S-READ", 626, 0, 0, 0 },
106 {
"DeleteDirtyRead",
true,
"DELETE", 0, 0,
"D-READ", 626, 0, 626, 0 },
107 {
"DeleteInsert",
true,
"DELETE", 0, 0,
"INSERT", 0, 1, 0, 1 },
108 {
"DeleteUpdate",
true,
"DELETE", 0, 0,
"UPDATE", 626, 1, 0, 0 },
109 {
"DeleteDelete",
true,
"DELETE", 0, 0,
"DELETE", 626, 0, 0, 0 }
112 #define CHECK(b) if (!(b)) { \
113 g_err << "ERR: "<< step->getName() \
114 << " failed on line " << __LINE__ << endl; \
115 result = NDBT_FAILED; \
118 #define C3(b) if (!(b)) { \
119 g_err << "ERR: failed on line " << __LINE__ << endl; \
120 return NDBT_FAILED; }
128 #define C2(x, y) { int r = (x); int s = (y); if(r != s) {\
129 g_err << "ERR: failed on line " << __LINE__ << ": " \
130 << r << " != " << s << endl; \
131 return NDBT_FAILED; }}
133 if(strcmp(op,
"READ") == 0){
135 }
else if(strcmp(op,
"READ-EX") == 0){
137 }
else if(strcmp(op,
"S-READ") == 0){
139 }
else if(strcmp(op,
"D-READ") == 0){
141 }
else if(strcmp(op,
"INSERT") == 0){
142 C2(hugoOps.pkInsertRecord(pNdb, 1, 1, value), 0);
143 }
else if(strcmp(op,
"UPDATE") == 0){
144 C2(hugoOps.pkUpdateRecord(pNdb, 1, 1, value), 0);
145 }
else if(strcmp(op,
"DELETE") == 0){
146 C2(hugoOps.pkDeleteRecord(pNdb, 1, 1), 0);
148 g_err << __FILE__ <<
" - " << __LINE__
149 <<
": Unknown operation" << op << endl;
164 if(strcmp(op,
"READ") == 0){
165 }
else if(strcmp(op,
"READ-EX") == 0){
166 }
else if(strcmp(op,
"S-READ") == 0){
167 }
else if(strcmp(op,
"D-READ") == 0){
172 return hugoOps.verifyUpdatesValue(value);
177 int result = NDBT_OK;
179 Ndb* pNdb = GETNDB(step);
181 const char * op1 = ctx->getProperty(
"op1",
"NONE");
182 const int val1 = ctx->getProperty(
"val1", ~0);
183 const int res1 = ctx->getProperty(
"res1", ~0);
184 const char * op2 = ctx->getProperty(
"op2",
"NONE");
185 const int res2 = ctx->getProperty(
"res2", ~0);
186 const int val2 = ctx->getProperty(
"val2", ~0);
188 const int res3 = ctx->getProperty(
"res3", ~0);
189 const int val3 = ctx->getProperty(
"val3", ~0);
193 CHECK(hugoOps.startTransaction(pNdb) == 0);
194 CHECK(runOp(hugoOps, pNdb, op1, val1) == 0);
195 AbortOption oa = (res1 == 0) ? AbortOnError : AO_IgnoreError;
196 CHECK(hugoOps.execute_NoCommit(pNdb, oa) == res1);
197 CHECK(checkVal(hugoOps, op1, val1, res1) == 0);
199 ndbout_c(
"-- running op 2");
201 CHECK(runOp(hugoOps, pNdb, op2, val2) == 0);
202 CHECK(hugoOps.execute_Commit(pNdb) == res2);
203 CHECK(checkVal(hugoOps, op2, val2, res2) == 0);
206 hugoOps.closeTransaction(pNdb);
208 if(result != NDBT_OK)
212 CHECK(hugoOps.startTransaction(pNdb) == 0);
213 CHECK(runOp(hugoOps, pNdb,
"READ", 0) == 0);
214 CHECK(hugoOps.execute_Commit(pNdb) == res3);
215 CHECK(checkVal(hugoOps,
"READ", val3, res3) == 0);
217 hugoOps.closeTransaction(pNdb);
224 int result = NDBT_OK;
226 Ndb* pNdb = GETNDB(step);
230 CHECK(hugoOps.startTransaction(pNdb) == 0);
231 CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
232 CHECK(hugoOps.execute_Commit(pNdb) == 0);
236 hugoOps.closeTransaction(pNdb);
243 int records = ctx->getNumRecords();
246 if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){
252 r.dumpStateAllNodes(&lcp, 1);
257 enum OPS { o_DONE= 0, o_INS= 1, o_UPD= 2, o_DEL= 3 };
262 valid(
const Sequence& s)
267 for(
size_t i = 1;
i<s.size();
i++)
288 NdbOut& operator<<(NdbOut& out,
const Sequence& s)
291 for(
size_t i = 0; i<s.size(); i++)
314 generate(Sequence& out,
int no)
318 out.push_back((OPS)(no & 3));
335 for(
int i = 0; i<max; i++)
340 if(tmp.size() >= len && valid(tmp))
352 static const Uint32 DUMMY = 0;
353 static const Uint32 ROW = 1;
357 Ndb* pNdb,
int seq, OPS latest,
bool initial_row,
bool commit)
360 ctx->getProperty(
"NoWait", (Uint32)1);
362 for(
size_t j = no_wait; j<3; j++)
365 C3(other.startTransaction(pNdb) == 0);
367 int tmp= other.execute_Commit(pNdb);
371 C3(initial_row? tmp==0 && other.verifyUpdatesValue(0) == 0 : tmp==626);
383 C3(tmp == 0 && other.verifyUpdatesValue(seq) == 0);
395 C3(initial_row? tmp==0 && other.verifyUpdatesValue(0) == 0 : tmp==626);
404 Ndb* pNdb,
int seq, OPS latest,
405 Uint64 transactionId)
407 bool initial_row= (seq == 0) && latest == o_INS;
409 for(
size_t j = 0; j<3; j++)
414 C3(same.startTransaction(pNdb) == 0);
415 same.setTransactionId(transactionId);
420 for(
size_t l = 1; l<=(size_t)seq; l++)
422 C3(same.pkReadRecord(pNdb, DUMMY, 1, lm) == 0);
423 C3(same.execute_NoCommit(pNdb) == 0);
424 g_info <<
"savepoint: " << l << endl;
427 g_info <<
"op(" << seq <<
"): "
428 <<
" lock mode " << lm << endl;
430 C3(same.pkReadRecord(pNdb, ROW, 1, lm) == 0);
431 int tmp= same.execute_Commit(pNdb);
436 C3(tmp == 0 && same.verifyUpdatesValue(0) == 0);
447 C3(tmp == 0 && same.verifyUpdatesValue(seq) == 0);
463 Ndb* pNdb = GETNDB(step);
465 Uint32 seqNo = ctx->getProperty(
"Sequence", (Uint32)0);
466 Uint32 commit= ctx->getProperty(
"Commit", (Uint32)1);
474 generate(seq, seqNo);
479 C3(hugoOps.startTransaction(pNdb) == 0);
480 C3(hugoOps.pkInsertRecord(pNdb, DUMMY, 1, 0) == 0);
481 C3(hugoOps.execute_Commit(pNdb) == 0);
484 const bool initial_row= (seq[0] != o_INS);
488 C3(hugoOps.startTransaction(pNdb) == 0);
489 C3(hugoOps.pkInsertRecord(pNdb, ROW, 1, 0) == 0);
490 C3(hugoOps.execute_Commit(pNdb) == 0);
494 C3(trans1.startTransaction(pNdb) == 0);
495 for(
size_t i = 0; i<seq.size(); i++)
502 C3(trans1.pkInsertRecord(pNdb, ROW, 1, i+1) == 0);
505 C3(trans1.pkUpdateRecord(pNdb, ROW, 1, i+1) == 0);
508 C3(trans1.pkDeleteRecord(pNdb, ROW, 1) == 0);
513 C3(trans1.execute_NoCommit(pNdb) == 0);
518 if(verify_other(ctx, pNdb, 0, seq[0], initial_row, commit) != NDBT_OK)
524 Uint64 transactionId= trans1.getTransaction()->getTransactionId();
526 for(
size_t k=0; k<=i+1; k++)
528 if(verify_savepoint(ctx, pNdb, k,
529 k>0 ? seq[k-1] : initial_row ? o_INS : o_DONE,
530 transactionId) != NDBT_OK)
537 C3(trans1.execute_Commit(pNdb) == 0);
541 C3(trans1.execute_Rollback(pNdb) == 0);
544 if(verify_other(ctx, pNdb, seq.size(), seq.back(),
545 initial_row, commit) != NDBT_OK)
555 Ndb* pNdb = GETNDB(step);
559 if(hugoTrans.loadTable(pNdb, 1) != 0){
560 g_err <<
"Load table failed" << endl;
567 CHECK(hugoOps.startTransaction(pNdb) == 0);
568 if(ctx->getProperty(
"LOCK_UPGRADE", 1) == 1)
571 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
573 ctx->setProperty(
"READ_DONE", 1);
576 ctx->getPropertyWait(
"READ_DONE", 2);
577 ndbout_c(
"wait 2 - done");
581 ctx->setProperty(
"READ_DONE", 1);
583 ctx->getPropertyWait(
"READ_DONE", 2);
584 ndbout_c(
"wait 2 - done");
586 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
588 if(ctx->getProperty(
"LU_OP", o_INS) == o_INS)
590 CHECK(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
591 CHECK(hugoOps.pkInsertRecord(pNdb, 0, 1, 2) == 0);
593 else if(ctx->getProperty(
"LU_OP", o_UPD) == o_UPD)
595 CHECK(hugoOps.pkUpdateRecord(pNdb, 0, 1, 2) == 0);
599 CHECK(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
601 ctx->setProperty(
"READ_DONE", 3);
603 ndbout_c(
"before update");
604 ndbout_c(
"wait update");
605 CHECK(hugoOps.execute_Commit(pNdb) == 0);
606 CHECK(hugoOps.closeTransaction(pNdb) == 0);
608 CHECK(hugoOps.startTransaction(pNdb) == 0);
609 CHECK(hugoOps.pkReadRecord(pNdb, 0, 1) == 0);
610 int res= hugoOps.execute_Commit(pNdb);
611 if(ctx->getProperty(
"LU_OP", o_INS) == o_INS)
614 CHECK(hugoOps.verifyUpdatesValue(2) == 0);
616 else if(ctx->getProperty(
"LU_OP", o_UPD) == o_UPD)
619 CHECK(hugoOps.verifyUpdatesValue(2) == 0);
635 Ndb* pNdb = GETNDB(step);
643 CHECK(hugoOps.startTransaction(pNdb) == 0);
645 ctx->getPropertyWait(
"READ_DONE", 1);
646 ndbout_c(
"wait 1 - done");
648 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
649 ctx->setProperty(
"READ_DONE", 2);
652 ctx->getPropertyWait(
"READ_DONE", 3);
653 ndbout_c(
"wait 3 - done");
655 NdbSleep_MilliSleep(200);
656 if(ctx->getProperty(
"LU_COMMIT", (Uint32)0) == 0)
658 CHECK(hugoOps.execute_Commit(pNdb) == 0);
662 CHECK(hugoOps.execute_Rollback(pNdb) == 0);
670 main(
int argc,
const char** argv){
678 ts.setTemporaryTables(
true);
680 for(Uint32 i = 0; i < 12; i++)
682 if(
false && (i == 6 || i == 8 || i == 10))
686 name.appfmt(
"_%d", i);
690 pt->setProperty(
"LOCK_UPGRADE", 1 + (i & 1));
691 pt->setProperty(
"LU_OP", 1 + ((i >> 1) % 3));
692 pt->setProperty(
"LU_COMMIT", i / 6);
713 for(
size_t i = 0; i<tmp.size(); i++)
718 for(
size_t j = 0; j<s.size(); j++){
741 pt->setProperty(
"Sequence", tmp[i]);
758 pt->setProperty(
"Sequence", tmp[i]);
759 pt->setProperty(
"Commit", (Uint32)0);
775 for(Uint32 i = 0; i<
sizeof(matrix)/
sizeof(matrix[0]); i++){
782 if(matrix[i].preCond){
788 pt->setProperty(
"op1", matrix[i].op1);
789 pt->setProperty(
"res1", matrix[i].res1);
790 pt->setProperty(
"val1", matrix[i].val1);
792 pt->setProperty(
"op2", matrix[i].op2);
793 pt->setProperty(
"res2", matrix[i].res2);
794 pt->setProperty(
"val2", matrix[i].val2);
796 pt->setProperty(
"res3", matrix[i].res3);
797 pt->setProperty(
"val3", matrix[i].val3);
809 return ts.execute(argc, argv);