1 /*
2    Copyright (c) 2003, 2010, 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 <HugoTransactions.hpp>
28 #include <UtilTransactions.hpp>
29 #include <random.h>
30 #include <NdbConfig.hpp>
31 #include <signaldata/DumpStateOrd.hpp>
32 
33 #define TIMEOUT (Uint32)3000
34 Uint32 g_org_timeout = 3000;
35 Uint32 g_org_deadlock = 3000;
36 
37 int
setTransactionTimeout(NDBT_Context * ctx,NDBT_Step * step)38 setTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){
39   NdbRestarter restarter;
40   int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT);
41 
42   NdbConfig conf(GETNDB(step)->getNodeId()+1);
43   unsigned int nodeId = conf.getMasterNodeId();
44   if (!conf.getProperty(nodeId,
45 			NODE_TYPE_DB,
46 			CFG_DB_TRANSACTION_INACTIVE_TIMEOUT,
47 			&g_org_timeout)){
48     return NDBT_FAILED;
49   }
50 
51   int val[] = { DumpStateOrd::TcSetApplTransactionTimeout, timeout };
52   if(restarter.dumpStateAllNodes(val, 2) != 0){
53     return NDBT_FAILED;
54   }
55 
56   return NDBT_OK;
57 }
58 
59 int
resetTransactionTimeout(NDBT_Context * ctx,NDBT_Step * step)60 resetTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){
61   NdbRestarter restarter;
62 
63   int val[] = { DumpStateOrd::TcSetApplTransactionTimeout, g_org_timeout };
64   if(restarter.dumpStateAllNodes(val, 2) != 0){
65     return NDBT_FAILED;
66   }
67 
68   return NDBT_OK;
69 }
70 
71 int
setDeadlockTimeout(NDBT_Context * ctx,NDBT_Step * step)72 setDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
73   NdbRestarter restarter;
74   int timeout = ctx->getProperty("TransactionDeadlockTimeout", TIMEOUT);
75 
76   NdbConfig conf(GETNDB(step)->getNodeId()+1);
77   unsigned int nodeId = conf.getMasterNodeId();
78   if (!conf.getProperty(nodeId,
79 			NODE_TYPE_DB,
80 			CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
81 			&g_org_deadlock))
82     return NDBT_FAILED;
83 
84   g_err << "Setting timeout: " << timeout << endl;
85   int val[] = { DumpStateOrd::TcSetTransactionTimeout, timeout };
86   if(restarter.dumpStateAllNodes(val, 2) != 0){
87     return NDBT_FAILED;
88   }
89 
90   return NDBT_OK;
91 }
92 
93 int
getDeadlockTimeout(NDBT_Context * ctx,NDBT_Step * step)94 getDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
95   NdbRestarter restarter;
96 
97   Uint32 val = 0;
98   NdbConfig conf(GETNDB(step)->getNodeId()+1);
99   unsigned int nodeId = conf.getMasterNodeId();
100   if (!conf.getProperty(nodeId,
101 			NODE_TYPE_DB,
102 			CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
103 			&val))
104     return NDBT_FAILED;
105 
106   if (val < 120000)
107     val = 120000;
108   ctx->setProperty("TransactionDeadlockTimeout", 4*val);
109 
110   return NDBT_OK;
111 }
112 
113 int
resetDeadlockTimeout(NDBT_Context * ctx,NDBT_Step * step)114 resetDeadlockTimeout(NDBT_Context* ctx, NDBT_Step* step){
115   NdbRestarter restarter;
116 
117   int val[] = { DumpStateOrd::TcSetTransactionTimeout, g_org_deadlock };
118   if(restarter.dumpStateAllNodes(val, 2) != 0){
119     return NDBT_FAILED;
120   }
121 
122   return NDBT_OK;
123 }
124 
125 
runLoadTable(NDBT_Context * ctx,NDBT_Step * step)126 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
127 
128   int records = ctx->getNumRecords();
129   HugoTransactions hugoTrans(*ctx->getTab());
130   if (hugoTrans.loadTable(GETNDB(step), records) != 0){
131     return NDBT_FAILED;
132   }
133   return NDBT_OK;
134 }
135 
runClearTable(NDBT_Context * ctx,NDBT_Step * step)136 int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
137   int records = ctx->getNumRecords();
138 
139   UtilTransactions utilTrans(*ctx->getTab());
140   if (utilTrans.clearTable2(GETNDB(step),  records) != 0){
141     return NDBT_FAILED;
142   }
143   return NDBT_OK;
144 }
145 
146 
147 #define CHECK(b) if (!(b)) { \
148   ndbout << "ERR: "<< step->getName() \
149          << " failed on line " << __LINE__ << endl; \
150   result = NDBT_FAILED; \
151   break; }
152 
runTimeoutTrans2(NDBT_Context * ctx,NDBT_Step * step)153 int runTimeoutTrans2(NDBT_Context* ctx, NDBT_Step* step){
154   int result = NDBT_OK;
155   int loops = ctx->getNumLoops();
156   int stepNo = step->getStepNo();
157   int mul1 = ctx->getProperty("Op1", (Uint32)0);
158   int mul2 = ctx->getProperty("Op2", (Uint32)0);
159   int records = ctx->getNumRecords();
160 
161   int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT);
162 
163   int minSleep = (int)(timeout * 1.5);
164   int maxSleep = timeout * 2;
165 
166   HugoOperations hugoOps(*ctx->getTab());
167   Ndb* pNdb = GETNDB(step);
168 
169   for (int l = 0; l<loops && !ctx->isTestStopped() && result == NDBT_OK; l++){
170 
171     int op1 = 0 + (l + stepNo) * mul1;
172     int op2 = 0 + (l + stepNo) * mul2;
173 
174     op1 = (op1 % 5);
175     op2 = (op2 % 5);
176 
177     ndbout << stepNo << ": TransactionInactiveTimeout="<< timeout
178 	   << ", minSleep="<<minSleep
179 	   << ", maxSleep="<<maxSleep
180 	   << ", op1=" << op1
181 	   << ", op2=" << op2 << endl;;
182 
183     do{
184       // Commit transaction
185       CHECK(hugoOps.startTransaction(pNdb) == 0);
186 
187       switch(op1){
188       case 0:
189 	break;
190       case 1:
191 	if(hugoOps.pkReadRecord(pNdb, stepNo) != 0){
192 	  g_err << stepNo << ": Fail" << __LINE__ << endl;
193 	  result = NDBT_FAILED; break;
194 	}
195 	break;
196       case 2:
197 	if(hugoOps.pkUpdateRecord(pNdb, stepNo) != 0){
198 	  g_err << stepNo << ": Fail" << __LINE__ << endl;
199 	  result = NDBT_FAILED; break;
200 	}
201 	break;
202       case 3:
203 	if(hugoOps.pkDeleteRecord(pNdb, stepNo) != 0){
204 	  g_err << stepNo << ": Fail" << __LINE__ << endl;
205 	  result = NDBT_FAILED; break;
206 	}
207 	break;
208       case 4:
209 	if(hugoOps.pkInsertRecord(pNdb, stepNo+records+l) != 0){
210 	  g_err << stepNo << ": Fail" << __LINE__ << endl;
211 	  result = NDBT_FAILED; break;
212 	}
213 	break;
214       }
215 
216       if(result != NDBT_OK)
217 	break;
218 
219       int res = hugoOps.execute_NoCommit(pNdb);
220       if(res != 0){
221 	g_err << stepNo << ": Fail" << __LINE__ << endl;
222 	result = NDBT_FAILED; break;
223       }
224 
225       int sleep = minSleep + myRandom48(maxSleep-minSleep);
226       ndbout << stepNo << ": Sleeping for "<< sleep << " milliseconds" << endl;
227       NdbSleep_MilliSleep(sleep);
228 
229       switch(op2){
230       case 0:
231 	break;
232       case 1:
233 	if(hugoOps.pkReadRecord(pNdb, stepNo) != 0){
234 	  g_err << stepNo << ": Fail" << __LINE__ << endl;
235 	  result = NDBT_FAILED; break;
236 	}
237 	break;
238       case 2:
239 	if(hugoOps.pkUpdateRecord(pNdb, stepNo) != 0){
240 	  g_err << stepNo << ": Fail" << __LINE__ << endl;
241 	  result = NDBT_FAILED; break;
242 	}
243 	break;
244       case 3:
245 	if(hugoOps.pkDeleteRecord(pNdb, stepNo) != 0){
246 	  g_err << stepNo << ": Fail" << __LINE__ << endl;
247 	  result = NDBT_FAILED; break;
248 	}
249 	break;
250       case 4:
251 	if(hugoOps.pkInsertRecord(pNdb, stepNo+2*records+l) != 0){
252 	  g_err << stepNo << ": Fail" << __LINE__ << endl;
253 	  result = NDBT_FAILED; break;
254 	}
255 	break;
256       }
257 
258       // Expect that transaction has timed-out
259       res = hugoOps.execute_Commit(pNdb);
260       if(op1 != 0 && res != 266){
261 	g_err << stepNo << ": Fail: " << res << "!= 237, op1="
262 	      << op1 << ", op2=" << op2 << endl;
263 	result = NDBT_FAILED; break;
264       }
265 
266     } while(false);
267 
268     hugoOps.closeTransaction(pNdb);
269   }
270 
271   return result;
272 }
273 
runDontTimeoutTrans(NDBT_Context * ctx,NDBT_Step * step)274 int runDontTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){
275   int result = NDBT_OK;
276   int loops = ctx->getNumLoops();
277   int stepNo = step->getStepNo();
278 
279   int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT);
280 
281   int maxSleep = (int)(timeout * 0.5);
282   ndbout << "TransactionInactiveTimeout="<< timeout
283 	 << ", maxSleep="<<maxSleep<<endl;
284 
285 
286   HugoOperations hugoOps(*ctx->getTab());
287   Ndb* pNdb = GETNDB(step);
288 
289   for (int l = 0; l < loops && result == NDBT_OK; l++){
290 
291     do{
292       // Commit transaction
293       CHECK(hugoOps.startTransaction(pNdb) == 0);
294       CHECK(hugoOps.pkReadRecord(pNdb, stepNo) == 0);
295       CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
296 
297       int sleep = myRandom48(maxSleep);
298       ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
299       NdbSleep_MilliSleep(sleep);
300 
301       // Expect that transaction has NOT timed-out
302       CHECK(hugoOps.execute_Commit(pNdb) == 0);
303 
304     } while(false);
305 
306     hugoOps.closeTransaction(pNdb);
307   }
308 
309   return result;
310 }
311 
runDeadlockTimeoutTrans(NDBT_Context * ctx,NDBT_Step * step)312 int runDeadlockTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){
313   int result = NDBT_OK;
314   int loops = ctx->getNumLoops();
315   int stepNo = step->getStepNo();
316 
317   Uint32 deadlock_timeout;
318   NdbConfig conf(GETNDB(step)->getNodeId()+1);
319   unsigned int nodeId = conf.getMasterNodeId();
320   if (!conf.getProperty(nodeId,
321                         NODE_TYPE_DB,
322                         CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT,
323                         &deadlock_timeout)){
324     return NDBT_FAILED;
325   }
326 
327 
328   int do_sleep = (int)(deadlock_timeout * 0.5);
329 
330 
331   HugoOperations hugoOps(*ctx->getTab());
332   Ndb* pNdb = GETNDB(step);
333 
334   for (int l = 0; l < loops && result == NDBT_OK; l++){
335 
336     do{
337       // Commit transaction
338       CHECK(hugoOps.startTransaction(pNdb) == 0);
339       CHECK(hugoOps.pkReadRecord(pNdb, stepNo) == 0);
340       CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
341 
342       int sleep = int(deadlock_timeout * 1.5 + myRandom48(do_sleep));
343       ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
344       NdbSleep_MilliSleep(sleep);
345 
346       // Expect that transaction has NOT timed-out
347       CHECK(hugoOps.execute_Commit(pNdb) == 0);
348 
349     } while(false);
350 
351     hugoOps.closeTransaction(pNdb);
352   }
353 
354   return result;
355 }
356 
runBuddyTransNoTimeout(NDBT_Context * ctx,NDBT_Step * step)357 int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){
358   int result = NDBT_OK;
359   int loops = ctx->getNumLoops();
360   int records = ctx->getNumRecords();
361   int stepNo = step->getStepNo();
362   int maxSleep = (int)(TIMEOUT * 0.3);
363   ndbout << "TransactionInactiveTimeout="<< TIMEOUT
364 	 << ", maxSleep="<<maxSleep<<endl;
365 
366   HugoOperations hugoOps(*ctx->getTab());
367   Ndb* pNdb = GETNDB(step);
368 
369   for (int l = 1; l < loops && result == NDBT_OK; l++){
370 
371     do{
372       // Start an insert trans
373       CHECK(hugoOps.startTransaction(pNdb) == 0);
374       int recordNo = records + (stepNo*loops) + l;
375       CHECK(hugoOps.pkInsertRecord(pNdb, recordNo) == 0);
376       CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
377 
378       int remain = maxSleep;
379       for (int i = 0; i < 3; i++)
380       {
381         NdbTransaction* pTrans = hugoOps.getTransaction();
382 
383         // Perform buddy scan reads
384         NdbScanOperation* pOp = pTrans->getNdbScanOperation(ctx->getTab());
385         CHECK(pOp != 0);
386         CHECK(pOp->readTuples(NdbOperation::LM_Read, 0, 0, 1) == 0);
387         CHECK(pTrans->execute(NoCommit) == 0);
388         while(pOp->nextResult() == 0);
389 
390         int sleep = myRandom48(remain);
391         remain = remain - sleep + 1;
392         ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
393         NdbSleep_MilliSleep(sleep);
394       }
395 
396       // Expect that transaction has NOT timed-out
397       CHECK(hugoOps.execute_Commit(pNdb) == 0);
398 
399     } while(false);
400 
401     hugoOps.closeTransaction(pNdb);
402   }
403 
404   return result;
405 }
406 
runBuddyTransTimeout(NDBT_Context * ctx,NDBT_Step * step)407 int runBuddyTransTimeout(NDBT_Context* ctx, NDBT_Step* step){
408   int result = NDBT_OK;
409   int loops = ctx->getNumLoops();
410   //int records = ctx->getNumRecords();
411   //int stepNo = step->getStepNo();
412   ndbout << "TransactionInactiveTimeout="<< TIMEOUT <<endl;
413 
414   HugoOperations hugoOps(*ctx->getTab());
415   Ndb* pNdb = GETNDB(step);
416 
417   for (int l = 1; l < loops && result == NDBT_OK; l++){
418 
419     NdbTransaction* pTrans = 0;
420     do{
421       pTrans = pNdb->startTransaction();
422       NdbScanOperation* pOp = pTrans->getNdbScanOperation(ctx->getTab());
423       CHECK(pOp->readTuples(NdbOperation::LM_Read, 0, 0, 1) == 0);
424       CHECK(pTrans->execute(NoCommit) == 0);
425 
426       int sleep = 2 * TIMEOUT;
427       ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
428       NdbSleep_MilliSleep(sleep);
429 
430       int res = 0;
431       while((res = pOp->nextResult()) == 0);
432       ndbout_c("res: %d", res);
433       CHECK(res == -1);
434 
435     } while(false);
436 
437     if (pTrans)
438     {
439       pTrans->close();
440     }
441   }
442 
443   return result;
444 }
445 
runScanRefreshNoTimeout(NDBT_Context * ctx,NDBT_Step * step)446 int runScanRefreshNoTimeout(NDBT_Context* ctx, NDBT_Step* step){
447   int result = NDBT_OK;
448   int loops = ctx->getNumLoops();
449   int records = ctx->getNumRecords();
450   int stepNo = step->getStepNo();
451   int maxSleep = (int)(TIMEOUT * 0.3);
452   ndbout << "TransactionInactiveTimeout="<< TIMEOUT
453 	 << ", maxSleep="<<maxSleep<<endl;
454 
455   HugoOperations hugoOps(*ctx->getTab());
456   Ndb* pNdb = GETNDB(step);
457 
458   for (int l = 1; l < loops && result == NDBT_OK; l++){
459 
460     do{
461       // Start an insert trans
462       CHECK(hugoOps.startTransaction(pNdb) == 0);
463       int recordNo = records + (stepNo*loops) + l;
464       CHECK(hugoOps.pkInsertRecord(pNdb, recordNo) == 0);
465       CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
466 
467       for (int i = 0; i < 3; i++)
468       {
469         NdbTransaction* pTrans = hugoOps.getTransaction();
470 
471         Vector<NdbScanOperation*> ops;
472         for (int j = 0; j <= i; j++)
473         {
474           // Perform buddy scan reads
475           NdbScanOperation* pOp = pTrans->getNdbScanOperation(ctx->getTab());
476           CHECK(pOp != 0);
477           CHECK(pOp->readTuples(NdbOperation::LM_Read, 0, 0, 1) == 0);
478           ops.push_back(pOp);
479         }
480         CHECK(pTrans->execute(NoCommit) == 0);
481 
482         for (unsigned i = 0; i<TIMEOUT; i += 1000)
483         {
484           pTrans->refresh();
485           NdbSleep_MilliSleep(1000);
486         }
487 
488         int res;
489         for (size_t j = 0; j < ops.size(); j++)
490         {
491           while((res = ops[j]->nextResult()) == 0);
492           CHECK(res != -1);
493         }
494       }
495 
496       // Expect that transaction has NOT timed-out
497       CHECK(hugoOps.execute_Commit(pNdb) == 0);
498 
499     } while(false);
500 
501     hugoOps.closeTransaction(pNdb);
502   }
503 
504   return result;
505 }
506 
507 int
runError4012(NDBT_Context * ctx,NDBT_Step * step)508 runError4012(NDBT_Context* ctx, NDBT_Step* step){
509   int result = NDBT_OK;
510   //int loops = ctx->getNumLoops();
511   //int stepNo = step->getStepNo();
512 
513   int timeout = ctx->getProperty("TransactionDeadlockTimeout", TIMEOUT);
514 
515   HugoOperations hugoOps(*ctx->getTab());
516   Ndb* pNdb = GETNDB(step);
517 
518   do{
519     // Commit transaction
520     CHECK(hugoOps.startTransaction(pNdb) == 0);
521     CHECK(hugoOps.pkUpdateRecord(pNdb, 0) == 0);
522     int ret = hugoOps.execute_NoCommit(pNdb);
523     if (ret == 0)
524     {
525       int sleep = timeout;
526       ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
527       NdbSleep_MilliSleep(sleep);
528 
529       // Expect that transaction has NOT timed-out
530       CHECK(hugoOps.execute_Commit(pNdb) == 0);
531     }
532     else
533     {
534       CHECK(ret == 4012);
535     }
536   } while(false);
537 
538   hugoOps.closeTransaction(pNdb);
539 
540   return result;
541 }
542 
543 
544 NDBT_TESTSUITE(testTimeout);
545 TESTCASE("DontTimeoutTransaction",
546 	 "Test that the transaction does not timeout "\
547 	 "if we sleep during the transaction. Use a sleep "\
548 	 "value which is smaller than TransactionInactiveTimeout"){
549   INITIALIZER(runLoadTable);
550   INITIALIZER(setTransactionTimeout);
551   STEPS(runDontTimeoutTrans, 1);
552   FINALIZER(resetTransactionTimeout);
553   FINALIZER(runClearTable);
554 }
555 TESTCASE("Bug11290",
556          "Setting TransactionInactiveTimeout to 0(zero) "\
557          "should result in infinite timeout, and not as "\
558          "was the bug, a timeout that is equal to the deadlock timeout"){
559   TC_PROPERTY("TransactionInactiveTimeout",(Uint32)0);
560   INITIALIZER(runLoadTable);
561   INITIALIZER(setTransactionTimeout);
562   STEPS(runDeadlockTimeoutTrans, 1);
563   FINALIZER(resetTransactionTimeout);
564   FINALIZER(runClearTable);
565 }
566 TESTCASE("DontTimeoutTransaction5",
567 	 "Test that the transaction does not timeout "\
568 	 "if we sleep during the transaction. Use a sleep "\
569 	 "value which is smaller than TransactionInactiveTimeout" \
570 	 "Five simultaneous threads"){
571   INITIALIZER(runLoadTable);
572   INITIALIZER(setTransactionTimeout);
573   STEPS(runDontTimeoutTrans, 5);
574   FINALIZER(resetTransactionTimeout);
575   FINALIZER(runClearTable);
576 }
577 TESTCASE("TimeoutRandTransaction",
578 	 "Test that the transaction does timeout "\
579 	 "if we sleep during the transaction. Use a sleep "\
580 	 "value which is larger than TransactionInactiveTimeout"){
581   INITIALIZER(runLoadTable);
582   INITIALIZER(setTransactionTimeout);
583   TC_PROPERTY("Op1", 7);
584   TC_PROPERTY("Op2", 11);
585   STEPS(runTimeoutTrans2, 5);
586   FINALIZER(resetTransactionTimeout);
587   FINALIZER(runClearTable);
588 }
589 TESTCASE("BuddyTransNoTimeout",
590 	 "Start a transaction and perform an insert with NoCommit. " \
591 	 "Start a buddy transaction wich performs long running scans " \
592 	 "and sleeps. " \
593 	 "The total sleep time is longer than TransactionInactiveTimeout" \
594 	 "Commit the first transaction, it should not have timed out."){
595   INITIALIZER(runLoadTable);
596   INITIALIZER(setTransactionTimeout);
597   STEPS(runBuddyTransNoTimeout, 1);
598   FINALIZER(resetTransactionTimeout);
599   FINALIZER(runClearTable);
600 }
601 TESTCASE("BuddyTransNoTimeout5",
602 	 "Start a transaction and perform an insert with NoCommit. " \
603 	 "Start a buddy transaction wich performs long running scans " \
604 	 "and sleeps. " \
605 	 "The total sleep time is longer than TransactionInactiveTimeout" \
606 	 "Commit the first transaction, it should not have timed out." \
607 	 "Five simultaneous threads"){
608   INITIALIZER(runLoadTable);
609   INITIALIZER(setTransactionTimeout);
610   STEPS(runBuddyTransNoTimeout, 5);
611   FINALIZER(resetTransactionTimeout);
612   FINALIZER(runClearTable);
613 }
614 TESTCASE("BuddyTransTimeout1",
615 	 "Start a scan and check that it gets aborted"){
616   INITIALIZER(runLoadTable);
617   INITIALIZER(setTransactionTimeout);
618   STEPS(runBuddyTransTimeout, 1);
619   FINALIZER(resetTransactionTimeout);
620   FINALIZER(runClearTable);
621 }
622 TESTCASE("ScanRefreshNoTimeout",
623 	 "")
624 {
625   INITIALIZER(runLoadTable);
626   INITIALIZER(setTransactionTimeout);
627   STEPS(runScanRefreshNoTimeout, 1);
628   FINALIZER(resetTransactionTimeout);
629   FINALIZER(runClearTable);
630 }
631 #if 0
632 TESTCASE("Error4012", ""){
633   TC_PROPERTY("TransactionDeadlockTimeout", 120000);
634   INITIALIZER(runLoadTable);
635   INITIALIZER(getDeadlockTimeout);
636   INITIALIZER(setDeadlockTimeout);
637   STEPS(runError4012, 2);
638   FINALIZER(runClearTable);
639 }
640 #endif
641 NDBT_TESTSUITE_END(testTimeout);
642 
main(int argc,const char ** argv)643 int main(int argc, const char** argv){
644   ndb_init();
645   myRandom48Init((long)NdbTick_CurrentMillisecond());
646   NDBT_TESTSUITE_INSTANCE(testTimeout);
647   return testTimeout.execute(argc, argv);
648 }
649 
650 template class Vector<NdbScanOperation*>;
651