Commit e18b384b authored by joreland@mysql.com's avatar joreland@mysql.com

testIndex -n NFNR1

Bugs in scan(tc)
        nf-handling(api)
        exec-handling(tc)
parent ad7d5bbd
...@@ -693,9 +693,6 @@ NdbConnection::checkState_TransId(const Uint32 * transId) const { ...@@ -693,9 +693,6 @@ NdbConnection::checkState_TransId(const Uint32 * transId) const {
const Uint32 tTmp2 = transId[1]; const Uint32 tTmp2 = transId[1];
Uint64 tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32); Uint64 tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32);
bool b = theStatus == Connected && theTransactionId == tRecTransId; bool b = theStatus == Connected && theTransactionId == tRecTransId;
#ifdef NDB_NO_DROPPED_SIGNAL
if(!b) abort();
#endif
return b; return b;
} }
......
...@@ -755,7 +755,7 @@ protected: ...@@ -755,7 +755,7 @@ protected:
int receiveREAD_CONF(const Uint32* aDataPtr, Uint32 aDataLength); int receiveREAD_CONF(const Uint32* aDataPtr, Uint32 aDataLength);
int checkMagicNumber(); // Verify correct object int checkMagicNumber(bool b = true); // Verify correct object
int checkState_TransId(NdbApiSignal* aSignal); int checkState_TransId(NdbApiSignal* aSignal);
...@@ -900,11 +900,11 @@ protected: ...@@ -900,11 +900,11 @@ protected:
inline inline
int int
NdbOperation::checkMagicNumber() NdbOperation::checkMagicNumber(bool b)
{ {
if (theMagicNumber != 0xABCDEF01){ if (theMagicNumber != 0xABCDEF01){
#ifdef NDB_NO_DROPPED_SIGNAL #ifdef NDB_NO_DROPPED_SIGNAL
abort(); if(b) abort();
#endif #endif
return -1; return -1;
} }
......
...@@ -79,7 +79,36 @@ ...@@ -79,7 +79,36 @@
#ifdef VM_TRACE #ifdef VM_TRACE
NdbOut & NdbOut &
operator<<(NdbOut& out, Dbtc::ConnectionState state){ operator<<(NdbOut& out, Dbtc::ConnectionState state){
out << (int)state; switch(state){
case Dbtc::CS_CONNECTED: out << "CS_CONNECTED"; break;
case Dbtc::CS_DISCONNECTED: out << "CS_DISCONNECTED"; break;
case Dbtc::CS_STARTED: out << "CS_STARTED"; break;
case Dbtc::CS_RECEIVING: out << "CS_RECEIVING"; break;
case Dbtc::CS_PREPARED: out << "CS_PREPARED"; break;
case Dbtc::CS_START_PREPARING: out << "CS_START_PREPARING"; break;
case Dbtc::CS_REC_PREPARING: out << "CS_REC_PREPARING"; break;
case Dbtc::CS_RESTART: out << "CS_RESTART"; break;
case Dbtc::CS_ABORTING: out << "CS_ABORTING"; break;
case Dbtc::CS_COMPLETING: out << "CS_COMPLETING"; break;
case Dbtc::CS_COMPLETE_SENT: out << "CS_COMPLETE_SENT"; break;
case Dbtc::CS_PREPARE_TO_COMMIT: out << "CS_PREPARE_TO_COMMIT"; break;
case Dbtc::CS_COMMIT_SENT: out << "CS_COMMIT_SENT"; break;
case Dbtc::CS_START_COMMITTING: out << "CS_START_COMMITTING"; break;
case Dbtc::CS_COMMITTING: out << "CS_COMMITTING"; break;
case Dbtc::CS_REC_COMMITTING: out << "CS_REC_COMMITTING"; break;
case Dbtc::CS_WAIT_ABORT_CONF: out << "CS_WAIT_ABORT_CONF"; break;
case Dbtc::CS_WAIT_COMPLETE_CONF: out << "CS_WAIT_COMPLETE_CONF"; break;
case Dbtc::CS_WAIT_COMMIT_CONF: out << "CS_WAIT_COMMIT_CONF"; break;
case Dbtc::CS_FAIL_ABORTING: out << "CS_FAIL_ABORTING"; break;
case Dbtc::CS_FAIL_ABORTED: out << "CS_FAIL_ABORTED"; break;
case Dbtc::CS_FAIL_PREPARED: out << "CS_FAIL_PREPARED"; break;
case Dbtc::CS_FAIL_COMMITTING: out << "CS_FAIL_COMMITTING"; break;
case Dbtc::CS_FAIL_COMMITTED: out << "CS_FAIL_COMMITTED"; break;
case Dbtc::CS_FAIL_COMPLETED: out << "CS_FAIL_COMPLETED"; break;
case Dbtc::CS_START_SCAN: out << "CS_START_SCAN"; break;
default:
out << "Unknown: " << (int)state; break;
}
return out; return out;
} }
NdbOut & NdbOut &
...@@ -1240,13 +1269,13 @@ void Dbtc::execTCRELEASEREQ(Signal* signal) ...@@ -1240,13 +1269,13 @@ void Dbtc::execTCRELEASEREQ(Signal* signal)
jam(); /* JUST REPLY OK */ jam(); /* JUST REPLY OK */
releaseApiCon(signal, apiConnectptr.i); releaseApiCon(signal, apiConnectptr.i);
signal->theData[0] = tuserpointer; signal->theData[0] = tuserpointer;
sendSignal(apiConnectptr.p->ndbapiBlockref, sendSignal(tapiBlockref,
GSN_TCRELEASECONF, signal, 1, JBB); GSN_TCRELEASECONF, signal, 1, JBB);
} else { } else {
jam(); jam();
signal->theData[0] = tuserpointer; signal->theData[0] = tuserpointer;
signal->theData[1] = ZINVALID_CONNECTION; signal->theData[1] = ZINVALID_CONNECTION;
sendSignal(apiConnectptr.p->ndbapiBlockref, sendSignal(tapiBlockref,
GSN_TCRELEASEREF, signal, 2, JBB); GSN_TCRELEASEREF, signal, 2, JBB);
} }
} else { } else {
...@@ -3683,7 +3712,7 @@ Dbtc::lqhKeyConf_checkTransactionState(Signal * signal, ...@@ -3683,7 +3712,7 @@ Dbtc::lqhKeyConf_checkTransactionState(Signal * signal,
case CS_RECEIVING: case CS_RECEIVING:
if (TnoOfOutStanding == 0) { if (TnoOfOutStanding == 0) {
jam(); jam();
sendtckeyconf(signal, 0); sendtckeyconf(signal, 2);
return; return;
} else { } else {
if (apiConnectPtrP->tckeyrec == ZTCOPCONF_SIZE) { if (apiConnectPtrP->tckeyrec == ZTCOPCONF_SIZE) {
...@@ -3742,7 +3771,7 @@ void Dbtc::sendtckeyconf(Signal* signal, UintR TcommitFlag) ...@@ -3742,7 +3771,7 @@ void Dbtc::sendtckeyconf(Signal* signal, UintR TcommitFlag)
ptrAss(localHostptr, hostRecord); ptrAss(localHostptr, hostRecord);
UintR TcurrLen = localHostptr.p->noOfWordsTCKEYCONF; UintR TcurrLen = localHostptr.p->noOfWordsTCKEYCONF;
UintR confInfo = 0; UintR confInfo = 0;
TcKeyConf::setCommitFlag(confInfo, TcommitFlag); TcKeyConf::setCommitFlag(confInfo, TcommitFlag == 1);
TcKeyConf::setMarkerFlag(confInfo, Tmarker); TcKeyConf::setMarkerFlag(confInfo, Tmarker);
const UintR TpacketLen = 6 + TopWords; const UintR TpacketLen = 6 + TopWords;
regApiPtr->tckeyrec = 0; regApiPtr->tckeyrec = 0;
...@@ -3767,8 +3796,10 @@ void Dbtc::sendtckeyconf(Signal* signal, UintR TcommitFlag) ...@@ -3767,8 +3796,10 @@ void Dbtc::sendtckeyconf(Signal* signal, UintR TcommitFlag)
return; // No queued TcKeyConf return; // No queued TcKeyConf
}//if }//if
}//if }//if
if(TcommitFlag){
jam();
regApiPtr->m_exec_flag = 0; regApiPtr->m_exec_flag = 0;
}
TcKeyConf::setNoOfOperations(confInfo, (TopWords >> 1)); TcKeyConf::setNoOfOperations(confInfo, (TopWords >> 1));
if ((TpacketLen > 25) || !is_api){ if ((TpacketLen > 25) || !is_api){
TcKeyConf * const tcKeyConf = (TcKeyConf *)signal->getDataPtrSend(); TcKeyConf * const tcKeyConf = (TcKeyConf *)signal->getDataPtrSend();
...@@ -4481,6 +4512,8 @@ void Dbtc::copyApi(Signal* signal) ...@@ -4481,6 +4512,8 @@ void Dbtc::copyApi(Signal* signal)
setApiConTimer(tmpApiConnectptr.i, 0, __LINE__); setApiConTimer(tmpApiConnectptr.i, 0, __LINE__);
regTmpApiPtr->apiConnectstate = CS_CONNECTED; regTmpApiPtr->apiConnectstate = CS_CONNECTED;
regTmpApiPtr->commitAckMarker = RNIL; regTmpApiPtr->commitAckMarker = RNIL;
regTmpApiPtr->firstTcConnect = RNIL;
regTmpApiPtr->lastTcConnect = RNIL;
}//Dbtc::copyApi() }//Dbtc::copyApi()
void Dbtc::unlinkApiConnect(Signal* signal) void Dbtc::unlinkApiConnect(Signal* signal)
...@@ -5003,7 +5036,7 @@ void Dbtc::execLQHKEYREF(Signal* signal) ...@@ -5003,7 +5036,7 @@ void Dbtc::execLQHKEYREF(Signal* signal)
return; return;
} else if (regApiPtr->tckeyrec > 0) { } else if (regApiPtr->tckeyrec > 0) {
jam(); jam();
sendtckeyconf(signal, 0); sendtckeyconf(signal, 2);
return; return;
}//if }//if
}//if }//if
...@@ -5991,7 +6024,9 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr) ...@@ -5991,7 +6024,9 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr)
/* THIS TRANSACTION HAVE EXPERIENCED A TIME-OUT AND WE NEED TO*/ /* THIS TRANSACTION HAVE EXPERIENCED A TIME-OUT AND WE NEED TO*/
/* FIND OUT WHAT WE NEED TO DO BASED ON THE STATE INFORMATION.*/ /* FIND OUT WHAT WE NEED TO DO BASED ON THE STATE INFORMATION.*/
/*------------------------------------------------------------------*/ /*------------------------------------------------------------------*/
DEBUG("Time-out in state = " << apiConnectptr.p->apiConnectstate DEBUG("[ H'" << hex << apiConnectptr.p->transid[0]
<< " H'" << apiConnectptr.p->transid[1] << "] " << dec
<< "Time-out in state = " << apiConnectptr.p->apiConnectstate
<< " apiConnectptr.i = " << apiConnectptr.i << " apiConnectptr.i = " << apiConnectptr.i
<< " - exec: " << apiConnectptr.p->m_exec_flag); << " - exec: " << apiConnectptr.p->m_exec_flag);
switch (apiConnectptr.p->apiConnectstate) { switch (apiConnectptr.p->apiConnectstate) {
...@@ -8789,6 +8824,10 @@ void Dbtc::releaseScanResources(ScanRecordPtr scanPtr) ...@@ -8789,6 +8824,10 @@ void Dbtc::releaseScanResources(ScanRecordPtr scanPtr)
ndbrequire(scanPtr.p->m_queued_scan_frags.isEmpty()); ndbrequire(scanPtr.p->m_queued_scan_frags.isEmpty());
ndbrequire(scanPtr.p->m_delivered_scan_frags.isEmpty()); ndbrequire(scanPtr.p->m_delivered_scan_frags.isEmpty());
ndbassert(scanPtr.p->scanApiRec == apiConnectptr.i);
ndbassert(apiConnectptr.p->apiScanRec == scanPtr.i);
// link into free list // link into free list
scanPtr.p->nextScan = cfirstfreeScanrec; scanPtr.p->nextScan = cfirstfreeScanrec;
scanPtr.p->scanState = ScanRecord::IDLE; scanPtr.p->scanState = ScanRecord::IDLE;
...@@ -8984,6 +9023,10 @@ void Dbtc::scanError(Signal* signal, ScanRecordPtr scanptr, Uint32 errorCode) ...@@ -8984,6 +9023,10 @@ void Dbtc::scanError(Signal* signal, ScanRecordPtr scanptr, Uint32 errorCode)
DEBUG("scanError, errorCode = "<< errorCode << DEBUG("scanError, errorCode = "<< errorCode <<
", scanState = " << scanptr.p->scanState); ", scanState = " << scanptr.p->scanState);
apiConnectptr.i = scanP->scanApiRec;
ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
ndbrequire(apiConnectptr.p->apiScanRec == scanptr.i);
if(scanP->scanState == ScanRecord::CLOSING_SCAN){ if(scanP->scanState == ScanRecord::CLOSING_SCAN){
jam(); jam();
close_scan_req_send_conf(signal, scanptr); close_scan_req_send_conf(signal, scanptr);
...@@ -8992,10 +9035,6 @@ void Dbtc::scanError(Signal* signal, ScanRecordPtr scanptr, Uint32 errorCode) ...@@ -8992,10 +9035,6 @@ void Dbtc::scanError(Signal* signal, ScanRecordPtr scanptr, Uint32 errorCode)
ndbrequire(scanP->scanState == ScanRecord::RUNNING); ndbrequire(scanP->scanState == ScanRecord::RUNNING);
apiConnectptr.i = scanP->scanApiRec;
ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
ndbrequire(apiConnectptr.p->apiScanRec == scanptr.i);
/** /**
* Close scan wo/ having received an order to do so * Close scan wo/ having received an order to do so
*/ */
...@@ -9249,7 +9288,9 @@ void Dbtc::execSCAN_NEXTREQ(Signal* signal) ...@@ -9249,7 +9288,9 @@ void Dbtc::execSCAN_NEXTREQ(Signal* signal)
void void
Dbtc::close_scan_req(Signal* signal, ScanRecordPtr scanPtr, bool req_received){ Dbtc::close_scan_req(Signal* signal, ScanRecordPtr scanPtr, bool req_received){
ScanRecord* scanP = scanPtr.p; ScanRecord* scanP = scanPtr.p;
ndbrequire(scanPtr.p->scanState != ScanRecord::IDLE);
scanPtr.p->scanState = ScanRecord::CLOSING_SCAN; scanPtr.p->scanState = ScanRecord::CLOSING_SCAN;
scanPtr.p->m_close_scan_req = req_received; scanPtr.p->m_close_scan_req = req_received;
...@@ -9990,6 +10031,8 @@ void Dbtc::releaseApiCon(Signal* signal, UintR TapiConnectPtr) ...@@ -9990,6 +10031,8 @@ void Dbtc::releaseApiCon(Signal* signal, UintR TapiConnectPtr)
cfirstfreeApiConnect = TlocalApiConnectptr.i; cfirstfreeApiConnect = TlocalApiConnectptr.i;
setApiConTimer(TlocalApiConnectptr.i, 0, __LINE__); setApiConTimer(TlocalApiConnectptr.i, 0, __LINE__);
TlocalApiConnectptr.p->apiConnectstate = CS_DISCONNECTED; TlocalApiConnectptr.p->apiConnectstate = CS_DISCONNECTED;
ndbassert(TlocalApiConnectptr.p->apiScanRec == RNIL);
TlocalApiConnectptr.p->ndbapiBlockref = 0;
}//Dbtc::releaseApiCon() }//Dbtc::releaseApiCon()
void Dbtc::releaseApiConnectFail(Signal* signal) void Dbtc::releaseApiConnectFail(Signal* signal)
...@@ -10042,12 +10085,12 @@ void Dbtc::seizeApiConnect(Signal* signal) ...@@ -10042,12 +10085,12 @@ void Dbtc::seizeApiConnect(Signal* signal)
apiConnectptr.p->nextApiConnect = RNIL; apiConnectptr.p->nextApiConnect = RNIL;
setApiConTimer(apiConnectptr.i, 0, __LINE__); setApiConTimer(apiConnectptr.i, 0, __LINE__);
apiConnectptr.p->apiConnectstate = CS_CONNECTED; /* STATE OF CONNECTION */ apiConnectptr.p->apiConnectstate = CS_CONNECTED; /* STATE OF CONNECTION */
apiConnectptr.p->triggerPending = false;
apiConnectptr.p->isIndexOp = false;
} else { } else {
jam(); jam();
terrorCode = ZNO_FREE_API_CONNECTION; terrorCode = ZNO_FREE_API_CONNECTION;
}//if }//if
apiConnectptr.p->triggerPending = false;
apiConnectptr.p->isIndexOp = false;
}//Dbtc::seizeApiConnect() }//Dbtc::seizeApiConnect()
void Dbtc::seizeApiConnectFail(Signal* signal) void Dbtc::seizeApiConnectFail(Signal* signal)
...@@ -10997,11 +11040,15 @@ void Dbtc::sendTcIndxConf(Signal* signal, UintR TcommitFlag) ...@@ -10997,11 +11040,15 @@ void Dbtc::sendTcIndxConf(Signal* signal, UintR TcommitFlag)
UintR TcurrLen = localHostptr.p->noOfWordsTCINDXCONF; UintR TcurrLen = localHostptr.p->noOfWordsTCINDXCONF;
UintR confInfo = 0; UintR confInfo = 0;
TcIndxConf::setNoOfOperations(confInfo, (TopWords >> 1)); TcIndxConf::setNoOfOperations(confInfo, (TopWords >> 1));
TcIndxConf::setCommitFlag(confInfo, TcommitFlag); TcIndxConf::setCommitFlag(confInfo, TcommitFlag == 1);
TcIndxConf::setMarkerFlag(confInfo, Tmarker); TcIndxConf::setMarkerFlag(confInfo, Tmarker);
const UintR TpacketLen = 6 + TopWords; const UintR TpacketLen = 6 + TopWords;
regApiPtr->tcindxrec = 0; regApiPtr->tcindxrec = 0;
if(TcommitFlag || (regApiPtr->lqhkeyreqrec == regApiPtr->lqhkeyconfrec)){
jam();
regApiPtr->m_exec_flag = 0; regApiPtr->m_exec_flag = 0;
}
if ((TpacketLen > 25) || !is_api){ if ((TpacketLen > 25) || !is_api){
TcIndxConf * const tcIndxConf = (TcIndxConf *)signal->getDataPtrSend(); TcIndxConf * const tcIndxConf = (TcIndxConf *)signal->getDataPtrSend();
......
...@@ -1296,6 +1296,10 @@ NdbConnection::receiveTC_COMMITCONF(const TcCommitConf * commitConf) ...@@ -1296,6 +1296,10 @@ NdbConnection::receiveTC_COMMITCONF(const TcCommitConf * commitConf)
theCommitStatus = Committed; theCommitStatus = Committed;
theCompletionStatus = CompletedSuccess; theCompletionStatus = CompletedSuccess;
return 0; return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
} }
return -1; return -1;
}//NdbConnection::receiveTC_COMMITCONF() }//NdbConnection::receiveTC_COMMITCONF()
...@@ -1317,7 +1321,12 @@ NdbConnection::receiveTC_COMMITREF(NdbApiSignal* aSignal) ...@@ -1317,7 +1321,12 @@ NdbConnection::receiveTC_COMMITREF(NdbApiSignal* aSignal)
theCommitStatus = Aborted; theCommitStatus = Aborted;
theCompletionStatus = CompletedFailure; theCompletionStatus = CompletedFailure;
return 0; return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
} }
return -1; return -1;
}//NdbConnection::receiveTC_COMMITREF() }//NdbConnection::receiveTC_COMMITREF()
...@@ -1336,7 +1345,12 @@ NdbConnection::receiveTCROLLBACKCONF(NdbApiSignal* aSignal) ...@@ -1336,7 +1345,12 @@ NdbConnection::receiveTCROLLBACKCONF(NdbApiSignal* aSignal)
theCommitStatus = Aborted; theCommitStatus = Aborted;
theCompletionStatus = CompletedSuccess; theCompletionStatus = CompletedSuccess;
return 0; return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
} }
return -1; return -1;
}//NdbConnection::receiveTCROLLBACKCONF() }//NdbConnection::receiveTCROLLBACKCONF()
...@@ -1356,7 +1370,12 @@ NdbConnection::receiveTCROLLBACKREF(NdbApiSignal* aSignal) ...@@ -1356,7 +1370,12 @@ NdbConnection::receiveTCROLLBACKREF(NdbApiSignal* aSignal)
theCommitStatus = Aborted; theCommitStatus = Aborted;
theCompletionStatus = CompletedFailure; theCompletionStatus = CompletedFailure;
return 0; return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
} }
return -1; return -1;
}//NdbConnection::receiveTCROLLBACKREF() }//NdbConnection::receiveTCROLLBACKREF()
...@@ -1390,7 +1409,12 @@ transactions. ...@@ -1390,7 +1409,12 @@ transactions.
theCompletionStatus = CompletedFailure; theCompletionStatus = CompletedFailure;
theCommitStatus = Aborted; theCommitStatus = Aborted;
return 0; return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
} }
return -1; return -1;
}//NdbConnection::receiveTCROLLBACKREP() }//NdbConnection::receiveTCROLLBACKREP()
...@@ -1451,7 +1475,12 @@ from other transactions. ...@@ -1451,7 +1475,12 @@ from other transactions.
return 0; // No more operations to wait for return 0; // No more operations to wait for
}//if }//if
// Not completed the reception yet. // Not completed the reception yet.
}//if } else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
}
return -1; return -1;
}//NdbConnection::receiveTCKEYCONF() }//NdbConnection::receiveTCKEYCONF()
...@@ -1505,6 +1534,10 @@ NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) ...@@ -1505,6 +1534,10 @@ NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf)
}//while }//while
theReleaseOnClose = true; theReleaseOnClose = true;
return 0; return 0;
} else {
#ifdef VM_TRACE
ndbout_c("Recevied TCKEY_FAILCONF wo/ operation");
#endif
} }
return -1; return -1;
}//NdbConnection::receiveTCKEY_FAILCONF() }//NdbConnection::receiveTCKEY_FAILCONF()
...@@ -1544,6 +1577,10 @@ NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) ...@@ -1544,6 +1577,10 @@ NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal)
theReleaseOnClose = true; theReleaseOnClose = true;
theCommitStatus = NdbConnection::Aborted; theCommitStatus = NdbConnection::Aborted;
return 0; return 0;
} else {
#ifdef VM_TRACE
ndbout_c("Recevied TCKEY_FAILREF wo/ operation");
#endif
} }
return -1; return -1;
}//NdbConnection::receiveTCKEY_FAILREF() }//NdbConnection::receiveTCKEY_FAILREF()
...@@ -1599,7 +1636,12 @@ NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, ...@@ -1599,7 +1636,12 @@ NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf,
return 0; // No more operations to wait for return 0; // No more operations to wait for
}//if }//if
// Not completed the reception yet. // Not completed the reception yet.
}//if } else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
}
return -1; return -1;
}//NdbConnection::receiveTCINDXCONF() }//NdbConnection::receiveTCINDXCONF()
...@@ -1628,7 +1670,12 @@ NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal) ...@@ -1628,7 +1670,12 @@ NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal)
theCompletionStatus = NdbConnection::CompletedFailure; theCompletionStatus = NdbConnection::CompletedFailure;
theCommitStatus = NdbConnection::Aborted; theCommitStatus = NdbConnection::Aborted;
return 0; return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
} }
return -1; return -1;
}//NdbConnection::receiveTCINDXREF() }//NdbConnection::receiveTCINDXREF()
......
...@@ -69,7 +69,12 @@ NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){ ...@@ -69,7 +69,12 @@ NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){
assert(theScanningOp->m_sent_receivers_count); assert(theScanningOp->m_sent_receivers_count);
theScanningOp->m_conf_receivers_count++; theScanningOp->m_conf_receivers_count++;
return 0; return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
} }
return -1; return -1;
} }
...@@ -120,6 +125,10 @@ NdbConnection::receiveSCAN_TABCONF(NdbApiSignal* aSignal, ...@@ -120,6 +125,10 @@ NdbConnection::receiveSCAN_TABCONF(NdbApiSignal* aSignal,
} }
} }
return 0; return 0;
} else {
#ifdef NDB_NO_DROPPED_SIGNAL
abort();
#endif
} }
return -1; return -1;
......
...@@ -373,8 +373,10 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) ...@@ -373,8 +373,10 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
switch(tRec->getType()){ switch(tRec->getType()){
case NdbReceiver::NDB_OPERATION: case NdbReceiver::NDB_OPERATION:
case NdbReceiver::NDB_INDEX_OPERATION: case NdbReceiver::NDB_INDEX_OPERATION:
if(tCon->OpCompleteSuccess() != -1) if(tCon->OpCompleteSuccess() != -1){
completedTransaction(tCon); completedTransaction(tCon);
return;
}
break; break;
case NdbReceiver::NDB_SCANRECEIVER: case NdbReceiver::NDB_SCANRECEIVER:
tCon->theScanningOp->receiver_delivered(tRec); tCon->theScanningOp->receiver_delivered(tRec);
...@@ -392,14 +394,12 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) ...@@ -392,14 +394,12 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
case GSN_TCKEY_FAILCONF: case GSN_TCKEY_FAILCONF:
{ {
tFirstDataPtr = int2void(tFirstData); tFirstDataPtr = int2void(tFirstData);
if (tFirstDataPtr == 0) goto InvalidSignal; const TcKeyFailConf * failConf = (TcKeyFailConf *)tDataPtr;
const TcKeyFailConf * const failConf = (TcKeyFailConf *)tDataPtr;
const BlockReference aTCRef = aSignal->theSendersBlockRef; const BlockReference aTCRef = aSignal->theSendersBlockRef;
if (tFirstDataPtr != 0){
tOp = void2rec_op(tFirstDataPtr); tOp = void2rec_op(tFirstDataPtr);
if (tOp->checkMagicNumber() == 0) { if (tOp->checkMagicNumber(false) == 0) {
tCon = tOp->theNdbCon; tCon = tOp->theNdbCon;
if (tCon != NULL) { if (tCon != NULL) {
if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || if ((tCon->theSendStatus == NdbConnection::sendTC_OP) ||
...@@ -409,9 +409,13 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) ...@@ -409,9 +409,13 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
completedTransaction(tCon); completedTransaction(tCon);
}//if }//if
}//if }//if
}//if }
}//if }
} else {
#ifdef VM_TRACE
ndbout_c("Recevied TCKEY_FAILCONF wo/ operation");
#endif
}
if(tFirstData & 1){ if(tFirstData & 1){
NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal,
failConf->transId1, failConf->transId1,
...@@ -423,8 +427,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) ...@@ -423,8 +427,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
case GSN_TCKEY_FAILREF: case GSN_TCKEY_FAILREF:
{ {
tFirstDataPtr = int2void(tFirstData); tFirstDataPtr = int2void(tFirstData);
if (tFirstDataPtr == 0) goto InvalidSignal; if(tFirstDataPtr != 0){
tOp = void2rec_op(tFirstDataPtr); tOp = void2rec_op(tFirstDataPtr);
if (tOp->checkMagicNumber() == 0) { if (tOp->checkMagicNumber() == 0) {
tCon = tOp->theNdbCon; tCon = tOp->theNdbCon;
...@@ -439,7 +442,12 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) ...@@ -439,7 +442,12 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
}//if }//if
}//if }//if
}//if }//if
return; } else {
#ifdef VM_TRACE
ndbout_c("Recevied TCKEY_FAILREF wo/ operation");
#endif
}
break;
} }
case GSN_TCKEYREF: case GSN_TCKEYREF:
{ {
...@@ -454,9 +462,10 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) ...@@ -454,9 +462,10 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
tReturnCode = tOp->receiveTCKEYREF(aSignal); tReturnCode = tOp->receiveTCKEYREF(aSignal);
if (tReturnCode != -1) { if (tReturnCode != -1) {
completedTransaction(tCon); completedTransaction(tCon);
}//if
return; return;
}//if }//if
break;
}//if
}//if }//if
} //if } //if
goto InvalidSignal; goto InvalidSignal;
...@@ -501,7 +510,6 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) ...@@ -501,7 +510,6 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
tReturnCode = tCon->receiveTC_COMMITREF(aSignal); tReturnCode = tCon->receiveTC_COMMITREF(aSignal);
if (tReturnCode != -1) { if (tReturnCode != -1) {
completedTransaction(tCon); completedTransaction(tCon);
return;
}//if }//if
}//if }//if
return; return;
...@@ -532,7 +540,6 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) ...@@ -532,7 +540,6 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
tReturnCode = tCon->receiveTCROLLBACKREF(aSignal); tReturnCode = tCon->receiveTCROLLBACKREF(aSignal);
if (tReturnCode != -1) { if (tReturnCode != -1) {
completedTransaction(tCon); completedTransaction(tCon);
return;
}//if }//if
}//if }//if
return; return;
...@@ -777,7 +784,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) ...@@ -777,7 +784,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3])
indxConf->transId2, indxConf->transId2,
aTCRef); aTCRef);
} }
break; return;
} }
case GSN_TCINDXREF:{ case GSN_TCINDXREF:{
tFirstDataPtr = int2void(tFirstData); tFirstDataPtr = int2void(tFirstData);
...@@ -940,6 +947,10 @@ Ndb::check_send_timeout() ...@@ -940,6 +947,10 @@ Ndb::check_send_timeout()
WAITFOR_RESPONSE_TIMEOUT) { WAITFOR_RESPONSE_TIMEOUT) {
#ifdef VM_TRACE #ifdef VM_TRACE
a_con->printState(); a_con->printState();
Uint32 t1 = a_con->theTransactionId;
Uint32 t2 = a_con->theTransactionId >> 32;
ndbout_c("[%.8x %.8x]", t1, t2);
abort();
#endif #endif
a_con->setOperationErrorCodeAbort(4012); a_con->setOperationErrorCodeAbort(4012);
a_con->theCommitStatus = NdbConnection::Aborted; a_con->theCommitStatus = NdbConnection::Aborted;
......
...@@ -161,6 +161,11 @@ setSignalLog(){ ...@@ -161,6 +161,11 @@ setSignalLog(){
} }
return false; return false;
} }
#ifdef TRACE_APIREGREQ
#define TRACE_GSN(gsn) true
#else
#define TRACE_GSN(gsn) (gsn != GSN_API_REGREQ && gsn != GSN_API_REGCONF)
#endif
#endif #endif
// These symbols are needed, but not used in the API // These symbols are needed, but not used in the API
...@@ -168,7 +173,7 @@ int g_sectionSegmentPool; ...@@ -168,7 +173,7 @@ int g_sectionSegmentPool;
struct ErrorReporter { struct ErrorReporter {
void handleAssert(const char*, const char*, int); void handleAssert(const char*, const char*, int);
}; };
void ErrorReporter::handleAssert(const char* message, const char* file, int line) {} void ErrorReporter::handleAssert(const char*, const char*, int) {}
/** /**
* The execute function : Handle received signal * The execute function : Handle received signal
...@@ -183,9 +188,7 @@ execute(void * callbackObj, SignalHeader * const header, ...@@ -183,9 +188,7 @@ execute(void * callbackObj, SignalHeader * const header,
Uint32 tRecBlockNo = header->theReceiversBlockNumber; Uint32 tRecBlockNo = header->theReceiversBlockNumber;
#ifdef API_TRACE #ifdef API_TRACE
if(setSignalLog()){ if(setSignalLog() && TRACE_GSN(header->theVerId_signalNumber)){
// header->theVerId_signalNumber != GSN_API_REGREQ &&
// header->theVerId_signalNumber != GSN_API_REGCONF){
signalLogger.executeSignal(* header, signalLogger.executeSignal(* header,
prio, prio,
theData, theData,
...@@ -765,8 +768,7 @@ TransporterFacade::checkForceSend(Uint32 block_number) { ...@@ -765,8 +768,7 @@ TransporterFacade::checkForceSend(Uint32 block_number) {
/****************************************************************************** /******************************************************************************
* SEND SIGNAL METHODS * SEND SIGNAL METHODS
******************************************************************************/ *****************************************************************************/
int int
TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){ TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){
Uint32* tDataPtr = aSignal->getDataPtrSend(); Uint32* tDataPtr = aSignal->getDataPtrSend();
...@@ -774,9 +776,7 @@ TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){ ...@@ -774,9 +776,7 @@ TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){
Uint32 TBno = aSignal->theReceiversBlockNumber; Uint32 TBno = aSignal->theReceiversBlockNumber;
if(getIsNodeSendable(aNode) == true){ if(getIsNodeSendable(aNode) == true){
#ifdef API_TRACE #ifdef API_TRACE
if(setSignalLog()){ if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
// aSignal->theVerId_signalNumber != GSN_API_REGREQ &&
// aSignal->theVerId_signalNumber != GSN_API_REGCONF){
Uint32 tmp = aSignal->theSendersBlockRef; Uint32 tmp = aSignal->theSendersBlockRef;
aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
LinearSectionPtr ptr[3]; LinearSectionPtr ptr[3];
...@@ -810,9 +810,7 @@ TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){ ...@@ -810,9 +810,7 @@ TransporterFacade::sendSignal(NdbApiSignal * aSignal, NodeId aNode){
int int
TransporterFacade::sendSignalUnCond(NdbApiSignal * aSignal, NodeId aNode){ TransporterFacade::sendSignalUnCond(NdbApiSignal * aSignal, NodeId aNode){
#ifdef API_TRACE #ifdef API_TRACE
if(setSignalLog()){ if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
//aSignal->theVerId_signalNumber != GSN_API_REGREQ &&
//aSignal->theVerId_signalNumber != GSN_API_REGCONF
Uint32 tmp = aSignal->theSendersBlockRef; Uint32 tmp = aSignal->theSendersBlockRef;
aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
LinearSectionPtr ptr[3]; LinearSectionPtr ptr[3];
...@@ -842,7 +840,7 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode, ...@@ -842,7 +840,7 @@ TransporterFacade::sendFragmentedSignal(NdbApiSignal* aSignal, NodeId aNode,
aSignal->m_noOfSections = secs; aSignal->m_noOfSections = secs;
if(getIsNodeSendable(aNode) == true){ if(getIsNodeSendable(aNode) == true){
#ifdef API_TRACE #ifdef API_TRACE
if(setSignalLog()){ if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
Uint32 tmp = aSignal->theSendersBlockRef; Uint32 tmp = aSignal->theSendersBlockRef;
aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
signalLogger.sendSignal(* aSignal, signalLogger.sendSignal(* aSignal,
...@@ -878,7 +876,7 @@ TransporterFacade::sendFragmentedSignalUnCond(NdbApiSignal* aSignal, ...@@ -878,7 +876,7 @@ TransporterFacade::sendFragmentedSignalUnCond(NdbApiSignal* aSignal,
aSignal->m_noOfSections = secs; aSignal->m_noOfSections = secs;
#ifdef API_TRACE #ifdef API_TRACE
if(setSignalLog()){ if(setSignalLog() && TRACE_GSN(aSignal->theVerId_signalNumber)){
Uint32 tmp = aSignal->theSendersBlockRef; Uint32 tmp = aSignal->theSendersBlockRef;
aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId); aSignal->theSendersBlockRef = numberToRef(tmp, theOwnId);
signalLogger.sendSignal(* aSignal, signalLogger.sendSignal(* aSignal,
......
...@@ -63,6 +63,8 @@ public: ...@@ -63,6 +63,8 @@ public:
bool getPropertyWait(const char*, Uint32); bool getPropertyWait(const char*, Uint32);
const char* getPropertyWait(const char*, const char* ); const char* getPropertyWait(const char*, const char* );
void decProperty(const char *);
// Communicate with other tests // Communicate with other tests
void stopTest(); void stopTest();
bool isTestStopped(); bool isTestStopped();
......
...@@ -380,6 +380,25 @@ runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -380,6 +380,25 @@ runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK; return NDBT_OK;
} }
int
sync_down(NDBT_Context* ctx){
Uint32 threads = ctx->getProperty("PauseThreads", (unsigned)0);
if(threads){
ctx->decProperty("PauseThreads");
}
}
int
sync_up_and_wait(NDBT_Context* ctx){
Uint32 threads = ctx->getProperty("Threads", (unsigned)0);
ndbout_c("Setting PauseThreads to %d", threads);
ctx->setProperty("PauseThreads", threads);
ctx->getPropertyWait("PauseThreads", (unsigned)0);
if(threads){
ndbout_c("wait completed");
}
}
int int
runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ runTransactions1(NDBT_Context* ctx, NDBT_Step* step){
// Verify that data in index match // Verify that data in index match
...@@ -394,10 +413,17 @@ runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -394,10 +413,17 @@ runTransactions1(NDBT_Context* ctx, NDBT_Step* step){
g_err << "Updated table failed" << endl; g_err << "Updated table failed" << endl;
return NDBT_FAILED; return NDBT_FAILED;
} }
sync_down(ctx);
if(ctx->isTestStopped())
break;
if (hugoTrans.scanUpdateRecords(pNdb, rows, batchSize) != 0){ if (hugoTrans.scanUpdateRecords(pNdb, rows, batchSize) != 0){
g_err << "Updated table failed" << endl; g_err << "Updated table failed" << endl;
return NDBT_FAILED; return NDBT_FAILED;
} }
sync_down(ctx);
} }
return NDBT_OK; return NDBT_OK;
} }
...@@ -418,7 +444,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -418,7 +444,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED; return NDBT_FAILED;
} }
#endif #endif
sync_down(ctx);
if(ctx->isTestStopped()) if(ctx->isTestStopped())
break; break;
#if 1 #if 1
...@@ -427,6 +453,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -427,6 +453,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED; return NDBT_FAILED;
} }
#endif #endif
sync_down(ctx);
} }
return NDBT_OK; return NDBT_OK;
} }
...@@ -447,6 +474,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -447,6 +474,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){
g_err << "Load table failed" << endl; g_err << "Load table failed" << endl;
return NDBT_FAILED; return NDBT_FAILED;
} }
sync_down(ctx);
if(ctx->isTestStopped()) if(ctx->isTestStopped())
break; break;
...@@ -455,6 +483,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -455,6 +483,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED; return NDBT_FAILED;
} }
sync_down(ctx);
if(ctx->isTestStopped()) if(ctx->isTestStopped())
break; break;
...@@ -463,6 +492,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -463,6 +492,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED; return NDBT_FAILED;
} }
sync_down(ctx);
if(ctx->isTestStopped()) if(ctx->isTestStopped())
break; break;
...@@ -471,6 +501,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -471,6 +501,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED; return NDBT_FAILED;
} }
sync_down(ctx);
if(ctx->isTestStopped()) if(ctx->isTestStopped())
break; break;
...@@ -479,6 +510,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -479,6 +510,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED; return NDBT_FAILED;
} }
sync_down(ctx);
if(ctx->isTestStopped()) if(ctx->isTestStopped())
break; break;
...@@ -486,12 +518,15 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -486,12 +518,15 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){
g_err << "Clear table failed" << endl; g_err << "Clear table failed" << endl;
return NDBT_FAILED; return NDBT_FAILED;
} }
sync_down(ctx);
if(ctx->isTestStopped()) if(ctx->isTestStopped())
break; break;
int count = -1; int count = -1;
if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0) if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0)
return NDBT_FAILED; return NDBT_FAILED;
sync_down(ctx);
} }
return NDBT_OK; return NDBT_OK;
} }
...@@ -510,6 +545,7 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -510,6 +545,7 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){
result = NDBT_FAILED; result = NDBT_FAILED;
break; break;
} }
sync_up_and_wait(ctx);
i++; i++;
} }
ctx->stopTest(); ctx->stopTest();
...@@ -1259,6 +1295,7 @@ TESTCASE("CreateLoadDrop_O", ...@@ -1259,6 +1295,7 @@ TESTCASE("CreateLoadDrop_O",
TESTCASE("NFNR1", TESTCASE("NFNR1",
"Test that indexes are correctly maintained during node fail and node restart"){ "Test that indexes are correctly maintained during node fail and node restart"){
TC_PROPERTY("LoggedIndexes", (unsigned)0); TC_PROPERTY("LoggedIndexes", (unsigned)0);
//TC_PROPERTY("Threads", 2);
INITIALIZER(runClearTable); INITIALIZER(runClearTable);
INITIALIZER(createRandomIndex); INITIALIZER(createRandomIndex);
INITIALIZER(runLoadTable); INITIALIZER(runLoadTable);
......
...@@ -132,6 +132,17 @@ void NDBT_Context::setProperty(const char* _name, Uint32 _val){ ...@@ -132,6 +132,17 @@ void NDBT_Context::setProperty(const char* _name, Uint32 _val){
assert(b == true); assert(b == true);
NdbMutex_Unlock(propertyMutexPtr); NdbMutex_Unlock(propertyMutexPtr);
} }
void
NDBT_Context::decProperty(const char * name){
NdbMutex_Lock(propertyMutexPtr);
Uint32 val = 0;
if(props.get(name, &val)){
assert(val > 0);
props.put(name, (val - 1), true);
}
NdbCondition_Broadcast(propertyCondPtr);
NdbMutex_Unlock(propertyMutexPtr);
}
void NDBT_Context::setProperty(const char* _name, const char* _val){ void NDBT_Context::setProperty(const char* _name, const char* _val){
NdbMutex_Lock(propertyMutexPtr); NdbMutex_Lock(propertyMutexPtr);
...@@ -994,6 +1005,7 @@ int NDBT_TestSuite::execute(int argc, const char** argv){ ...@@ -994,6 +1005,7 @@ int NDBT_TestSuite::execute(int argc, const char** argv){
res = executeAll(_testname); res = executeAll(_testname);
} else { } else {
testSuiteTimer.doStart(); testSuiteTimer.doStart();
Ndb ndb("TEST_DB"); ndb.init();
for(int i = optind; i<argc; i++){ for(int i = optind; i<argc; i++){
executeOne(argv[i], _testname); executeOne(argv[i], _testname);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment