22 #include <UtilTransactions.hpp>
35 if (m_initialized ==
true)
38 myRandom48Init((
long)NdbTick_CurrentMillisecond());
43 ndbout <<
"Ndb not ready" << endl;
47 if (getNumAccounts() != NDBT_OK)
54 int Bank::performTransactions(
int maxSleepBetweenTrans,
int yield){
58 while(performTransaction() == NDBT_OK)
62 if (maxSleepBetweenTrans > 0){
63 int val = myRandom48(maxSleepBetweenTrans);
64 NdbSleep_MilliSleep(val);
67 if((transactions % 100) == 0)
68 g_info << transactions << endl;
70 if (yield != 0 && transactions >= yield)
78 int Bank::performTransaction(){
81 if (m_maxAccount <= 0){
82 g_err <<
"No accounts in bank" << endl;
86 int fromAccount = myRandom48(m_maxAccount);
87 int toAccount = myRandom48(m_maxAccount);
89 if (fromAccount == toAccount){
91 toAccount = (toAccount+1)%m_maxAccount;
94 int maxAmount = getMaxAmount();
96 int amount = myRandom48(maxAmount);
99 int res = performTransaction(fromAccount, toAccount, amount);
103 g_err <<
"performTransaction returned NDBT_FAILED" << endl
104 <<
" fromAccount = " << fromAccount << endl
105 <<
" toAccount = " << toAccount << endl
106 <<
" amount = " << amount << endl;
107 result = NDBT_FAILED;
109 case NOT_ENOUGH_FUNDS:
113 g_err <<
"TEMPORARY_ERRROR retrying" << endl;
114 NdbSleep_MilliSleep(50);
115 goto retry_transaction;
118 g_info <<
"performTransaction returned "<<res << endl;
132 int Bank::performTransaction(
int fromAccountId,
153 return performTransactionImpl1(fromAccountId, toAccountId, amount);
157 int Bank::performTransactionImpl1(
int fromAccountId,
165 int result = NDBT_OK;
166 if ((result= getNextTransactionId(transId)) != NDBT_OK){
172 if( pTrans == NULL ) {
176 return NDBT_TEMPORARY;
183 if (prepareGetCurrTimeOp(pTrans, currTime) != NDBT_OK){
206 check = pOp->
equal(
"ACCOUNT_ID", fromAccountId);
214 if( balanceFromRec ==NULL ) {
221 if( fromAccountTypeRec == NULL ) {
244 check = pOp6->
equal(
"ACCOUNT_ID", toAccountId);
252 if( balanceToRec == NULL ) {
259 if( toAccountTypeRec == NULL ) {
265 check = pTrans->
execute(NoCommit);
271 return NDBT_TEMPORARY;
278 Uint32 balanceFrom = balanceFromRec->
u_32_value();
281 if (((Int64)balanceFrom - amount) < 0){
284 return NOT_ENOUGH_FUNDS;
287 Uint32 fromAccountType = fromAccountTypeRec->
u_32_value();
289 Uint32 balanceTo = balanceToRec->
u_32_value();
291 Uint32 toAccountType = toAccountTypeRec->
u_32_value();
310 check = pOp2->
equal(
"ACCOUNT_ID", fromAccountId);
317 check = pOp2->
setValue(
"BALANCE", balanceFrom - amount);
341 check = pOp3->
equal(
"ACCOUNT_ID", toAccountId);
348 check = pOp3->
setValue(
"BALANCE", balanceTo + amount);
372 check = pOp4->
equal(
"TRANSACTION_ID", transId);
379 check = pOp4->
equal(
"ACCOUNT", fromAccountId);
386 check = pOp4->
setValue(
"ACCOUNT_TYPE", fromAccountType);
393 check = pOp4->
setValue(
"OTHER_ACCOUNT", toAccountId);
400 check = pOp4->
setValue(
"TRANSACTION_TYPE", WithDrawal);
407 check = pOp4->
setValue(
"TIME", currTime);
414 check = pOp4->
setValue(
"AMOUNT", amount);
438 check = pOp5->
equal(
"TRANSACTION_ID", transId);
445 check = pOp5->
equal(
"ACCOUNT", toAccountId);
452 check = pOp5->
setValue(
"ACCOUNT_TYPE", toAccountType);
459 check = pOp5->
setValue(
"OTHER_ACCOUNT", fromAccountId);
466 check = pOp5->
setValue(
"TRANSACTION_TYPE", Deposit);
473 check = pOp5->
setValue(
"TIME", currTime);
480 check = pOp5->
setValue(
"AMOUNT", amount);
487 check = pTrans->
execute(Commit);
493 return NDBT_TEMPORARY;
509 int counter, maxCounter;
510 int yieldCounter = 0;
516 maxCounter = 50 + myRandom48(100);
522 result = performValidateGLs();
523 if (result != NDBT_OK){
524 if (result == VERIFICATION_FAILED){
525 g_err <<
"performValidateGLs verification failed" << endl;
528 g_info <<
"performValidateGLs failed: " << result << endl;
533 result = performValidatePurged();
534 if (result != NDBT_OK){
535 if (result == VERIFICATION_FAILED){
536 g_err <<
"performValidatePurged verification failed" << endl;
539 g_info <<
"performValidatePurged failed" << endl;
546 if (yield != 0 && yieldCounter >= yield)
554 if (findLastGL(lastGLTime) != NDBT_OK){
555 g_info <<
"findLastGL failed" << endl;
567 if (getCurrTime(currTime) != NDBT_OK){
568 g_info <<
"getCurrTime failed" << endl;
572 if (lastGLTime < currTime){
574 if (performMakeGL(lastGLTime) != NDBT_OK){
575 g_info <<
"performMakeGL failed" << endl;
580 if (counter > maxCounter){
583 g_info <<
"counter("<<counter<<
") > maxCounter("<<maxCounter<<
")" << endl;
591 NdbSleep_SecSleep(1);
596 if (purgeOldGLTransactions(currTime, age) != NDBT_OK){
597 g_info <<
"purgeOldGLTransactions failed" << endl;
619 result = performValidateGLs(age);
620 if (result != NDBT_OK){
621 if (result == VERIFICATION_FAILED){
622 g_err <<
"performValidateGLs verification failed" << endl;
625 g_err <<
"performValidateGLs failed: " << result << endl;
633 result = performValidatePurged();
634 if (result != NDBT_OK){
635 if (result == VERIFICATION_FAILED){
636 g_err <<
"performValidatePurged verification failed" << endl;
639 g_err <<
"performValidatePurged failed" << endl;
649 int Bank::findLastGL(Uint64 &lastTime){
656 if (pScanTrans == NULL) {
675 if( timeRec ==NULL ) {
681 check = pScanTrans->
execute(NoCommit);
714 int Bank::performMakeGL(Uint64 time){
715 g_info <<
"performMakeGL: " << time << endl;
726 for (
int i = 0;
i < getNumAccountTypes();
i++){
728 if (performMakeGLForAccountType(pTrans, time,
i) != NDBT_OK){
729 g_err <<
"performMakeGLForAccountType returned NDBT_FAILED"<<endl;
735 if( pTrans->
execute(Commit) == -1 ) {
747 Uint32 accountTypeId){
751 Uint32 withdrawalCount = 0;
752 Uint32 withdrawalSum = 0;
753 Uint32 depositSum = 0;
754 Uint32 depositCount = 0;
755 Uint32 countTransactions = 0;
774 check = pOp->
equal(
"TIME", glTime);
780 check = pOp->
equal(
"ACCOUNT_TYPE", accountTypeId);
786 check = pOp->
setValue(
"BALANCE", balance);
792 check = pOp->
setValue(
"DEPOSIT_COUNT", depositCount);
798 check = pOp->
setValue(
"DEPOSIT_SUM", depositSum);
804 check = pOp->
setValue(
"WITHDRAWAL_COUNT", withdrawalCount);
810 check = pOp->
setValue(
"WITHDRAWAL_SUM", withdrawalSum);
816 check = pOp->
setValue(
"PURGED", purged);
822 check = pTrans->
execute(NoCommit);
841 check = pOp2->
equal(
"TIME", glTime-1);
847 check = pOp2->
equal(
"ACCOUNT_TYPE", accountTypeId);
854 if( oldBalanceRec == NULL ) {
859 check = pTrans->
execute(NoCommit);
865 Uint32 oldBalance = oldBalanceRec->
u_32_value();
867 balance = oldBalance;
873 if (sumTransactionsForGL(glTime,
905 check = pOp3->
equal(
"TIME", glTime);
911 check = pOp3->
equal(
"ACCOUNT_TYPE", accountTypeId);
917 check = pOp3->
setValue(
"BALANCE", balance);
923 check = pOp3->
setValue(
"DEPOSIT_COUNT", depositCount);
929 check = pOp3->
setValue(
"DEPOSIT_SUM", depositSum);
935 check = pOp3->
setValue(
"WITHDRAWAL_COUNT", withdrawalCount);
941 check = pOp3->
setValue(
"WITHDRAWAL_SUM", withdrawalSum);
947 check = pOp3->
setValue(
"PURGED", purged);
954 check = pTrans->
execute(NoCommit);
966 int Bank::sumTransactionsForGL(
const Uint64 glTime,
967 const Uint32 accountType,
969 Uint32& withdrawalCount,
970 Uint32& withdrawalSum,
972 Uint32& depositCount,
973 Uint32& transactionsCount,
980 if (pScanTrans == NULL) {
992 if( pOp->readTuplesExclusive()) {
999 if( accountTypeRec ==NULL ) {
1006 if( timeRec ==NULL ) {
1013 if( transTypeRec ==NULL ) {
1020 if( amountRec ==NULL ) {
1026 check = pScanTrans->
execute(NoCommit);
1043 if (a == accountType && t == glTime){
1048 if (transType == WithDrawal){
1050 withdrawalSum += amount;
1053 assert(transType == Deposit);
1055 depositSum += amount;
1062 if ((rows % 100) == 0){
1064 if (pTrans->
refresh() == -1) {
1079 transactionsCount = rowsFound;
1085 int Bank::performValidateGLs(Uint64 age){
1088 if (getCurrTime(currTime) != NDBT_OK){
1091 Uint64 glTime = currTime - 1;
1092 while((glTime > 0) && ((glTime + age) >= currTime)){
1094 int result = performValidateGL(glTime);
1095 if (result != NDBT_OK){
1096 g_err <<
"performValidateGL failed: " << result << endl;
1106 int Bank::performValidateGL(Uint64 glTime){
1108 ndbout <<
"performValidateGL: " << glTime << endl;
1132 if (pScanTrans == NULL) {
1151 if( accountTypeRec ==NULL ) {
1158 if( timeRec ==NULL ) {
1165 if( purgedRec ==NULL ) {
1172 if( balanceRec ==NULL ) {
1179 if( depositSumRec ==NULL ) {
1186 if( depositCountRec ==NULL ) {
1193 if( withdrawalSumRec ==NULL ) {
1199 if( withdrawalCountRec ==NULL ) {
1205 check = pScanTrans->
execute(NoCommit);
1214 int countGlRecords = 0;
1215 int result = NDBT_OK;
1226 Uint32 wsum = withdrawalSumRec->
u_32_value();
1227 Uint32 wcount = withdrawalCountRec->
u_32_value();
1229 Uint32 dcount = depositCountRec->
u_32_value();
1233 Uint32 withdrawalSum = 0;
1234 Uint32 withdrawalCount = 0;
1235 Uint32 depositSum = 0;
1236 Uint32 depositCount = 0;
1237 Uint32 countTransactions = 0;
1249 if (sumTransactionsForGL(t,
1257 pScanTrans) != NDBT_OK){
1258 result = NDBT_FAILED;
1260 Uint32 prevBalance = 0;
1261 if (getBalanceForGL(t-1, a, prevBalance) != NDBT_OK){
1262 result = NDBT_FAILED;
1264 if (((prevBalance + balance) != b) ||
1265 (wsum != withdrawalSum) ||
1266 (wcount != withdrawalCount) ||
1267 (dsum != depositSum) ||
1268 (dcount != depositCount)){
1269 g_err <<
"performValidateGL, sums and counts failed" << endl
1270 <<
"balance : " << balance+prevBalance <<
"!="<<b<<endl
1271 <<
"with sum : " << withdrawalSum <<
"!="<<wsum<<endl
1272 <<
"with count: " << withdrawalCount <<
"!="<<wcount<<endl
1273 <<
"dep sum : " << depositSum <<
"!="<<dsum<<endl
1274 <<
"dep count : " << depositCount <<
"!="<<dcount<<endl;
1275 result = VERIFICATION_FAILED;
1280 assert(purged == 1);
1284 if (sumTransactionsForGL(t,
1292 pScanTrans) != NDBT_OK){
1293 result = NDBT_FAILED;
1295 if (countTransactions != 0){
1296 g_err <<
"performValidateGL, countTransactions("<<countTransactions<<
") != 0" << endl;
1297 result = VERIFICATION_FAILED;
1314 if ((countGlRecords != 0) && (countGlRecords != getNumAccountTypes())){
1315 g_err <<
"performValidateGL: " << endl
1316 <<
"countGlRecords = " << countGlRecords << endl;
1317 result = VERIFICATION_FAILED;
1325 int Bank::getBalanceForGL(
const Uint64 glTime,
1326 const Uint32 accountTypeId,
1331 if (pTrans == NULL) {
1348 check = pOp->
equal(
"TIME", glTime);
1354 check = pOp->
equal(
"ACCOUNT_TYPE", accountTypeId);
1361 if( balanceRec == NULL ) {
1366 check = pTrans->
execute(Commit);
1381 int Bank::getOldestPurgedGL(
const Uint32 accountType,
1391 if (pScanTrans == NULL) {
1410 if( accountTypeRec ==NULL ) {
1417 if( timeRec ==NULL ) {
1424 if( purgedRec ==NULL ) {
1430 check = pScanTrans->
execute(NoCommit);
1437 NdbSleep_MilliSleep(50);
1453 if (a == accountType && p == 1){
1469 NdbSleep_MilliSleep(50);
1482 int Bank::getOldestNotPurgedGL(Uint64 &oldest,
1483 Uint32 &accountTypeId,
1491 if (pScanTrans == NULL) {
1510 if( accountTypeRec ==NULL ) {
1517 if( timeRec ==NULL ) {
1524 if( purgedRec ==NULL ) {
1530 check = pScanTrans->
execute(NoCommit);
1540 oldest = (Uint64)-1;
1570 int Bank::checkNoTransactionsOlderThan(
const Uint32 accountType,
1571 const Uint64 oldest){
1585 if (pScanTrans == NULL) {
1604 if( accountTypeRec ==NULL ) {
1611 if( timeRec ==NULL ) {
1618 if( transactionIdRec ==NULL ) {
1624 check = pScanTrans->
execute(NoCommit);
1632 NdbSleep_MilliSleep(50);
1648 if (a == accountType && t <= oldest){
1651 g_err <<
"checkNoTransactionsOlderThan found one record" << endl
1652 <<
" t = " << t << endl
1653 <<
" a = " << a << endl
1654 <<
" ti = " << ti << endl;
1666 NdbSleep_MilliSleep(50);
1681 return VERIFICATION_FAILED;
1685 int Bank::performValidatePurged(){
1692 for (
int i = 0;
i < getNumAccountTypes();
i++){
1693 ndbout <<
"performValidatePurged: " <<
i << endl;
1694 Uint64 oldestGlTime;
1695 if (getOldestPurgedGL(
i, oldestGlTime) != NDBT_OK){
1696 g_err <<
"getOldestPurgedGL failed" << endl;
1699 int result = checkNoTransactionsOlderThan(
i, oldestGlTime);
1700 if (result != NDBT_OK){
1701 g_err <<
"checkNoTransactionsOlderThan failed" << endl;
1710 int Bank::purgeOldGLTransactions(Uint64 currTime, Uint32 age){
1726 Uint64 oldestGlTime;
1727 Uint32 accountTypeId;
1728 if (getOldestNotPurgedGL(oldestGlTime, accountTypeId, found) != NDBT_OK){
1729 g_err <<
"getOldestNotPurgedGL failed" << endl;
1734 if (found ==
false){
1745 if ((currTime < age) || (oldestGlTime > (currTime-age))){
1750 if (purgeTransactions(oldestGlTime, accountTypeId) != NDBT_OK){
1751 g_err <<
"purgeTransactions failed" << endl;
1755 g_err <<
"abnormal return" << endl;
1760 int Bank::purgeTransactions(
const Uint64 glTime,
1761 const Uint32 accountTypeId)
1764 g_info <<
"purgeTransactions: " << glTime <<
", "<<accountTypeId<<endl;
1766 if (pTrans == NULL){
1784 check = pOp->
equal(
"TIME", glTime);
1790 check = pOp->
equal(
"ACCOUNT_TYPE", accountTypeId);
1797 check = pOp->
setValue(
"PURGED", purged);
1804 check = pTrans->
execute(NoCommit);
1812 if(findTransactionsToPurge(glTime,
1814 pTrans) != NDBT_OK){
1815 g_err <<
"findTransactionToPurge failed" << endl;
1822 check = pTrans->
execute(Commit);
1833 int Bank::findTransactionsToPurge(
const Uint64 glTime,
1834 const Uint32 accountType,
1839 if (pScanTrans == NULL) {
1851 if( pOp->readTuplesExclusive() ) {
1858 if( timeRec ==NULL ) {
1865 if( accountTypeRec ==NULL ) {
1871 check = pScanTrans->
execute(NoCommit);
1888 if (a == accountType && t == glTime){
1899 check = pTrans->
execute(NoCommit);
1922 int Bank::performIncreaseTime(
int maxSleepBetweenDays,
int yield)
1924 int yieldCounter = 0;
1929 if (incCurrTime(currTime) != NDBT_OK)
1932 g_info <<
"Current time is " << currTime << endl;
1933 if (maxSleepBetweenDays > 0){
1934 int val = myRandom48(maxSleepBetweenDays);
1935 NdbSleep_SecSleep(val);
1939 if (yield != 0 && yieldCounter >= yield)
1946 int Bank::readSystemValue(SystemValueId sysValId, Uint64 & value){
1958 NdbSleep_MilliSleep(50);
1965 if ((result= prepareReadSystemValueOp(pTrans, sysValId, value)) != NDBT_OK)
1972 check = pTrans->
execute(Commit);
1979 NdbSleep_MilliSleep(50);
1993 int Bank::prepareReadSystemValueOp(
NdbConnection* pTrans, SystemValueId sysValId, Uint64 & value){
2007 check = pOp->
equal(
"SYSTEM_VALUES_ID", sysValId);
2013 if( valueRec == NULL ) {
2020 int Bank::writeSystemValue(SystemValueId sysValId, Uint64 value){
2025 if (pTrans == NULL){
2044 check = pOp->
equal(
"SYSTEM_VALUES_ID", sysValId);
2051 check = pOp->
setValue(
"VALUE", value);
2058 check = pTrans->
execute(Commit);
2070 int Bank::getNextTransactionId(Uint64 &value){
2071 return increaseSystemValue2(LastTransactionId, value);
2074 int Bank::incCurrTime(Uint64 &value){
2075 return increaseSystemValue(CurrentTime, value);
2079 int Bank::increaseSystemValue(SystemValueId sysValId, Uint64 &value){
2086 DBUG_ENTER(
"Bank::increaseSystemValue");
2091 if (pTrans == NULL){
2094 DBUG_RETURN(NDBT_TEMPORARY);
2095 DBUG_RETURN(NDBT_FAILED);
2102 DBUG_RETURN(NDBT_FAILED);
2110 DBUG_RETURN(NDBT_FAILED);
2113 check = pOp->
equal(
"SYSTEM_VALUES_ID", sysValId);
2117 DBUG_RETURN(NDBT_FAILED);
2121 if( valueRec ==NULL ) {
2124 DBUG_RETURN(NDBT_FAILED);
2127 check = pTrans->
execute(NoCommit);
2133 DBUG_RETURN(NDBT_TEMPORARY);
2136 DBUG_RETURN(NDBT_FAILED);
2146 DBUG_RETURN(NDBT_FAILED);
2153 DBUG_RETURN(NDBT_FAILED);
2156 check = pOp2->
equal(
"SYSTEM_VALUES_ID", sysValId);
2160 DBUG_RETURN(NDBT_FAILED);
2163 check = pOp2->
setValue(
"VALUE", value);
2167 DBUG_RETURN(NDBT_FAILED);
2170 check = pTrans->
execute(NoCommit);
2174 DBUG_RETURN(NDBT_FAILED);
2181 DBUG_RETURN(NDBT_FAILED);
2188 DBUG_RETURN(NDBT_FAILED);
2191 check = pOp3->
equal(
"SYSTEM_VALUES_ID", sysValId);
2195 DBUG_RETURN(NDBT_FAILED);
2200 if( valueNewRec ==NULL ) {
2203 DBUG_RETURN(NDBT_FAILED);
2206 check = pTrans->
execute(Commit);
2212 DBUG_RETURN(NDBT_TEMPORARY);
2215 DBUG_RETURN(NDBT_FAILED);
2221 printf(
"value actual=%lld\n", valueNewRec->
u_64_value());
2222 printf(
"value expected=%lld actual=%lld\n", value, valueNewRec->
u_64_value());
2224 DBUG_PRINT(
"info", (
"value expected=%ld actual=%ld", (
long)value, (
long)valueNewRec->
u_64_value()));
2225 g_err <<
"getNextTransactionId: value was not updated" << endl;
2227 DBUG_RETURN(NDBT_FAILED);
2235 int Bank::increaseSystemValue2(SystemValueId sysValId, Uint64 &value){
2246 if (pTrans == NULL){
2249 return NDBT_TEMPORARY;
2267 check = pOp->
equal(
"SYSTEM_VALUES_ID", sysValId );
2274 Uint32 valToIncWith = 1;
2275 check = pOp->
incValue(
"VALUE", valToIncWith);
2283 if( valueRec == NULL ) {
2289 check = pTrans->
execute(Commit);
2295 return NDBT_TEMPORARY;
2311 int Bank::getCurrTime(Uint64 &time){
2312 return readSystemValue(CurrentTime, time);
2315 int Bank::prepareGetCurrTimeOp(
NdbConnection *pTrans, Uint64 &time){
2316 return prepareReadSystemValueOp(pTrans, CurrentTime, time);
2320 int Bank::performSumAccounts(
int maxSleepBetweenSums,
int yield){
2322 int yieldCounter = 0;
2326 Uint32 sumAccounts = 0;
2327 Uint32 numAccounts = 0;
2328 if (getSumAccounts(sumAccounts, numAccounts) != NDBT_OK){
2329 g_err <<
"getSumAccounts FAILED" << endl;
2332 g_info <<
"num="<<numAccounts<<
", sum=" << sumAccounts << endl;
2334 if (sumAccounts != (10000000 + (10000*(numAccounts-1)))){
2335 g_err <<
"performSumAccounts FAILED" << endl
2336 <<
" sumAccounts="<<sumAccounts<<endl
2337 <<
" expected ="<<(10000000 + (10000*(numAccounts-1)))<<endl
2338 <<
" numAccounts="<<numAccounts<<endl;
2342 if (maxSleepBetweenSums > 0){
2343 int val = myRandom48(maxSleepBetweenSums);
2344 NdbSleep_MilliSleep(val);
2349 if (yield != 0 && yieldCounter >= yield)
2356 int Bank::getSumAccounts(Uint32 &sumAccounts,
2357 Uint32 &numAccounts){
2363 if (pScanTrans == NULL) {
2375 if( pOp->readTuplesExclusive() ) {
2382 if( balanceRec ==NULL ) {
2388 check = pScanTrans->
execute(NoCommit);
2396 if (pTrans == NULL) {
2416 if (pLockOp == NULL){
2423 Uint32 illegalBalance = 99;
2424 check = pLockOp->
setValue(
"BALANCE", illegalBalance);
2433 check = pTrans->
execute(NoCommit);
2453 check = pTrans->
execute(Rollback);