mariadb/ndb/test/ndbapi/testNdbApi.cpp
unknown f755e4aece wl2240 - ndb partitioning
1) Fix startTransaction with hint
2) Ship fragment data to API to make better guess
3) Expose both primary & backup replicas 
   To (in the future) be even more clever on choosing nodes for
   transactions/operations


ndb/include/kernel/ndb_limits.h:
  Set maxsize of array with fragment data
ndb/include/kernel/signaldata/DictTabInfo.hpp:
  Send fragment data to API
ndb/src/common/debugger/signaldata/DictTabInfo.cpp:
  Send fragment data to API
ndb/src/kernel/blocks/dbdict/Dbdict.cpp:
  Send fragment data to API
ndb/src/kernel/blocks/dbdict/Dbdict.hpp:
  Send fragment data to API
ndb/src/kernel/blocks/dbdih/DbdihMain.cpp:
  Use Uint16 for fragment info
  Fix uninit variable
ndb/src/ndbapi/Ndb.cpp:
  Impl. startTransaction with hint
ndb/src/ndbapi/NdbDictionaryImpl.cpp:
  Add interface for retreiving replica nodes given a hash-value
ndb/src/ndbapi/NdbDictionaryImpl.hpp:
  Add interface for retreiving replica nodes given a hash-value
ndb/src/ndbapi/ndb_cluster_connection.cpp:
  remove Fragment2NodeMap and put it on table instead
ndb/src/ndbapi/ndb_cluster_connection_impl.hpp:
  remove Fragment2NodeMap and put it on table instead
ndb/test/ndbapi/testNdbApi.cpp:
  Test some more
2005-01-10 14:40:54 +01:00

1012 lines
22 KiB
C++

/* 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>
#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(&ctx->m_cluster_connection, "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;
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 j = 0; j < ndbVector.size(); j++){
delete ndbVector[j];
if(((j+1) % 250) == 0){
ndbout << "Deleted " << (Uint64) j << " 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(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
}
if (pNdb->init(2048)){
ERR(pNdb->getNdbError());
delete pNdb;
return NDBT_FAILED;
}
const NdbDictionary::Table* pTab = ctx->getTab();
if (pTab == 0) abort();
while (l < loops && result == NDBT_OK){
int errors = 0;
int maxErrors = 5;
Vector<NdbConnection*> conVector;
int i = 0;
do {
NdbConnection* pCon;
int type = i%2;
switch (type){
case 0:
pCon = pNdb->startTransaction();
break;
case 1:
{
BaseString key;
key.appfmt("DATA-%d", i);
ndbout_c("%s", key.c_str());
pCon = pNdb->startTransaction(pTab,
key.c_str(),
key.length());
}
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 j = 0; j < conVector.size(); j++){
pNdb->closeTransaction(conVector[j]);
}
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(&ctx->m_cluster_connection, "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, 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(&ctx->m_cluster_connection, "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(&ctx->m_cluster_connection, "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(&ctx->m_cluster_connection, "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 j = 0; j < ndbVector.size(); j++)
delete ndbVector[j];
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(&ctx->m_cluster_connection, "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(&ctx->m_cluster_connection, "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(&ctx->m_cluster_connection, "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(&ctx->m_cluster_connection, "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(&ctx->m_cluster_connection, "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 work
int check = pCon->execute(Commit);
if (check == 0){
ndbout << "execute worked" << endl;
} else {
ERR(pCon->getNdbError());
result = NDBT_FAILED;
}
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(&ctx->m_cluster_connection, "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(&ctx->m_cluster_connection, "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){
ndb_init();
// TABLE("T1");
return testNdbApi.execute(argc, argv);
}
template class Vector<Ndb*>;
template class Vector<NdbConnection*>;