mariadb/ndb/test/ndbapi/testNdbApi.cpp

1014 lines
22 KiB
C++
Raw Normal View History

/* Copyright (C) 2003 MySQL AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <NDBT.hpp>
#include <NDBT_Test.hpp>
#include <HugoTransactions.hpp>
#include <UtilTransactions.hpp>
#include <NdbRestarter.hpp>
#include <NdbRestarts.hpp>
#include <Vector.hpp>
#include <random.h>
#include <NdbTick.h>
Removed AttrType.hpp and moved the "internal" datatypes to their corresponding class. Moved NdbSchemaCon and NdbSchemaOp out of the public NdbApi, it can however still be used by old test programs. Added print oof indexes to desc. ndb/BinDist.sh: Removed AttrType.hpp from BinDist.sh ndb/include/ndbapi/Ndb.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbApi.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbConnection.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Moved internal types to the class where they are used ndb/include/ndbapi/NdbIndexOperation.hpp: Use limit from ndbapi_limit.h ndb/include/ndbapi/NdbOperation.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Remove faulty comment about how many attributes a key is allowed to consist of Removed unused member variables ndb/include/ndbapi/NdbRecAttr.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbSchemaCon.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbSchemaOp.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Moved all "old" datatypes here, so if a test program is still using old type, include NdbSchemaCon.hpp ndb/include/ndbapi/ndbapi_limits.h: Corrected limitations, added some from AttrTyp.hpp ndb/src/Makefile: Remove newtonapi from Makefile ndb/src/kernel/blocks/backup/restore/Restore.hpp: Removed AttrType Include NdbSchemaCon since restore uses old types ndb/src/kernel/blocks/backup/restore/main.cpp: Include NdbOut ndb/src/mgmsrv/MgmtSrvr.cpp: Remov AttrType.hpp ndb/src/ndbapi/ClusterMgr.cpp: Remov AttrType.hpp ndb/src/ndbapi/Ndb.cpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Moved internal types to the class where they are used ndb/src/ndbapi/NdbApiSignal.cpp: Removed AttrType.hpp ndb/src/ndbapi/NdbApiSignal.hpp: Removed AttrType.hpp ndb/src/ndbapi/NdbConnection.cpp: Moved internal type s to the class where they belong ndb/src/ndbapi/NdbDictionaryImpl.cpp: RemovedAttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbEventOperationImpl.cpp: Removed AttrType.hpp Moved printRecAttr to end since it depends on old types and need to include "NdbSchemaCon", function will be rewritten and moved to NdbRecAttr. It's also useful from other places where an attribute has been read into an NdbRecAttr. ndb/src/ndbapi/NdbIndexOperation.cpp: Use limitations from ndbapi_limits.h Moved internal tyeps to the class where they belongs ndb/src/ndbapi/NdbOperation.cpp: Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbOperationDefine.cpp: Remove AttrType.hpp ndb/src/ndbapi/NdbOperationExec.cpp: Moved internal tyeps to the class where they belongs ndb/src/ndbapi/NdbOperationInt.cpp: RemovedAttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbOperationScan.cpp: RemovedAttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbOperationSearch.cpp: Removed AttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbResultSet.cpp: Moved the "internal" types to corresponding class ndb/src/ndbapi/NdbSchemaCon.cpp: Updated not to be included in public NdbApi ndb/src/ndbapi/NdbSchemaOp.cpp: Updated not to be included in public NdbApi ndb/src/ndbapi/NdbUtil.hpp: Removed AttrType.hpp ndb/src/ndbapi/Ndbif.cpp: Removed AttrType.hpp Removed NdbSchemaCon and NdbSchemaOp from public NdbApi Moved "interal" types to their corresponding class ndb/src/ndbapi/Ndbinit.cpp: Removed NdbSchemaCon and NdbSchemaOp from public NdbApi ndb/src/ndbapi/Ndblist.cpp: Removed NdbSchemaCon and NdbSchemaOp from public NdbApi Moved "internal" types to their corresponding class ndb/src/ndbapi/TransporterFacade.cpp: Removed AttrType.hpp ndb/src/ndbapi/TransporterFacade.hpp: Removed AttrType.hpp Moved internal definition of how many Ndb objects to create to here ndb/test/include/NDBT_Table.hpp: Removed old NdbSchema* Added function to print information about an index ndb/test/ndbapi/acid/acid.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/flexAsynch/flexAsynch.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/flexScan/flexScan.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/interpreterInTup/interpreterInTup.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/lmc-bench/src/user/userInterface.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/ronja/initronja/initronja.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/telco/msa.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/testDataBuffers/testDataBuffers.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/testNdbApi/testNdbApi.cpp: Remove AttrType.hpp Define max number of Ndb objects test should "try" to create. ndb/test/ndbapi/testRestartGci/testRestartGci.cpp: Moved "internal" datatypes to corresponding class, in this case Ndb class ndb/test/src/NDBT_ResultRow.cpp: This test program uses old NdbScheaCon.hpp But should soon use "printer" from NdbRecAttr ndb/test/src/NDBT_Table.cpp: Print table info more SQL like ndb/test/src/UtilTransactions.cpp: When AttrType.hpp, this hidden bug was discovered. Using wrong enum types in switch. ndb/tools/desc/desc.cpp: Alos print info about indexes for a table
2004-05-25 11:53:07 +02:00
#define MAX_NDB_OBJECTS 32678
#define CHECK(b) if (!(b)) { \
ndbout << "ERR: "<< step->getName() \
<< " failed on line " << __LINE__ << endl; \
result = NDBT_FAILED; \
continue; }
#define CHECKE(b) if (!(b)) { \
errors++; \
ndbout << "ERR: "<< step->getName() \
<< " failed on line " << __LINE__ << endl; \
result = NDBT_FAILED; \
continue; }
int runTestMaxNdb(NDBT_Context* ctx, NDBT_Step* step){
Uint32 loops = ctx->getNumLoops();
Uint32 l = 0;
int oldi = 0;
int result = NDBT_OK;
while (l < loops && result == NDBT_OK){
ndbout_c("loop %d", l + 1);
int errors = 0;
int maxErrors = 5;
Vector<Ndb*> ndbVector;
int i = 0;
int init = 0;
do {
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
errors++;
continue;
}
i++;
ndbVector.push_back(pNdb);
if (pNdb->init()){
ERR(pNdb->getNdbError());
errors++;
continue;
}
init++;
} while (errors == 0);
ndbout << i << " ndb objects created" << endl;
Removed AttrType.hpp and moved the "internal" datatypes to their corresponding class. Moved NdbSchemaCon and NdbSchemaOp out of the public NdbApi, it can however still be used by old test programs. Added print oof indexes to desc. ndb/BinDist.sh: Removed AttrType.hpp from BinDist.sh ndb/include/ndbapi/Ndb.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbApi.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbConnection.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Moved internal types to the class where they are used ndb/include/ndbapi/NdbIndexOperation.hpp: Use limit from ndbapi_limit.h ndb/include/ndbapi/NdbOperation.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Remove faulty comment about how many attributes a key is allowed to consist of Removed unused member variables ndb/include/ndbapi/NdbRecAttr.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbSchemaCon.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbSchemaOp.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Moved all "old" datatypes here, so if a test program is still using old type, include NdbSchemaCon.hpp ndb/include/ndbapi/ndbapi_limits.h: Corrected limitations, added some from AttrTyp.hpp ndb/src/Makefile: Remove newtonapi from Makefile ndb/src/kernel/blocks/backup/restore/Restore.hpp: Removed AttrType Include NdbSchemaCon since restore uses old types ndb/src/kernel/blocks/backup/restore/main.cpp: Include NdbOut ndb/src/mgmsrv/MgmtSrvr.cpp: Remov AttrType.hpp ndb/src/ndbapi/ClusterMgr.cpp: Remov AttrType.hpp ndb/src/ndbapi/Ndb.cpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Moved internal types to the class where they are used ndb/src/ndbapi/NdbApiSignal.cpp: Removed AttrType.hpp ndb/src/ndbapi/NdbApiSignal.hpp: Removed AttrType.hpp ndb/src/ndbapi/NdbConnection.cpp: Moved internal type s to the class where they belong ndb/src/ndbapi/NdbDictionaryImpl.cpp: RemovedAttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbEventOperationImpl.cpp: Removed AttrType.hpp Moved printRecAttr to end since it depends on old types and need to include "NdbSchemaCon", function will be rewritten and moved to NdbRecAttr. It's also useful from other places where an attribute has been read into an NdbRecAttr. ndb/src/ndbapi/NdbIndexOperation.cpp: Use limitations from ndbapi_limits.h Moved internal tyeps to the class where they belongs ndb/src/ndbapi/NdbOperation.cpp: Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbOperationDefine.cpp: Remove AttrType.hpp ndb/src/ndbapi/NdbOperationExec.cpp: Moved internal tyeps to the class where they belongs ndb/src/ndbapi/NdbOperationInt.cpp: RemovedAttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbOperationScan.cpp: RemovedAttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbOperationSearch.cpp: Removed AttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbResultSet.cpp: Moved the "internal" types to corresponding class ndb/src/ndbapi/NdbSchemaCon.cpp: Updated not to be included in public NdbApi ndb/src/ndbapi/NdbSchemaOp.cpp: Updated not to be included in public NdbApi ndb/src/ndbapi/NdbUtil.hpp: Removed AttrType.hpp ndb/src/ndbapi/Ndbif.cpp: Removed AttrType.hpp Removed NdbSchemaCon and NdbSchemaOp from public NdbApi Moved "interal" types to their corresponding class ndb/src/ndbapi/Ndbinit.cpp: Removed NdbSchemaCon and NdbSchemaOp from public NdbApi ndb/src/ndbapi/Ndblist.cpp: Removed NdbSchemaCon and NdbSchemaOp from public NdbApi Moved "internal" types to their corresponding class ndb/src/ndbapi/TransporterFacade.cpp: Removed AttrType.hpp ndb/src/ndbapi/TransporterFacade.hpp: Removed AttrType.hpp Moved internal definition of how many Ndb objects to create to here ndb/test/include/NDBT_Table.hpp: Removed old NdbSchema* Added function to print information about an index ndb/test/ndbapi/acid/acid.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/flexAsynch/flexAsynch.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/flexScan/flexScan.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/interpreterInTup/interpreterInTup.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/lmc-bench/src/user/userInterface.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/ronja/initronja/initronja.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/telco/msa.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/testDataBuffers/testDataBuffers.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/testNdbApi/testNdbApi.cpp: Remove AttrType.hpp Define max number of Ndb objects test should "try" to create. ndb/test/ndbapi/testRestartGci/testRestartGci.cpp: Moved "internal" datatypes to corresponding class, in this case Ndb class ndb/test/src/NDBT_ResultRow.cpp: This test program uses old NdbScheaCon.hpp But should soon use "printer" from NdbRecAttr ndb/test/src/NDBT_Table.cpp: Print table info more SQL like ndb/test/src/UtilTransactions.cpp: When AttrType.hpp, this hidden bug was discovered. Using wrong enum types in switch. ndb/tools/desc/desc.cpp: Alos print info about indexes for a table
2004-05-25 11:53:07 +02:00
if (l > 0 && i != oldi && init != MAX_NDB_OBJECTS){
ndbout << l << ": not as manyNdb objects created" << endl
<< i << " != " << oldi << endl;
result = NDBT_FAILED;
}
oldi = i;
for(size_t i = 0; i < ndbVector.size(); i++){
delete ndbVector[i];
if(((i+1) % 250) == 0){
ndbout << "Deleted " << (Uint64) i << " ndb objects " << endl;
}
}
ndbVector.clear();
l++;
}
return result;
}
int runTestMaxTransaction(NDBT_Context* ctx, NDBT_Step* step){
Uint32 loops = ctx->getNumLoops();
Uint32 l = 0;
int oldi = 0;
int result = NDBT_OK;
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init(2048)){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
while (l < loops && result == NDBT_OK){
int errors = 0;
int maxErrors = 5;
Vector<NdbConnection*> conVector;
int i = 0;
do {
NdbConnection* pCon;
int type = i%4;
switch (type){
case 0:
pCon = pNdb->startTransaction();
break;
case 1:
pCon = pNdb->startTransaction(2,
"DATA",
4);
break;
case 2:
pCon = pNdb->startTransactionDGroup(1,
"TEST",
0);
break;
case 3:
pCon = pNdb->startTransactionDGroup(2,
"TEST",
1);
break;
default:
abort();
}
if (pCon == NULL){
ERR(pNdb->getNdbError());
errors++;
continue;
}
conVector.push_back(pCon);
i++;
} while (errors < maxErrors);
ndbout << i << " connections created" << endl;
if (l > 0 && i != oldi){
ndbout << l << ": not as many transactions created" << endl
<< i << " != " << oldi << endl;
result = NDBT_FAILED;
}
oldi = i;
for(size_t i = 0; i < conVector.size(); i++){
pNdb->closeTransaction(conVector[i]);
}
conVector.clear();
l++;
}
// BONUS Test closeTransaction with null trans
pNdb->closeTransaction(NULL);
delete pNdb;
return result;
}
int runTestMaxOperations(NDBT_Context* ctx, NDBT_Step* step){
Uint32 l = 1;
int result = NDBT_OK;
int maxOpsLimit = 1;
const NdbDictionary::Table* pTab = ctx->getTab();
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init(2048)){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
HugoOperations hugoOps(*pTab);
bool endTest = false;
while (!endTest && result == NDBT_OK){
int errors = 0;
int maxErrors = 5;
maxOpsLimit = l*1000;
if (hugoOps.startTransaction(pNdb) != NDBT_OK){
delete pNdb;
return NDBT_FAILED;
}
int i = 0;
while (errors < maxErrors){
if(hugoOps.pkReadRecord(pNdb,1, false, 1) != NDBT_OK){
errors++;
continue;
}
i++;
if (i >= maxOpsLimit){
errors = maxErrors;
}
}
ndbout << i << " operations used" << endl;
int execResult = hugoOps.execute_Commit(pNdb);
switch(execResult){
case NDBT_OK:
break;
case 233: // Out of operation records in transaction coordinator
// OK - end test
endTest = true;
break;
default:
result = NDBT_FAILED;
break;
}
hugoOps.closeTransaction(pNdb);
l++;
}
delete pNdb;
return result;
}
int runTestGetValue(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const NdbDictionary::Table* pTab = ctx->getTab();
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init(2048)){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
HugoOperations hugoOps(*pTab);
for (int m = 1; m < 100; m++){
int errors = 0;
int maxErrors = 5;
NdbConnection* pCon = pNdb->startTransaction();
if (pCon == NULL){
delete pNdb;
return NDBT_FAILED;
}
NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
if (pOp == NULL){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
if (pOp->readTuple() != 0){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
for(int a = 0; a<pTab->getNoOfColumns(); a++){
if (pTab->getColumn(a)->getPrimaryKey() == true){
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
}
}
int i = 0;
int maxLimit = 1000*m;
do {
if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
const NdbError err = pCon->getNdbError();
ERR(err);
if (err.code == 0)
result = NDBT_FAILED;
errors++;
continue;
}
i++;
} while (errors < maxErrors && i < maxLimit);
ndbout << i << " getValues called" << endl;
if (pCon->execute(Commit) != 0){
const NdbError err = pCon->getNdbError();
switch(err.code){
case 880: // TUP - Read too much
case 823: // TUP - Too much AI
case 4257: // NDBAPI - Too much AI
// OK errors
ERR(pCon->getNdbError());
break;
default:
ERR(pCon->getNdbError());
ndbout << "Illegal error" << endl;
result= NDBT_FAILED;
break;
}
}
pNdb->closeTransaction(pCon);
}// m
delete pNdb;
return result;
}
int runTestEqual(NDBT_Context* ctx, NDBT_Step* step){
Uint32 loops = ctx->getNumLoops();
Uint32 l = 0;
int result = NDBT_OK;
const NdbDictionary::Table* pTab = ctx->getTab();
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init(2048)){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
HugoOperations hugoOps(*pTab);
while (l < loops){
for(int m = 1; m < 10; m++){
int errors = 0;
int maxErrors = 5;
NdbConnection* pCon = pNdb->startTransaction();
if (pCon == NULL){
ndbout << "Could not start transaction" << endl;
delete pNdb;
return NDBT_FAILED;
}
NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
if (pOp == NULL){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
if (pOp->readTuple() != 0){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
int i = 0;
int maxLimit = 1000*m;
do {
if ((l%2)!=0){
// Forward
for(int a = 0; a<pTab->getNoOfColumns(); a++){
if (pTab->getColumn(a)->getPrimaryKey() == true){
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
const NdbError err = pCon->getNdbError();
ERR(err);
if (err.code == 0)
result = NDBT_FAILED;
errors++;
}
}
}
} else {
// Backward
for(int a = pTab->getNoOfColumns()-1; a>=0; a--){
if (pTab->getColumn(a)->getPrimaryKey() == true){
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
const NdbError err = pCon->getNdbError();
ERR(err);
if (err.code == 0)
result = NDBT_FAILED;
errors++;
}
}
}
}
i++;
} while (errors < maxErrors && i < maxLimit);
if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
const NdbError err = pCon->getNdbError();
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
if (err.code == 4225) {
return NDBT_OK;
} else {
return NDBT_FAILED;
}//if
}
ndbout << i << " equal called" << endl;
int check = pCon->execute(Commit);
if (check != 0){
ERR(pCon->getNdbError());
}
pNdb->closeTransaction(pCon);
}// m
l++;
}// l
delete pNdb;
return result;
}
int runTestDeleteNdb(NDBT_Context* ctx, NDBT_Step* step){
Uint32 loops = ctx->getNumLoops();
Uint32 l = 0;
int result = NDBT_OK;
NdbRestarts restarts;
Vector<Ndb*> ndbVector;
const NdbDictionary::Table* pTab = ctx->getTab();
HugoTransactions hugoTrans(*pTab);
int records = ctx->getNumRecords();
while (l < loops && result == NDBT_OK){
// Create 5 ndb objects
for( int i = 0; i < 5; i++){
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
result = NDBT_FAILED;
goto end_test;
}
ndbVector.push_back(pNdb);
if (pNdb->init()){
ERR(pNdb->getNdbError());
result = NDBT_FAILED;
goto end_test;
}
if (pNdb->waitUntilReady() != 0){
ERR(pNdb->getNdbError());
result = NDBT_FAILED;
goto end_test;
}
if (hugoTrans.pkReadRecords(pNdb, records) != 0){
result = NDBT_FAILED;
goto end_test;
}
}
if ((l % 2) == 0){
// Restart random node
ndbout << "Restart random node " << endl;
if(restarts.executeRestart("RestartRandomNodeAbort", 120) != 0){
g_err << "Failed to executeRestart(RestartRandomNode)"<<endl;
result = NDBT_FAILED;
goto end_test;
}
} else {
// Restart all nodes
ndbout << "Restart all nodes " << endl;
if(restarts.executeRestart("RestartAllNodesAbort", 120) != 0){
g_err << "Failed to executeRestart(RestartAllNodes)"<<endl;
result = NDBT_FAILED;
goto end_test;
}
}
// Delete the ndb objects
for(size_t i = 0; i < ndbVector.size(); i++)
delete ndbVector[i];
ndbVector.clear();
l++;
}
end_test:
for(size_t i = 0; i < ndbVector.size(); i++)
delete ndbVector[i];
ndbVector.clear();
return result;
}
int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
int records = ctx->getNumRecords();
UtilTransactions utilTrans(*ctx->getTab());
if (utilTrans.clearTable2(GETNDB(step), records) != 0){
return NDBT_FAILED;
}
return NDBT_OK;
}
int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
int records = ctx->getNumRecords();
HugoTransactions hugoTrans(*ctx->getTab());
if (hugoTrans.loadTable(GETNDB(step), records) != 0){
return NDBT_FAILED;
}
return NDBT_OK;
}
int runTestWaitUntilReady(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = new Ndb("TEST_DB");
// Forget about calling pNdb->init();
if (pNdb->waitUntilReady() == 0){
ndbout << "waitUntilReady returned OK" << endl;
delete pNdb;
return NDBT_FAILED;
}
const NdbError err = pNdb->getNdbError();
delete pNdb;
ERR(err);
if (err.code != 4256)
return NDBT_FAILED;
return NDBT_OK;
}
int runGetNdbOperationNoTab(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init()){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
NdbConnection* pCon = pNdb->startTransaction();
if (pCon == NULL){
delete pNdb;
return NDBT_FAILED;
}
// Call getNdbOperation on an unknown table
NdbOperation* pOp = pCon->getNdbOperation("HUPP76");
if (pOp == NULL){
NdbError err = pCon->getNdbError();
ERR(err);
if (err.code == 0){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
}
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_OK;
}
int runMissingOperation(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const NdbDictionary::Table* pTab = ctx->getTab();
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init()){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
NdbConnection* pCon = pNdb->startTransaction();
if (pCon == NULL){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
if (pOp == NULL){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
// Forget about calling pOp->insertTuple();
// Call getValue should not work
if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
const NdbError err = pCon->getNdbError();
ERR(err);
if (err.code == 0){
ndbout << "hupp" << endl;
result = NDBT_FAILED;
}
} else {
ndbout << "hupp2" << endl;
result = NDBT_FAILED;
}
pNdb->closeTransaction(pCon);
delete pNdb;
return result;
}
int runGetValueInUpdate(NDBT_Context* ctx, NDBT_Step* step){
const NdbDictionary::Table* pTab = ctx->getTab();
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init()){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
NdbConnection* pCon = pNdb->startTransaction();
if (pCon == NULL){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
if (pOp == NULL){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
if (pOp->updateTuple() != 0){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
// Call getValue should not work
if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
// It didn't work
const NdbError err = pCon->getNdbError();
ERR(err);
if (err.code == 0){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
} else {
// It worked, not good!
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
int check = pCon->execute(Commit);
if (check != 0){
ERR(pCon->getNdbError());
}
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_OK;
}
int runUpdateWithoutValues(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const NdbDictionary::Table* pTab = ctx->getTab();
HugoOperations hugoOps(*pTab);
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init()){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
NdbConnection* pCon = pNdb->startTransaction();
if (pCon == NULL){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
if (pOp == NULL){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
if (pOp->updateTuple() != 0){
pNdb->closeTransaction(pCon);
ERR(pOp->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
for(int a = 0; a<pTab->getNoOfColumns(); a++){
if (pTab->getColumn(a)->getPrimaryKey() == true){
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
}
}
// Dont' call any setValues
// Execute should not work
int check = pCon->execute(Commit);
if (check == 0){
ndbout << "execute worked" << endl;
result = NDBT_FAILED;
} else {
ERR(pCon->getNdbError());
}
pNdb->closeTransaction(pCon);
delete pNdb;
return result;
}
int runUpdateWithoutKeys(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const NdbDictionary::Table* pTab = ctx->getTab();
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init()){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
NdbConnection* pCon = pNdb->startTransaction();
if (pCon == NULL){
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
if (pOp == NULL){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
if (pOp->updateTuple() != 0){
pNdb->closeTransaction(pCon);
ERR(pOp->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
// Dont' call any equal or setValues
// Execute should not work
int check = pCon->execute(Commit);
if (check == 0){
ndbout << "execute worked" << endl;
result = NDBT_FAILED;
} else {
ERR(pCon->getNdbError());
}
pNdb->closeTransaction(pCon);
delete pNdb;
return result;
}
int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const NdbDictionary::Table* pTab = ctx->getTab();
Ndb* pNdb = new Ndb("TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init(2048)){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
HugoOperations hugoOps(*pTab);
NdbConnection* pCon = pNdb->startTransaction();
if (pCon == NULL){
ndbout << "Could not start transaction" << endl;
delete pNdb;
return NDBT_FAILED;
}
NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
if (pOp == NULL){
ERR(pCon->getNdbError());
pNdb->closeTransaction(pCon);
delete pNdb;
return NDBT_FAILED;
}
// Dont call readTuple here
// That's the error!
for(int a = 0; a<pTab->getNoOfColumns(); a++){
if (pTab->getColumn(a)->getPrimaryKey() == true){
if(hugoOps.equalForAttr(pOp, a, 1) != 0){
// An error has occured, check that
// it's possible to get the NdbErrorOperation
const NdbError err = pCon->getNdbError();
ERR(err);
if (err.code == 0)
result = NDBT_FAILED;
NdbOperation* pOp2 = pCon->getNdbErrorOperation();
if (pOp2 == NULL)
result = NDBT_FAILED;
else {
const NdbError err2 = pOp2->getNdbError();
ERR(err2);
if (err.code == 0)
result = NDBT_FAILED;
}
}
}
}
pNdb->closeTransaction(pCon);
delete pNdb;
return result;
}
NDBT_TESTSUITE(testNdbApi);
TESTCASE("MaxNdb",
"Create Ndb objects until no more can be created\n"){
INITIALIZER(runTestMaxNdb);
}
TESTCASE("MaxTransactions",
"Start transactions until no more can be created\n"){
INITIALIZER(runTestMaxTransaction);
}
TESTCASE("MaxOperations",
"Get operations until no more can be created\n"){
INITIALIZER(runLoadTable);
INITIALIZER(runTestMaxOperations);
FINALIZER(runClearTable);
}
TESTCASE("MaxGetValue",
"Call getValue loads of time\n"){
INITIALIZER(runLoadTable);
INITIALIZER(runTestGetValue);
FINALIZER(runClearTable);
}
TESTCASE("MaxEqual",
"Call equal loads of time\n"){
INITIALIZER(runTestEqual);
}
TESTCASE("DeleteNdb",
"Make sure that a deleted Ndb object is properly deleted\n"
"and removed from transporter\n"){
INITIALIZER(runLoadTable);
INITIALIZER(runTestDeleteNdb);
FINALIZER(runClearTable);
}
TESTCASE("WaitUntilReady",
"Make sure you get an error message when calling waitUntilReady\n"
"without an init'ed Ndb\n"){
INITIALIZER(runTestWaitUntilReady);
}
TESTCASE("GetOperationNoTab",
"Call getNdbOperation on a table that does not exist\n"){
INITIALIZER(runGetNdbOperationNoTab);
}
TESTCASE("MissingOperation",
"Missing operation request(insertTuple) should give an error code\n"){
INITIALIZER(runMissingOperation);
}
TESTCASE("GetValueInUpdate",
"Test that it's not possible to perform getValue in an update\n"){
INITIALIZER(runLoadTable);
INITIALIZER(runGetValueInUpdate);
FINALIZER(runClearTable);
}
TESTCASE("UpdateWithoutKeys",
"Test that it's not possible to perform update without setting\n"
"PKs"){
INITIALIZER(runLoadTable);
INITIALIZER(runUpdateWithoutKeys);
FINALIZER(runClearTable);
}
TESTCASE("UpdateWithoutValues",
"Test that it's not possible to perform update without setValues\n"){
INITIALIZER(runLoadTable);
INITIALIZER(runUpdateWithoutValues);
FINALIZER(runClearTable);
}
TESTCASE("NdbErrorOperation",
"Test that NdbErrorOperation is properly set"){
INITIALIZER(runCheckGetNdbErrorOperation);
}
NDBT_TESTSUITE_END(testNdbApi);
int main(int argc, const char** argv){
// TABLE("T1");
return testNdbApi.execute(argc, argv);
}