diff options
Diffstat (limited to 'ndb/test/ndbapi/testIndex.cpp')
-rw-r--r-- | ndb/test/ndbapi/testIndex.cpp | 1495 |
1 files changed, 1495 insertions, 0 deletions
diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp new file mode 100644 index 00000000000..47db0b3cff7 --- /dev/null +++ b/ndb/test/ndbapi/testIndex.cpp @@ -0,0 +1,1495 @@ +/* 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 <signaldata/DumpStateOrd.hpp> + +#define CHECK(b) if (!(b)) { \ + g_err << "ERR: "<< step->getName() \ + << " failed on line " << __LINE__ << endl; \ + result = NDBT_FAILED; \ +} + + +struct Attrib { + bool indexCreated; + int numAttribs; + int attribs[1024]; + Attrib(){ + numAttribs = 0; + indexCreated = false; + } +}; +class AttribList { +public: + AttribList(){}; + ~AttribList(){ + for(size_t i = 0; i < attriblist.size(); i++){ + delete attriblist[i]; + } + }; + void buildAttribList(const NdbDictionary::Table* pTab); + Vector<Attrib*> attriblist; +}; + +void AttribList::buildAttribList(const NdbDictionary::Table* pTab){ + attriblist.clear(); + + Attrib* attr; + // Build attrib definitions that describes which attributes to build index + // Try to build strange combinations, not just "all" or all PK's + + for(int i = 1; i <= pTab->getNoOfColumns(); i++){ + attr = new Attrib; + attr->numAttribs = i; + for(int a = 0; a<i; a++) + attr->attribs[a] = a; + attriblist.push_back(attr); + } + int b = 0; + for(int i = pTab->getNoOfColumns()-1; i > 0; i--){ + attr = new Attrib; + attr->numAttribs = i; + b++; + for(int a = 0; a<i; a++) + attr->attribs[a] = a+b; + attriblist.push_back(attr); + } + for(int i = pTab->getNoOfColumns(); i > 0; i--){ + attr = new Attrib; + attr->numAttribs = pTab->getNoOfColumns() - i; + for(int a = 0; a<pTab->getNoOfColumns() - i; a++) + attr->attribs[a] = pTab->getNoOfColumns()-a-1; + attriblist.push_back(attr); + } + for(int i = 1; i < pTab->getNoOfColumns(); i++){ + attr = new Attrib; + attr->numAttribs = pTab->getNoOfColumns() - i; + for(int a = 0; a<pTab->getNoOfColumns() - i; a++) + attr->attribs[a] = pTab->getNoOfColumns()-a-1; + attriblist.push_back(attr); + } + for(int i = 1; i < pTab->getNoOfColumns(); i++){ + attr = new Attrib; + attr->numAttribs = 2; + for(int a = 0; a<2; a++){ + attr->attribs[a] = i%pTab->getNoOfColumns(); + } + attriblist.push_back(attr); + } + + // Last + attr = new Attrib; + attr->numAttribs = 1; + attr->attribs[0] = pTab->getNoOfColumns()-1; + attriblist.push_back(attr); + + // Last and first + attr = new Attrib; + attr->numAttribs = 2; + attr->attribs[0] = pTab->getNoOfColumns()-1; + attr->attribs[1] = 0; + attriblist.push_back(attr); + + // First and last + attr = new Attrib; + attr->numAttribs = 2; + attr->attribs[0] = 0; + attr->attribs[1] = pTab->getNoOfColumns()-1; + attriblist.push_back(attr); + +#if 0 + for(size_t i = 0; i < attriblist.size(); i++){ + + ndbout << attriblist[i]->numAttribs << ": " ; + for(int a = 0; a < attriblist[i]->numAttribs; a++) + ndbout << attriblist[i]->attribs[a] << ", "; + ndbout << endl; + } +#endif + +} + +char idxName[255]; +char pkIdxName[255]; + +static const int SKIP_INDEX = 99; + +int create_index(NDBT_Context* ctx, int indxNum, + const NdbDictionary::Table* pTab, + Ndb* pNdb, Attrib* attr, bool logged){ + bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0); + int result = NDBT_OK; + + HugoCalculator calc(*pTab); + + if (attr->numAttribs == 1 && + calc.isUpdateCol(attr->attribs[0]) == true){ + // Don't create index for the Hugo update column + // since it's not unique + return SKIP_INDEX; + } + + // Create index + snprintf(idxName, 255, "IDC%d", indxNum); + if (orderedIndex) + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "<<idxName << " ("; + else + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "<<idxName << " ("; + ndbout << flush; + NdbDictionary::Index pIdx(idxName); + pIdx.setTable(pTab->getName()); + if (orderedIndex) + pIdx.setType(NdbDictionary::Index::OrderedIndex); + else + pIdx.setType(NdbDictionary::Index::UniqueHashIndex); + for (int c = 0; c< attr->numAttribs; c++){ + int attrNo = attr->attribs[c]; + pIdx.addIndexColumn(pTab->getColumn(attrNo)->getName()); + ndbout << pTab->getColumn(attrNo)->getName()<<" "; + } + + pIdx.setStoredIndex(logged); + ndbout << ") "; + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + attr->indexCreated = false; + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + if(err.classification == NdbError::ApplicationError) + return SKIP_INDEX; + + return NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + attr->indexCreated = true; + } + return result; +} + + +int drop_index(int indxNum, Ndb* pNdb, + const NdbDictionary::Table* pTab, Attrib* attr){ + int result = NDBT_OK; + + if (attr->indexCreated == false) + return NDBT_OK; + + snprintf(idxName, 255, "IDC%d", indxNum); + + // Drop index + ndbout << "Dropping index "<<idxName<<"(" << pTab->getName() << ") "; + if (pNdb->getDictionary()->dropIndex(idxName, pTab->getName()) != 0){ + ndbout << "FAILED!" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + result = NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + } + return result; +} + +int runCreateIndexes(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int l = 0; + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + // NOTE If we need to test creating both logged and non logged indexes + // this should be divided into two testcases + // The paramater logged should then be specified + // as a TC_PROPERTY. ex TC_PROPERTY("LoggedIndexes", 1); + // and read into the test step like + bool logged = ctx->getProperty("LoggedIndexes", 1); + + AttribList attrList; + attrList.buildAttribList(pTab); + + + while (l < loops && result == NDBT_OK){ + + for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + + // Try to create index + if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED) + result = NDBT_FAILED; + } + + // Now drop all indexes that where created + for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + + // Try to drop index + if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK) + result = NDBT_FAILED; + } + + l++; + } + + return result; +} + +int createRandomIndex(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + bool logged = ctx->getProperty("LoggedIndexes", 1); + + AttribList attrList; + attrList.buildAttribList(pTab); + + int retries = 100; + while(retries > 0){ + const Uint32 i = rand() % attrList.attriblist.size(); + int res = create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], + logged); + if (res == SKIP_INDEX){ + retries--; + continue; + } + + if (res == NDBT_FAILED){ + return NDBT_FAILED; + } + + ctx->setProperty("createRandomIndex", i); + // Now drop all indexes that where created + + return NDBT_OK; + } + + return NDBT_FAILED; +} + +int createRandomIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + + Uint32 i = ctx->getProperty("createRandomIndex"); + + snprintf(idxName, 255, "IDC%d", i); + + // Drop index + ndbout << "Dropping index " << idxName << " "; + if (pNdb->getDictionary()->dropIndex(idxName, + ctx->getTab()->getName()) != 0){ + ndbout << "FAILED!" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + } + + return NDBT_OK; +} + +int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){ + bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0); + + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + + bool logged = ctx->getProperty("LoggedIndexes", 1); + + // Create index + snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName()); + if (orderedIndex) + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index " + << pkIdxName << " ("; + else + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index " + << pkIdxName << " ("; + + NdbDictionary::Index pIdx(pkIdxName); + pIdx.setTable(pTab->getName()); + if (orderedIndex) + pIdx.setType(NdbDictionary::Index::OrderedIndex); + else + pIdx.setType(NdbDictionary::Index::UniqueHashIndex); + for (int c = 0; c< pTab->getNoOfColumns(); c++){ + const NdbDictionary::Column * col = pTab->getColumn(c); + if(col->getPrimaryKey()){ + pIdx.addIndexColumn(col->getName()); + ndbout << col->getName() <<" "; + } + } + + pIdx.setStoredIndex(logged); + ndbout << ") "; + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + return NDBT_FAILED; + } + + ndbout << "OK!" << endl; + return NDBT_OK; +} + +int createPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){ + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + + // Drop index + ndbout << "Dropping index " << pkIdxName << " "; + if (pNdb->getDictionary()->dropIndex(pkIdxName, + pTab->getName()) != 0){ + ndbout << "FAILED!" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + } + + return NDBT_OK; +} + +int +runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + UtilTransactions utilTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 16); + const int parallelism = batchSize > 240 ? 240 : batchSize; + + do { + if (utilTrans.verifyIndex(pNdb, idxName, parallelism, true) != 0){ + g_err << "Inconsistent index" << endl; + return NDBT_FAILED; + } + } while(ctx->isTestStopped() == false); + return NDBT_OK; +} + +int +runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 50); + + int rows = ctx->getNumRecords(); + while (ctx->isTestStopped() == false) { + if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + return NDBT_FAILED; + } + if (hugoTrans.scanUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + return NDBT_FAILED; + } + } + return NDBT_OK; +} + +int +runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 50); + + int rows = ctx->getNumRecords(); + while (ctx->isTestStopped() == false) { +#if 1 + if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){ + g_err << "Index read failed" << endl; + return NDBT_FAILED; + } +#endif + + if(ctx->isTestStopped()) + break; +#if 1 + if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){ + g_err << "Index update failed" << endl; + return NDBT_FAILED; + } +#endif + } + return NDBT_OK; +} + +int +runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + UtilTransactions utilTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 32); + const int parallel = batchSize > 240 ? 240 : batchSize; + + int rows = ctx->getNumRecords(); + while (ctx->isTestStopped() == false) { + if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){ + g_err << "Load table failed" << endl; + return NDBT_FAILED; + } + if(ctx->isTestStopped()) + break; + + if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + return NDBT_FAILED; + } + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){ + g_err << "Index read failed" << endl; + return NDBT_FAILED; + } + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){ + g_err << "Index update failed" << endl; + return NDBT_FAILED; + } + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){ + g_err << "Scan updated table failed" << endl; + return NDBT_FAILED; + } + + if(ctx->isTestStopped()) + break; + + if(utilTrans.clearTable(pNdb, rows, parallel) != 0){ + g_err << "Clear table failed" << endl; + return NDBT_FAILED; + } + if(ctx->isTestStopped()) + break; + + int count = -1; + if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0) + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + NDBT_TestCase* pCase = ctx->getCase(); + NdbRestarts restarts; + int i = 0; + int timeout = 240; + + while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){ + if(restarts.executeRestart("RestartRandomNodeAbort", timeout) != 0){ + g_err << "Failed to executeRestart(" <<pCase->getName() <<")" << endl; + result = NDBT_FAILED; + break; + } + i++; + } + ctx->stopTest(); + return result; +} + +int runCreateLoadDropIndex(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int l = 0; + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int batchSize = ctx->getProperty("BatchSize", 1); + int parallelism = batchSize > 240? 240: batchSize; + ndbout << "batchSize="<<batchSize<<endl; + bool logged = ctx->getProperty("LoggedIndexes", 1); + + HugoTransactions hugoTrans(*pTab); + UtilTransactions utilTrans(*pTab); + AttribList attrList; + attrList.buildAttribList(pTab); + + for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + + while (l < loops && result == NDBT_OK){ + + if ((l % 2) == 0){ + // Create index first and then load + + // Try to create index + if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED){ + result = NDBT_FAILED; + } + + // Load the table with data + ndbout << "Loading data after" << endl; + CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); + + + } else { + // Load table then create index + + // Load the table with data + ndbout << "Loading data before" << endl; + CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); + + // Try to create index + if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED) + result = NDBT_FAILED; + + } + + // Verify that data in index match + // table data + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + + // Do it all... + ndbout <<"Doing it all"<<endl; + int count; + ndbout << " pkUpdateRecords" << endl; + CHECK(hugoTrans.pkUpdateRecords(pNdb, records, batchSize) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records, batchSize) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + ndbout << " pkDelRecords half" << endl; + CHECK(hugoTrans.pkDelRecords(pNdb, records/2, batchSize) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + ndbout << " scanUpdateRecords" << endl; + CHECK(hugoTrans.scanUpdateRecords(pNdb, records/2, parallelism) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + ndbout << " clearTable" << endl; + CHECK(utilTrans.clearTable(pNdb, records/2, parallelism) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + ndbout << " loadTable" << endl; + CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + ndbout << " loadTable again" << endl; + CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + + + if ((l % 2) == 0){ + // Drop index first and then clear + + // Try to create index + if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK){ + result = NDBT_FAILED; + } + + // Clear table + ndbout << "Clearing table after" << endl; + CHECK(hugoTrans.clearTable(pNdb, records, parallelism) == 0); + + + } else { + // Clear table then drop index + + //Clear table + ndbout << "Clearing table before" << endl; + CHECK(hugoTrans.clearTable(pNdb, records, parallelism) == 0); + + // Try to drop index + if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK) + result = NDBT_FAILED; + } + + ndbout << " Done!" << endl; + l++; + } + + // Make sure index is dropped + drop_index(i, pNdb, pTab, attrList.attriblist[i]); + + } + + return result; +} + +int runInsertDelete(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + const NdbDictionary::Table* pTab = ctx->getTab(); + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int batchSize = ctx->getProperty("BatchSize", 1); + int parallelism = batchSize > 240? 240: batchSize; + ndbout << "batchSize="<<batchSize<<endl; + bool logged = ctx->getProperty("LoggedIndexes", 1); + + HugoTransactions hugoTrans(*pTab); + UtilTransactions utilTrans(*pTab); + + AttribList attrList; + attrList.buildAttribList(pTab); + + for (unsigned int i = 0; i < attrList.attriblist.size(); i++){ + + Attrib* attr = attrList.attriblist[i]; + // Create index + if (create_index(ctx, i, pTab, pNdb, attr, logged) == NDBT_OK){ + int l = 1; + while (l <= loops && result == NDBT_OK){ + + CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + CHECK(utilTrans.clearTable(pNdb, records, parallelism) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0); + l++; + } + + // Drop index + if (drop_index(i, pNdb, pTab, attr) != NDBT_OK) + result = NDBT_FAILED; + } + } + + return result; +} +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + HugoTransactions hugoTrans(*ctx->getTab()); + int batchSize = ctx->getProperty("BatchSize", 1); + if(hugoTrans.loadTable(GETNDB(step), records, batchSize) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + + +int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ + int records = ctx->getNumRecords(); + + UtilTransactions utilTrans(*ctx->getTab()); + if (utilTrans.clearTable(GETNDB(step), records) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} + +int runSystemRestart1(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + int result = NDBT_OK; + int timeout = 300; + Uint32 loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + int count; + NdbRestarter restarter; + Uint32 i = 1; + + UtilTransactions utilTrans(*ctx->getTab()); + HugoTransactions hugoTrans(*ctx->getTab()); + const char * name = ctx->getTab()->getName(); + while(i<=loops && result != NDBT_FAILED){ + + ndbout << "Loop " << i << "/"<< loops <<" started" << endl; + /* + 1. Load data + 2. Restart cluster and verify records + 3. Update records + 4. Restart cluster and verify records + 5. Delete half of the records + 6. Restart cluster and verify records + 7. Delete all records + 8. Restart cluster and verify records + 9. Insert, update, delete records + 10. Restart cluster and verify records + 11. Insert, update, delete records + 12. Restart cluster with error insert 5020 and verify records + */ + ndbout << "Loading records..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Restarting cluster" << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Updating records..." << endl; + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == records); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Deleting 50% of records..." << endl; + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0); + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == (records/2)); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Deleting all records..." << endl; + CHECK(utilTrans.clearTable(pNdb, records/2) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + + ndbout << "Doing it all..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + + ndbout << "Restarting cluster..." << endl; + CHECK(restarter.restartAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + ndbout << "Verifying records..." << endl; + CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); + CHECK(count == 0); + + ndbout << "Doing it all..." << endl; + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); + CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0); + CHECK(utilTrans.clearTable(pNdb, records) == 0); + + ndbout << "Restarting cluster with error insert 5020..." << endl; + CHECK(restarter.restartAll(false, true) == 0); + CHECK(restarter.waitClusterNoStart(timeout) == 0); + CHECK(restarter.insertErrorInAllNodes(5020) == 0); + CHECK(restarter.startAll() == 0); + CHECK(restarter.waitClusterStarted(timeout) == 0); + CHECK(pNdb->waitUntilReady(timeout) == 0); + + i++; + } + + ctx->stopTest(); + ndbout << "runSystemRestart1 finished" << endl; + + return result; +} + +#define CHECK2(b, t) if(!b){ g_err << __LINE__ << ": " << t << endl; break;} + +int +runMixed1(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoOperations hugoOps(*ctx->getTab()); + + + do { + // TC1 + g_err << "pkRead, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + // TC1 + g_err << "pkRead, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + + // TC2 + g_err << "pkRead, indexRead, NoCommit, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, + "indexReadRecords"); + CHECK2(hugoOps.execute_NoCommit(pNdb) == 0, "executeNoCommit"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + // TC3 + g_err << "pkRead, pkRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords "); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + + // TC4 + g_err << "indexRead, indexRead, Commit" << endl; + + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + + return NDBT_OK; + } while(false); + + + hugoOps.closeTransaction(pNdb); + return NDBT_FAILED; +} + +int +runBuildDuring(NDBT_Context* ctx, NDBT_Step* step){ + // Verify that data in index match + // table data + const int Threads = ctx->getProperty("Threads", (Uint32)0); + const int loops = ctx->getNumLoops(); + + for(int i = 0; i<loops; i++){ +#if 1 + if(createPkIndex(ctx, step) != NDBT_OK){ + g_err << "Failed to create index" << endl; + return NDBT_FAILED; + } +#endif + + if(ctx->isTestStopped()) + break; + +#if 1 + if(createRandomIndex(ctx, step) != NDBT_OK){ + g_err << "Failed to create index" << endl; + return NDBT_FAILED; + } +#endif + + if(ctx->isTestStopped()) + break; + + ctx->setProperty("pause", 1); + int count = 0; + for(int j = 0; count < Threads && !ctx->isTestStopped(); + j = (j+1) % Threads){ + char buf[255]; + sprintf(buf, "Thread%d_paused", j); + int tmp = ctx->getProperty(buf, (Uint32)0); + count += tmp; + } + + if(ctx->isTestStopped()) + break; + +#if 1 + if(createPkIndex_Drop(ctx, step) != NDBT_OK){ + g_err << "Failed to drop index" << endl; + return NDBT_FAILED; + } +#endif + + if(ctx->isTestStopped()) + break; + +#if 1 + if(createRandomIndex_Drop(ctx, step) != NDBT_OK){ + g_err << "Failed to drop index" << endl; + return NDBT_FAILED; + } +#endif + + ctx->setProperty("pause", (Uint32)0); + NdbSleep_SecSleep(2); + } + + ctx->stopTest(); + return NDBT_OK; +} + +static NdbLockable g_lock; +static int threadCounter = 0; + +void +wait_paused(NDBT_Context* ctx, int id){ + if(ctx->getProperty("pause", (Uint32)0) == 1){ + char buf[255]; + sprintf(buf, "Thread%d_paused", id); + ctx->setProperty(buf, 1); + while(!ctx->isTestStopped() && ctx->getProperty("pause", (Uint32)0) == 1){ + NdbSleep_MilliSleep(250); + } + ctx->setProperty(buf, (Uint32)0); + } +} + +int +runTransactions4(NDBT_Context* ctx, NDBT_Step* step){ + + g_lock.lock(); + const int ThreadId = threadCounter++; + g_lock.unlock(); + + // Verify that data in index match + // table data + Ndb* pNdb = GETNDB(step); + HugoTransactions hugoTrans(*ctx->getTab()); + UtilTransactions utilTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 32); + const int parallel = batchSize > 240 ? 240 : batchSize; + + int rows = ctx->getNumRecords(); + while (ctx->isTestStopped() == false) { + if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){ + g_err << "Load table failed" << endl; + return NDBT_FAILED; + } + + wait_paused(ctx, ThreadId); + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + return NDBT_FAILED; + } + + wait_paused(ctx, ThreadId); + + if(ctx->isTestStopped()) + break; + + if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){ + g_err << "Scan updated table failed" << endl; + return NDBT_FAILED; + } + + wait_paused(ctx, ThreadId); + + if(ctx->isTestStopped()) + break; + + if(utilTrans.clearTable(pNdb, rows, parallel) != 0){ + g_err << "Clear table failed" << endl; + return NDBT_FAILED; + } + } + return NDBT_OK; +} + +int +runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + + bool logged = ctx->getProperty("LoggedIndexes", 1); + bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0); + NdbConnection * pTrans = 0; + + const NdbDictionary::Table* pTab = ctx->getTab(); + // Create index + char nullIndex[255]; + snprintf(nullIndex, 255, "IDC_PK_%s_NULL", pTab->getName()); + if (orderedIndex) + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index " + << pkIdxName << " ("; + else + ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index " + << pkIdxName << " ("; + + NdbDictionary::Index pIdx(pkIdxName); + pIdx.setTable(pTab->getName()); + if (orderedIndex) + pIdx.setType(NdbDictionary::Index::OrderedIndex); + else + pIdx.setType(NdbDictionary::Index::UniqueHashIndex); + pIdx.setStoredIndex(logged); + + for (int c = 0; c< pTab->getNoOfColumns(); c++){ + const NdbDictionary::Column * col = pTab->getColumn(c); + if(col->getPrimaryKey()){ + pIdx.addIndexColumn(col->getName()); + ndbout << col->getName() <<" "; + } + } + + int colId = -1; + for (int c = 0; c< pTab->getNoOfColumns(); c++){ + const NdbDictionary::Column * col = pTab->getColumn(c); + if(col->getNullable()){ + pIdx.addIndexColumn(col->getName()); + ndbout << col->getName() <<" "; + colId = c; + break; + } + } + ndbout << ") "; + + if(colId == -1){ + ndbout << endl << "No nullable column found -> NDBT_FAILED" << endl; + return NDBT_FAILED; + } + + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + return NDBT_FAILED; + } + + int result = NDBT_OK; + + HugoTransactions hugoTrans(*ctx->getTab()); + const int batchSize = ctx->getProperty("BatchSize", 50); + int loops = ctx->getNumLoops(); + int rows = ctx->getNumRecords(); + while (loops-- > 0 && ctx->isTestStopped() == false) { + if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){ + g_err << "Updated table failed" << endl; + result = NDBT_FAILED; + goto done; + } + } + + if(ctx->isTestStopped()){ + goto done; + } + + ctx->stopTest(); + while(ctx->getNoOfRunningSteps() > 1){ + NdbSleep_MilliSleep(100); + } + + result = NDBT_FAILED; + pTrans = pNdb->startTransaction(); + NdbScanOperation * sOp; + NdbOperation * uOp; + NdbResultSet * rs; + int eof; + if(!pTrans) goto done; + sOp = pTrans->getNdbScanOperation(pTab->getName()); + if(!sOp) goto done; + rs = sOp->readTuples(240, NdbScanOperation::LM_Exclusive); + if(!rs) goto done; + if(pTrans->execute(NoCommit) == -1) goto done; + while((eof = rs->nextResult(true)) == 0){ + do { + NdbOperation * uOp = rs->updateTuple(); + if(uOp == 0) goto done; + uOp->setValue(colId, 0); + } while((eof = rs->nextResult(false)) == 0); + eof = pTrans->execute(Commit); + if(eof == -1) goto done; + } + + done: + if(pTrans) pNdb->closeTransaction(pTrans); + pNdb->getDictionary()->dropIndex(nullIndex, pTab->getName()); + return result; +} + +int runLQHKEYREF(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops() * 100; + NdbRestarter restarter; + + myRandom48Init(NdbTick_CurrentMillisecond()); + +#if 0 + int val = DumpStateOrd::DihMinTimeBetweenLCP; + if(restarter.dumpStateAllNodes(&val, 1) != 0){ + g_err << "Failed to dump DihMinTimeBetweenLCP" << endl; + return NDBT_FAILED; + } +#endif + + for(int i = 0; i<loops && !ctx->isTestStopped(); i++){ + int randomId = myRandom48(restarter.getNumDbNodes()); + int nodeId = restarter.getDbNodeId(randomId); + + const Uint32 error = 5031 + (i % 3); + + if(restarter.insertErrorInNode(nodeId, error) != 0){ + g_err << "Failed to error insert( " << error << ") in node " + << nodeId << endl; + return NDBT_FAILED; + } + } + + ctx->stopTest(); + return NDBT_OK; +} + +NDBT_TESTSUITE(testIndex); +TESTCASE("CreateAll", + "Test that we can create all various indexes on each table\n" + "Then drop the indexes\n"){ + INITIALIZER(runCreateIndexes); +} +TESTCASE("CreateAll_O", + "Test that we can create all various indexes on each table\n" + "Then drop the indexes\n"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runCreateIndexes); +} +TESTCASE("InsertDeleteGentle", + "Create one index, then perform insert and delete in the table\n" + "loop number of times. Use batch size 1."){ + TC_PROPERTY("BatchSize", 1); + INITIALIZER(runInsertDelete); + FINALIZER(runClearTable); +} +TESTCASE("InsertDeleteGentle_O", + "Create one index, then perform insert and delete in the table\n" + "loop number of times. Use batch size 1."){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", 1); + INITIALIZER(runInsertDelete); + FINALIZER(runClearTable); +} +TESTCASE("InsertDelete", + "Create one index, then perform insert and delete in the table\n" + "loop number of times. Use batchsize 512 to stress db more"){ + TC_PROPERTY("BatchSize", 512); + INITIALIZER(runInsertDelete); + FINALIZER(runClearTable); + +} +TESTCASE("InsertDelete_O", + "Create one index, then perform insert and delete in the table\n" + "loop number of times. Use batchsize 512 to stress db more"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", 512); + INITIALIZER(runInsertDelete); + FINALIZER(runClearTable); + +} +TESTCASE("CreateLoadDropGentle", + "Try to create, drop and load various indexes \n" + "on table loop number of times.Usa batch size 1.\n"){ + TC_PROPERTY("BatchSize", 1); + INITIALIZER(runCreateLoadDropIndex); +} +TESTCASE("CreateLoadDropGentle_O", + "Try to create, drop and load various indexes \n" + "on table loop number of times.Usa batch size 1.\n"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", 1); + INITIALIZER(runCreateLoadDropIndex); +} +TESTCASE("CreateLoadDrop", + "Try to create, drop and load various indexes \n" + "on table loop number of times. Use batchsize 512 to stress db more\n"){ + TC_PROPERTY("BatchSize", 512); + INITIALIZER(runCreateLoadDropIndex); +} +TESTCASE("CreateLoadDrop_O", + "Try to create, drop and load various indexes \n" + "on table loop number of times. Use batchsize 512 to stress db more\n"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", 512); + INITIALIZER(runCreateLoadDropIndex); +} +TESTCASE("NFNR1", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions1); + STEP(runTransactions1); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR1_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions1); + STEP(runTransactions1); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR2", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR2_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR3", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + STEP(runRestarts); + STEP(runTransactions3); + STEP(runVerifyIndex); + FINALIZER(runVerifyIndex); + FINALIZER(createPkIndex_Drop); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR3_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + STEP(runRestarts); + STEP(runTransactions3); + STEP(runVerifyIndex); + FINALIZER(runVerifyIndex); + FINALIZER(createPkIndex_Drop); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR4", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions1); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR4_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runRestarts); + STEP(runTransactions1); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR5", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", (unsigned)1); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runLQHKEYREF); + STEP(runTransactions1); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("NFNR5_O", + "Test that indexes are correctly maintained during node fail and node restart"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("BatchSize", (unsigned)1); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runLQHKEYREF); + STEP(runTransactions1); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runTransactions2); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("SR1", + "Test that indexes are correctly maintained during SR"){ + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + STEP(runSystemRestart1); + FINALIZER(runVerifyIndex); + FINALIZER(createPkIndex_Drop); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("MixedTransaction", + "Test mixing of index and normal operations"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runMixed1); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("SR1_O", + "Test that indexes are correctly maintained during SR"){ + TC_PROPERTY("OrderedIndex", 1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + STEP(runSystemRestart1); + FINALIZER(runVerifyIndex); + FINALIZER(createPkIndex_Drop); + FINALIZER(createRandomIndex_Drop); + FINALIZER(runClearTable); +} +TESTCASE("BuildDuring", + "Test that index build when running transactions work"){ + TC_PROPERTY("OrderedIndex", (unsigned)0); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("Threads", 1); // # runTransactions4 + INITIALIZER(runClearTable); + STEP(runBuildDuring); + STEP(runTransactions4); + //STEP(runTransactions4); + FINALIZER(runClearTable); +} +TESTCASE("BuildDuring_O", + "Test that index build when running transactions work"){ + TC_PROPERTY("OrderedIndex", (unsigned)1); + TC_PROPERTY("LoggedIndexes", (unsigned)0); + TC_PROPERTY("Threads", 1); // # runTransactions4 + INITIALIZER(runClearTable); + STEP(runBuildDuring); + STEP(runTransactions4); + //STEP(runTransactions4); + FINALIZER(runClearTable); +} +TESTCASE("UniqueNull", + "Test that unique indexes and nulls"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createRandomIndex); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runTransactions1); + STEP(runTransactions2); + STEP(runUniqueNullTransactions); + FINALIZER(runVerifyIndex); + FINALIZER(createRandomIndex_Drop); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} +NDBT_TESTSUITE_END(testIndex); + +int main(int argc, const char** argv){ + return testIndex.execute(argc, argv); +} + + |