mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / ndb / test / ndbapi / testTimeout.cpp
blobfeb2e780d7e56b7f6c2403cf152b4503aab429ce
1 /* Copyright (c) 2003-2006 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include <NDBT.hpp>
17 #include <NDBT_Test.hpp>
18 #include <HugoTransactions.hpp>
19 #include <UtilTransactions.hpp>
20 #include <random.h>
21 #include <NdbConfig.hpp>
22 #include <signaldata/DumpStateOrd.hpp>
24 #define TIMEOUT (Uint32)3000
25 Uint32 g_org_timeout = 3000;
26 Uint32 g_org_deadlock = 3000;
28 int
29 setTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){
30 NdbRestarter restarter;
31 int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT);
33 NdbConfig conf(GETNDB(step)->getNodeId()+1);
34 unsigned int nodeId = conf.getMasterNodeId();
35 if (!conf.getProperty(nodeId,
36 NODE_TYPE_DB,
37 CFG_DB_TRANSACTION_INACTIVE_TIMEOUT,
38 &g_org_timeout)){
39 return NDBT_FAILED;
42 int val[] = { DumpStateOrd::TcSetApplTransactionTimeout, timeout };
43 if(restarter.dumpStateAllNodes(val, 2) != 0){
44 return NDBT_FAILED;
47 return NDBT_OK;
50 int
51 resetTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){
52 NdbRestarter restarter;
54 int val[] = { DumpStateOrd::TcSetApplTransactionTimeout, g_org_timeout };
55 if(restarter.dumpStateAllNodes(val, 2) != 0){
56 return NDBT_FAILED;
59 return NDBT_OK;
62 int
63 setDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
64 NdbRestarter restarter;
65 int timeout = ctx->getProperty("TransactionDeadlockTimeout", TIMEOUT);
67 NdbConfig conf(GETNDB(step)->getNodeId()+1);
68 unsigned int nodeId = conf.getMasterNodeId();
69 if (!conf.getProperty(nodeId,
70 NODE_TYPE_DB,
71 CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
72 &g_org_deadlock))
73 return NDBT_FAILED;
75 g_err << "Setting timeout: " << timeout << endl;
76 int val[] = { DumpStateOrd::TcSetTransactionTimeout, timeout };
77 if(restarter.dumpStateAllNodes(val, 2) != 0){
78 return NDBT_FAILED;
81 return NDBT_OK;
84 int
85 getDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
86 NdbRestarter restarter;
88 Uint32 val = 0;
89 NdbConfig conf(GETNDB(step)->getNodeId()+1);
90 unsigned int nodeId = conf.getMasterNodeId();
91 if (!conf.getProperty(nodeId,
92 NODE_TYPE_DB,
93 CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
94 &val))
95 return NDBT_FAILED;
97 if (val < 120000)
98 val = 120000;
99 ctx->setProperty("TransactionDeadlockTimeout", 4*val);
101 return NDBT_OK;
105 resetDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
106 NdbRestarter restarter;
108 int val[] = { DumpStateOrd::TcSetTransactionTimeout, g_org_deadlock };
109 if(restarter.dumpStateAllNodes(val, 2) != 0){
110 return NDBT_FAILED;
113 return NDBT_OK;
117 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
119 int records = ctx->getNumRecords();
120 HugoTransactions hugoTrans(*ctx->getTab());
121 if (hugoTrans.loadTable(GETNDB(step), records) != 0){
122 return NDBT_FAILED;
124 return NDBT_OK;
127 int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
128 int records = ctx->getNumRecords();
130 UtilTransactions utilTrans(*ctx->getTab());
131 if (utilTrans.clearTable2(GETNDB(step), records) != 0){
132 return NDBT_FAILED;
134 return NDBT_OK;
138 #define CHECK(b) if (!(b)) { \
139 ndbout << "ERR: "<< step->getName() \
140 << " failed on line " << __LINE__ << endl; \
141 result = NDBT_FAILED; \
142 break; }
144 int runTimeoutTrans2(NDBT_Context* ctx, NDBT_Step* step){
145 int result = NDBT_OK;
146 int loops = ctx->getNumLoops();
147 int stepNo = step->getStepNo();
148 int mul1 = ctx->getProperty("Op1", (Uint32)0);
149 int mul2 = ctx->getProperty("Op2", (Uint32)0);
150 int records = ctx->getNumRecords();
152 int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT);
154 int minSleep = (int)(timeout * 1.5);
155 int maxSleep = timeout * 2;
157 HugoOperations hugoOps(*ctx->getTab());
158 Ndb* pNdb = GETNDB(step);
160 for (int l = 0; l<loops && !ctx->isTestStopped() && result == NDBT_OK; l++){
162 int op1 = 0 + (l + stepNo) * mul1;
163 int op2 = 0 + (l + stepNo) * mul2;
165 op1 = (op1 % 5);
166 op2 = (op2 % 5);
168 ndbout << stepNo << ": TransactionInactiveTimeout="<< timeout
169 << ", minSleep="<<minSleep
170 << ", maxSleep="<<maxSleep
171 << ", op1=" << op1
172 << ", op2=" << op2 << endl;;
175 // Commit transaction
176 CHECK(hugoOps.startTransaction(pNdb) == 0);
178 switch(op1){
179 case 0:
180 break;
181 case 1:
182 if(hugoOps.pkReadRecord(pNdb, stepNo) != 0){
183 g_err << stepNo << ": Fail" << __LINE__ << endl;
184 result = NDBT_FAILED; break;
186 break;
187 case 2:
188 if(hugoOps.pkUpdateRecord(pNdb, stepNo) != 0){
189 g_err << stepNo << ": Fail" << __LINE__ << endl;
190 result = NDBT_FAILED; break;
192 break;
193 case 3:
194 if(hugoOps.pkDeleteRecord(pNdb, stepNo) != 0){
195 g_err << stepNo << ": Fail" << __LINE__ << endl;
196 result = NDBT_FAILED; break;
198 break;
199 case 4:
200 if(hugoOps.pkInsertRecord(pNdb, stepNo+records+l) != 0){
201 g_err << stepNo << ": Fail" << __LINE__ << endl;
202 result = NDBT_FAILED; break;
204 break;
207 if(result != NDBT_OK)
208 break;
210 int res = hugoOps.execute_NoCommit(pNdb);
211 if(res != 0){
212 g_err << stepNo << ": Fail" << __LINE__ << endl;
213 result = NDBT_FAILED; break;
216 int sleep = minSleep + myRandom48(maxSleep-minSleep);
217 ndbout << stepNo << ": Sleeping for "<< sleep << " milliseconds" << endl;
218 NdbSleep_MilliSleep(sleep);
220 switch(op2){
221 case 0:
222 break;
223 case 1:
224 if(hugoOps.pkReadRecord(pNdb, stepNo) != 0){
225 g_err << stepNo << ": Fail" << __LINE__ << endl;
226 result = NDBT_FAILED; break;
228 break;
229 case 2:
230 if(hugoOps.pkUpdateRecord(pNdb, stepNo) != 0){
231 g_err << stepNo << ": Fail" << __LINE__ << endl;
232 result = NDBT_FAILED; break;
234 break;
235 case 3:
236 if(hugoOps.pkDeleteRecord(pNdb, stepNo) != 0){
237 g_err << stepNo << ": Fail" << __LINE__ << endl;
238 result = NDBT_FAILED; break;
240 break;
241 case 4:
242 if(hugoOps.pkInsertRecord(pNdb, stepNo+2*records+l) != 0){
243 g_err << stepNo << ": Fail" << __LINE__ << endl;
244 result = NDBT_FAILED; break;
246 break;
249 // Expect that transaction has timed-out
250 res = hugoOps.execute_Commit(pNdb);
251 if(op1 != 0 && res != 266){
252 g_err << stepNo << ": Fail: " << res << "!= 237, op1="
253 << op1 << ", op2=" << op2 << endl;
254 result = NDBT_FAILED; break;
257 } while(false);
259 hugoOps.closeTransaction(pNdb);
262 return result;
265 int runDontTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){
266 int result = NDBT_OK;
267 int loops = ctx->getNumLoops();
268 int stepNo = step->getStepNo();
270 int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT);
272 int maxSleep = (int)(timeout * 0.5);
273 ndbout << "TransactionInactiveTimeout="<< timeout
274 << ", maxSleep="<<maxSleep<<endl;
277 HugoOperations hugoOps(*ctx->getTab());
278 Ndb* pNdb = GETNDB(step);
280 for (int l = 0; l < loops && result == NDBT_OK; l++){
283 // Commit transaction
284 CHECK(hugoOps.startTransaction(pNdb) == 0);
285 CHECK(hugoOps.pkReadRecord(pNdb, stepNo) == 0);
286 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
288 int sleep = myRandom48(maxSleep);
289 ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
290 NdbSleep_MilliSleep(sleep);
292 // Expect that transaction has NOT timed-out
293 CHECK(hugoOps.execute_Commit(pNdb) == 0);
295 } while(false);
297 hugoOps.closeTransaction(pNdb);
300 return result;
303 int runDeadlockTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){
304 int result = NDBT_OK;
305 int loops = ctx->getNumLoops();
306 int stepNo = step->getStepNo();
308 Uint32 deadlock_timeout;
309 NdbConfig conf(GETNDB(step)->getNodeId()+1);
310 unsigned int nodeId = conf.getMasterNodeId();
311 if (!conf.getProperty(nodeId,
312 NODE_TYPE_DB,
313 CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
314 &deadlock_timeout)){
315 return NDBT_FAILED;
319 int do_sleep = (int)(deadlock_timeout * 0.5);
322 HugoOperations hugoOps(*ctx->getTab());
323 Ndb* pNdb = GETNDB(step);
325 for (int l = 0; l < loops && result == NDBT_OK; l++){
328 // Commit transaction
329 CHECK(hugoOps.startTransaction(pNdb) == 0);
330 CHECK(hugoOps.pkReadRecord(pNdb, stepNo) == 0);
331 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
333 int sleep = deadlock_timeout * 1.5 + myRandom48(do_sleep);
334 ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
335 NdbSleep_MilliSleep(sleep);
337 // Expect that transaction has NOT timed-out
338 CHECK(hugoOps.execute_Commit(pNdb) == 0);
340 } while(false);
342 hugoOps.closeTransaction(pNdb);
345 return result;
348 int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){
349 int result = NDBT_OK;
350 int loops = ctx->getNumLoops();
351 int records = ctx->getNumRecords();
352 int stepNo = step->getStepNo();
353 int maxSleep = (int)(TIMEOUT * 0.3);
354 ndbout << "TransactionInactiveTimeout="<< TIMEOUT
355 << ", maxSleep="<<maxSleep<<endl;
357 HugoOperations hugoOps(*ctx->getTab());
358 Ndb* pNdb = GETNDB(step);
360 for (int l = 1; l < loops && result == NDBT_OK; l++){
363 // Start an insert trans
364 CHECK(hugoOps.startTransaction(pNdb) == 0);
365 int recordNo = records + (stepNo*loops) + l;
366 CHECK(hugoOps.pkInsertRecord(pNdb, recordNo) == 0);
367 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
369 for (int i = 0; i < 3; i++){
370 // Perform buddy scan reads
371 CHECK((hugoOps.scanReadRecords(pNdb)) == 0);
372 CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
374 int sleep = myRandom48(maxSleep);
375 ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
376 NdbSleep_MilliSleep(sleep);
379 // Expect that transaction has NOT timed-out
380 CHECK(hugoOps.execute_Commit(pNdb) == 0);
382 } while(false);
384 hugoOps.closeTransaction(pNdb);
387 return result;
390 int runBuddyTransTimeout(NDBT_Context* ctx, NDBT_Step* step){
391 int result = NDBT_OK;
392 int loops = ctx->getNumLoops();
393 int records = ctx->getNumRecords();
394 int stepNo = step->getStepNo();
395 ndbout << "TransactionInactiveTimeout="<< TIMEOUT <<endl;
397 HugoOperations hugoOps(*ctx->getTab());
398 Ndb* pNdb = GETNDB(step);
400 for (int l = 1; l < loops && result == NDBT_OK; l++){
402 NdbTransaction* pTrans = 0;
404 pTrans = pNdb->startTransaction();
405 NdbScanOperation* pOp = pTrans->getNdbScanOperation(ctx->getTab());
406 CHECK(pOp->readTuples(NdbOperation::LM_Read, 0, 0, 1) == 0);
407 CHECK(pTrans->execute(NoCommit) == 0);
409 int sleep = 2 * TIMEOUT;
410 ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
411 NdbSleep_MilliSleep(sleep);
413 int res = 0;
414 while((res = pOp->nextResult()) == 0);
415 ndbout_c("res: %d", res);
416 CHECK(res == -1);
418 } while(false);
420 if (pTrans)
422 pTrans->close();
426 return result;
429 int
430 runError4012(NDBT_Context* ctx, NDBT_Step* step){
431 int result = NDBT_OK;
432 int loops = ctx->getNumLoops();
433 int stepNo = step->getStepNo();
435 int timeout = ctx->getProperty("TransactionDeadlockTimeout", TIMEOUT);
437 HugoOperations hugoOps(*ctx->getTab());
438 Ndb* pNdb = GETNDB(step);
441 // Commit transaction
442 CHECK(hugoOps.startTransaction(pNdb) == 0);
443 CHECK(hugoOps.pkUpdateRecord(pNdb, 0) == 0);
444 int ret = hugoOps.execute_NoCommit(pNdb);
445 if (ret == 0)
447 int sleep = timeout;
448 ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
449 NdbSleep_MilliSleep(sleep);
451 // Expect that transaction has NOT timed-out
452 CHECK(hugoOps.execute_Commit(pNdb) == 0);
454 else
456 CHECK(ret == 4012);
458 } while(false);
460 hugoOps.closeTransaction(pNdb);
462 return result;
466 NDBT_TESTSUITE(testTimeout);
467 TESTCASE("DontTimeoutTransaction",
468 "Test that the transaction does not timeout "\
469 "if we sleep during the transaction. Use a sleep "\
470 "value which is smaller than TransactionInactiveTimeout"){
471 INITIALIZER(runLoadTable);
472 INITIALIZER(setTransactionTimeout);
473 STEPS(runDontTimeoutTrans, 1);
474 FINALIZER(resetTransactionTimeout);
475 FINALIZER(runClearTable);
477 TESTCASE("Bug11290",
478 "Setting TransactionInactiveTimeout to 0(zero) "\
479 "should result in infinite timeout, and not as "\
480 "was the bug, a timeout that is equal to the deadlock timeout"){
481 TC_PROPERTY("TransactionInactiveTimeout",(Uint32)0);
482 INITIALIZER(runLoadTable);
483 INITIALIZER(setTransactionTimeout);
484 STEPS(runDeadlockTimeoutTrans, 1);
485 FINALIZER(resetTransactionTimeout);
486 FINALIZER(runClearTable);
488 TESTCASE("DontTimeoutTransaction5",
489 "Test that the transaction does not timeout "\
490 "if we sleep during the transaction. Use a sleep "\
491 "value which is smaller than TransactionInactiveTimeout" \
492 "Five simultaneous threads"){
493 INITIALIZER(runLoadTable);
494 INITIALIZER(setTransactionTimeout);
495 STEPS(runDontTimeoutTrans, 5);
496 FINALIZER(resetTransactionTimeout);
497 FINALIZER(runClearTable);
499 TESTCASE("TimeoutRandTransaction",
500 "Test that the transaction does timeout "\
501 "if we sleep during the transaction. Use a sleep "\
502 "value which is larger than TransactionInactiveTimeout"){
503 INITIALIZER(runLoadTable);
504 INITIALIZER(setTransactionTimeout);
505 TC_PROPERTY("Op1", 7);
506 TC_PROPERTY("Op2", 11);
507 STEPS(runTimeoutTrans2, 5);
508 FINALIZER(resetTransactionTimeout);
509 FINALIZER(runClearTable);
511 TESTCASE("BuddyTransNoTimeout",
512 "Start a transaction and perform an insert with NoCommit. " \
513 "Start a buddy transaction wich performs long running scans " \
514 "and sleeps. " \
515 "The total sleep time is longer than TransactionInactiveTimeout" \
516 "Commit the first transaction, it should not have timed out."){
517 INITIALIZER(runLoadTable);
518 INITIALIZER(setTransactionTimeout);
519 STEPS(runBuddyTransNoTimeout, 1);
520 FINALIZER(resetTransactionTimeout);
521 FINALIZER(runClearTable);
523 TESTCASE("BuddyTransNoTimeout5",
524 "Start a transaction and perform an insert with NoCommit. " \
525 "Start a buddy transaction wich performs long running scans " \
526 "and sleeps. " \
527 "The total sleep time is longer than TransactionInactiveTimeout" \
528 "Commit the first transaction, it should not have timed out." \
529 "Five simultaneous threads"){
530 INITIALIZER(runLoadTable);
531 INITIALIZER(setTransactionTimeout);
532 STEPS(runBuddyTransNoTimeout, 5);
533 FINALIZER(resetTransactionTimeout);
534 FINALIZER(runClearTable);
536 TESTCASE("BuddyTransTimeout1",
537 "Start a scan and check that it gets aborted"){
538 INITIALIZER(runLoadTable);
539 INITIALIZER(setTransactionTimeout);
540 STEPS(runBuddyTransTimeout, 1);
541 FINALIZER(resetTransactionTimeout);
542 FINALIZER(runClearTable);
544 #if 0
545 TESTCASE("Error4012", ""){
546 TC_PROPERTY("TransactionDeadlockTimeout", 120000);
547 INITIALIZER(runLoadTable);
548 INITIALIZER(getDeadlockTimeout);
549 INITIALIZER(setDeadlockTimeout);
550 STEPS(runError4012, 2);
551 FINALIZER(runClearTable);
553 #endif
554 NDBT_TESTSUITE_END(testTimeout);
556 int main(int argc, const char** argv){
557 ndb_init();
558 myRandom48Init(NdbTick_CurrentMillisecond());
559 return testTimeout.execute(argc, argv);