/* 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; version 2 of the License. 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 <Vector.hpp> #include <signaldata/DumpStateOrd.hpp> #include <../../include/kernel/ndb_limits.h> #include <random.h> #include <NdbAutoPtr.hpp> #include <NdbMixRestarter.hpp> #define CHECK(b) if (!(b)) { \ g_err << "ERR: "<< step->getName() \ << " failed on line " << __LINE__ << endl; \ result = NDBT_FAILED; \ break; } #define CHECK2(b, c) if (!(b)) { \ g_err << "ERR: "<< step->getName() \ << " failed on line " << __LINE__ << ": " << c << endl; \ result = NDBT_FAILED; \ goto end; } int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); int records = ctx->getNumRecords(); HugoTransactions hugoTrans(*ctx->getTab()); if (hugoTrans.loadTable(pNdb, records) != 0){ return NDBT_FAILED; } return NDBT_OK; } int runCreateInvalidTables(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); int result = NDBT_OK; char failTabName[256]; for (int i = 0; i < 10; i++){ BaseString::snprintf(failTabName, 256, "F%d", i); const NdbDictionary::Table* pFailTab = NDBT_Tables::getTable(failTabName); if (pFailTab != NULL){ ndbout << "|- " << failTabName << endl; // Try to create table in db if (pFailTab->createTableInDb(pNdb) == 0){ ndbout << failTabName << " created, this was not expected"<< endl; result = NDBT_FAILED; } // Verify that table is not in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, failTabName) ; if (pTab2 != NULL){ ndbout << failTabName << " was found in DB, this was not expected"<< endl; result = NDBT_FAILED; if (pFailTab->equal(*pTab2) == true){ ndbout << "It was equal" << endl; } else { ndbout << "It was not equal" << endl; } int records = 1000; HugoTransactions hugoTrans(*pTab2); if (hugoTrans.loadTable(pNdb, records) != 0){ ndbout << "It can NOT be loaded" << endl; } else{ ndbout << "It can be loaded" << endl; UtilTransactions utilTrans(*pTab2); if (utilTrans.clearTable(pNdb, records, 64) != 0){ ndbout << "It can NOT be cleared" << endl; } else{ ndbout << "It can be cleared" << endl; } } if (pNdb->getDictionary()->dropTable(pTab2->getName()) == -1){ ndbout << "It can NOT be dropped" << endl; } else { ndbout << "It can be dropped" << endl; } } } } return result; } int runCreateTheTable(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); const NdbDictionary::Table* pTab = ctx->getTab(); // Try to create table in db if (NDBT_Tables::createTable(pNdb, pTab->getName()) != 0){ return NDBT_FAILED; } // Verify that table is in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } ctx->setTab(pTab2); return NDBT_OK; } int runDropTheTable(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); const NdbDictionary::Table* pTab = ctx->getTab(); // Try to create table in db pNdb->getDictionary()->dropTable(pTab->getName()); return NDBT_OK; } int runCreateTableWhenDbIsFull(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); int result = NDBT_OK; const char* tabName = "TRANSACTION"; //Use a util table const NdbDictionary::Table* pTab = NDBT_Tables::getTable(tabName); if (pTab != NULL){ ndbout << "|- " << tabName << endl; // Verify that table is not in db if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){ ndbout << tabName << " was found in DB"<< endl; return NDBT_FAILED; } // Try to create table in db if (NDBT_Tables::createTable(pNdb, pTab->getName()) == 0){ result = NDBT_FAILED; } // Verify that table is in db if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){ ndbout << tabName << " was found in DB"<< endl; result = NDBT_FAILED; } } return result; } int runDropTableWhenDbIsFull(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); int result = NDBT_OK; const char* tabName = "TRANSACTION"; //Use a util table const NdbDictionary::Table* pTab = NDBT_Table::discoverTableFromDb(pNdb, tabName); if (pTab != NULL){ ndbout << "|- TRANSACTION" << endl; // Try to drop table in db if (pNdb->getDictionary()->dropTable(pTab->getName()) == -1){ result = NDBT_FAILED; } // Verify that table is not in db if (NDBT_Table::discoverTableFromDb(pNdb, tabName) != NULL){ ndbout << tabName << " was found in DB"<< endl; result = NDBT_FAILED; } } return result; } int runCreateAndDrop(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); int loops = ctx->getNumLoops(); int i = 0; const NdbDictionary::Table* pTab = ctx->getTab(); ndbout << "|- " << pTab->getName() << endl; while (i < loops){ ndbout << i << ": "; // Try to create table in db if (NDBT_Tables::createTable(pNdb, pTab->getName()) != 0){ return NDBT_FAILED; } // Verify that table is in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } if (pNdb->getDictionary()->dropTable(pTab2->getName())){ ndbout << "Failed to drop "<<pTab2->getName()<<" in db" << endl; return NDBT_FAILED; } // Verify that table is not in db const NdbDictionary::Table* pTab3 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab3 != NULL){ ndbout << pTab3->getName() << " was found in DB"<< endl; return NDBT_FAILED; } i++; } return NDBT_OK; } int runCreateAndDropAtRandom(NDBT_Context* ctx, NDBT_Step* step) { myRandom48Init(NdbTick_CurrentMillisecond()); Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); int loops = ctx->getNumLoops(); int numTables = NDBT_Tables::getNumTables(); bool* tabList = new bool [ numTables ]; int tabCount; { for (int num = 0; num < numTables; num++) { (void)pDic->dropTable(NDBT_Tables::getTable(num)->getName()); tabList[num] = false; } tabCount = 0; } NdbRestarter restarter; int result = NDBT_OK; int bias = 1; // 0-less 1-more int i = 0; while (i < loops) { g_info << "loop " << i << " tabs " << tabCount << "/" << numTables << endl; int num = myRandom48(numTables); const NdbDictionary::Table* pTab = NDBT_Tables::getTable(num); char tabName[200]; strcpy(tabName, pTab->getName()); if (tabList[num] == false) { if (bias == 0 && myRandom48(100) < 80) continue; g_info << tabName << ": create" << endl; if (pDic->createTable(*pTab) != 0) { const NdbError err = pDic->getNdbError(); g_err << tabName << ": create failed: " << err << endl; result = NDBT_FAILED; break; } const NdbDictionary::Table* pTab2 = pDic->getTable(tabName); if (pTab2 == NULL) { const NdbError err = pDic->getNdbError(); g_err << tabName << ": verify create: " << err << endl; result = NDBT_FAILED; break; } tabList[num] = true; assert(tabCount < numTables); tabCount++; if (tabCount == numTables) bias = 0; } else { if (bias == 1 && myRandom48(100) < 80) continue; g_info << tabName << ": drop" << endl; if (restarter.insertErrorInAllNodes(4013) != 0) { g_err << "error insert failed" << endl; result = NDBT_FAILED; break; } if (pDic->dropTable(tabName) != 0) { const NdbError err = pDic->getNdbError(); g_err << tabName << ": drop failed: " << err << endl; result = NDBT_FAILED; break; } const NdbDictionary::Table* pTab2 = pDic->getTable(tabName); if (pTab2 != NULL) { g_err << tabName << ": verify drop: table exists" << endl; result = NDBT_FAILED; break; } if (pDic->getNdbError().code != 709 && pDic->getNdbError().code != 723) { const NdbError err = pDic->getNdbError(); g_err << tabName << ": verify drop: " << err << endl; result = NDBT_FAILED; break; } tabList[num] = false; assert(tabCount > 0); tabCount--; if (tabCount == 0) bias = 1; } i++; } for (Uint32 i = 0; i<numTables; i++) if (tabList[i]) pDic->dropTable(NDBT_Tables::getTable(i)->getName()); delete [] tabList; return result; } int runCreateAndDropWithData(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); int loops = ctx->getNumLoops(); int records = ctx->getNumRecords(); int i = 0; NdbRestarter restarter; int val = DumpStateOrd::DihMinTimeBetweenLCP; if(restarter.dumpStateAllNodes(&val, 1) != 0){ int result; do { CHECK(0); } while (0); g_err << "Unable to change timebetween LCP" << endl; return NDBT_FAILED; } const NdbDictionary::Table* pTab = ctx->getTab(); ndbout << "|- " << pTab->getName() << endl; while (i < loops){ ndbout << i << ": "; // Try to create table in db if (NDBT_Tables::createTable(pNdb, pTab->getName()) != 0){ return NDBT_FAILED; } // Verify that table is in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } HugoTransactions hugoTrans(*pTab2); if (hugoTrans.loadTable(pNdb, records) != 0){ return NDBT_FAILED; } int count = 0; UtilTransactions utilTrans(*pTab2); if (utilTrans.selectCount(pNdb, 64, &count) != 0){ return NDBT_FAILED; } if (count != records){ ndbout << count <<" != "<<records << endl; return NDBT_FAILED; } if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ ndbout << "Failed to drop "<<pTab2->getName()<<" in db" << endl; return NDBT_FAILED; } // Verify that table is not in db const NdbDictionary::Table* pTab3 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab3 != NULL){ ndbout << pTab3->getName() << " was found in DB"<< endl; return NDBT_FAILED; } i++; } return NDBT_OK; } int runFillTable(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); HugoTransactions hugoTrans(*ctx->getTab()); if (hugoTrans.fillTable(pNdb) != 0){ return NDBT_FAILED; } return NDBT_OK; } int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); int records = ctx->getNumRecords(); UtilTransactions utilTrans(*ctx->getTab()); if (utilTrans.clearTable(pNdb, records) != 0){ return NDBT_FAILED; } return NDBT_OK; } int runCreateAndDropDuring(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; int loops = ctx->getNumLoops(); int i = 0; const NdbDictionary::Table* pTab = ctx->getTab(); ndbout << "|- " << pTab->getName() << endl; while (i < loops && result == NDBT_OK){ ndbout << i << ": " << endl; // Try to create table in db Ndb* pNdb = GETNDB(step); g_debug << "Creating table" << endl; if (NDBT_Tables::createTable(pNdb, pTab->getName()) != 0){ g_err << "createTableInDb failed" << endl; result = NDBT_FAILED; continue; } g_debug << "Verifying creation of table" << endl; // Verify that table is in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ g_err << pTab->getName() << " was not found in DB"<< endl; result = NDBT_FAILED; continue; } NdbSleep_MilliSleep(3000); g_debug << "Dropping table" << endl; if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ g_err << "Failed to drop "<<pTab2->getName()<<" in db" << endl; result = NDBT_FAILED; continue; } g_debug << "Verifying dropping of table" << endl; // Verify that table is not in db const NdbDictionary::Table* pTab3 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab3 != NULL){ g_err << pTab3->getName() << " was found in DB"<< endl; result = NDBT_FAILED; continue; } i++; } ctx->stopTest(); return result; } int runUseTableUntilStopped(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); const NdbDictionary::Table* pTab = ctx->getTab(); while (ctx->isTestStopped() == false) { // g_info << i++ << ": "; // Delete and recreate Ndb object // Otherwise you always get Invalid Schema Version // It would be a nice feature to remove this two lines //step->tearDown(); //step->setUp(); Ndb* pNdb = GETNDB(step); const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL) continue; int res; HugoTransactions hugoTrans(*pTab2); if ((res = hugoTrans.loadTable(pNdb, records)) != 0){ NdbError err = pNdb->getNdbError(res); if(err.classification == NdbError::SchemaError){ pNdb->getDictionary()->invalidateTable(pTab->getName()); } continue; } UtilTransactions utilTrans(*pTab2); if ((res = utilTrans.clearTable(pNdb, records)) != 0){ NdbError err = pNdb->getNdbError(res); if(err.classification == NdbError::SchemaError){ pNdb->getDictionary()->invalidateTable(pTab->getName()); } continue; } } g_info << endl; return NDBT_OK; } int runCreateMaxTables(NDBT_Context* ctx, NDBT_Step* step) { char tabName[256]; int numTables = ctx->getProperty("tables", 1000); Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); int i = 0; for (i = 0; i < numTables; i++) { BaseString::snprintf(tabName, 256, "MAXTAB%d", i); if (pNdb->waitUntilReady(30) != 0) { // Db is not ready, return with failure return NDBT_FAILED; } const NdbDictionary::Table* pTab = ctx->getTab(); //ndbout << "|- " << tabName << endl; // Set new name for T1 NdbDictionary::Table newTab(* pTab); newTab.setName(tabName); // Drop any old (or try to) (void)pDic->dropTable(newTab.getName()); // Try to create table in db if (newTab.createTableInDb(pNdb) != 0) { ndbout << tabName << " could not be created: " << pDic->getNdbError() << endl; if (pDic->getNdbError().code == 707 || pDic->getNdbError().code == 708 || pDic->getNdbError().code == 826 || pDic->getNdbError().code == 827) break; return NDBT_FAILED; } // Verify that table exists in db const NdbDictionary::Table* pTab3 = NDBT_Table::discoverTableFromDb(pNdb, tabName) ; if (pTab3 == NULL){ ndbout << tabName << " was not found in DB: " << pDic->getNdbError() << endl; return NDBT_FAILED; } if (! newTab.equal(*pTab3)) { ndbout << "It was not equal" << endl; abort(); return NDBT_FAILED; } int records = ctx->getNumRecords(); HugoTransactions hugoTrans(*pTab3); if (hugoTrans.loadTable(pNdb, records) != 0) { ndbout << "It can NOT be loaded" << endl; return NDBT_FAILED; } UtilTransactions utilTrans(*pTab3); if (utilTrans.clearTable(pNdb, records, 64) != 0) { ndbout << "It can NOT be cleared" << endl; return NDBT_FAILED; } } if (pNdb->waitUntilReady(30) != 0) { // Db is not ready, return with failure return NDBT_FAILED; } ctx->setProperty("maxtables", i); // HURRAAA! return NDBT_OK; } int runDropMaxTables(NDBT_Context* ctx, NDBT_Step* step) { char tabName[256]; int numTables = ctx->getProperty("maxtables", (Uint32)0); Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); for (int i = 0; i < numTables; i++) { BaseString::snprintf(tabName, 256, "MAXTAB%d", i); if (pNdb->waitUntilReady(30) != 0) { // Db is not ready, return with failure return NDBT_FAILED; } // Verify that table exists in db const NdbDictionary::Table* pTab3 = NDBT_Table::discoverTableFromDb(pNdb, tabName) ; if (pTab3 == NULL) { ndbout << tabName << " was not found in DB: " << pDic->getNdbError() << endl; return NDBT_FAILED; } // Try to drop table in db if (pDic->dropTable(pTab3->getName()) != 0) { ndbout << tabName << " could not be dropped: " << pDic->getNdbError() << endl; return NDBT_FAILED; } } return NDBT_OK; } int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){ int records = ctx->getNumRecords(); int fragTtype = ctx->getProperty("FragmentType"); Ndb* pNdb = GETNDB(step); int result = NDBT_OK; NdbRestarter restarter; if (pNdb->waitUntilReady(30) != 0){ // Db is not ready, return with failure return NDBT_FAILED; } const NdbDictionary::Table* pTab = ctx->getTab(); pNdb->getDictionary()->dropTable(pTab->getName()); NdbDictionary::Table newTab(* pTab); // Set fragment type for table newTab.setFragmentType((NdbDictionary::Object::FragmentType)fragTtype); // Try to create table in db if (newTab.createTableInDb(pNdb) != 0){ ndbout << newTab.getName() << " could not be created" << ", fragmentType = "<<fragTtype <<endl; ndbout << pNdb->getDictionary()->getNdbError() << endl; return NDBT_FAILED; } // Verify that table exists in db const NdbDictionary::Table* pTab3 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()) ; if (pTab3 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } if (pTab3->getFragmentType() != fragTtype){ ndbout << pTab->getName() << " fragmentType error "<< endl; result = NDBT_FAILED; goto drop_the_tab; } /** This test does not work since fragmentation is decided by the kernel, hence the fragementation attribute on the column will differ if (newTab.equal(*pTab3) == false){ ndbout << "It was not equal" << endl; result = NDBT_FAILED; goto drop_the_tab; } */ do { HugoTransactions hugoTrans(*pTab3); UtilTransactions utilTrans(*pTab3); int count; CHECK(hugoTrans.loadTable(pNdb, records) == 0); CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == records); CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == (records/2)); // restart all ndbout << "Restarting cluster" << endl; CHECK(restarter.restartAll() == 0); int timeout = 120; CHECK(restarter.waitClusterStarted(timeout) == 0); CHECK(pNdb->waitUntilReady(timeout) == 0); // Verify content CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == (records/2)); CHECK(utilTrans.clearTable(pNdb, records) == 0); CHECK(hugoTrans.loadTable(pNdb, records) == 0); CHECK(utilTrans.clearTable(pNdb, records) == 0); CHECK(hugoTrans.loadTable(pNdb, records) == 0); CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); CHECK(utilTrans.clearTable(pNdb, records, 64) == 0); } while(false); drop_the_tab: // Try to drop table in db if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){ ndbout << pTab3->getName() << " could not be dropped"<< endl; result = NDBT_FAILED; } return result; } int runTestTemporaryTables(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; int loops = ctx->getNumLoops(); int records = ctx->getNumRecords(); Ndb* pNdb = GETNDB(step); int i = 0; NdbRestarter restarter; const NdbDictionary::Table* pTab = ctx->getTab(); ndbout << "|- " << pTab->getName() << endl; NdbDictionary::Table newTab(* pTab); // Set table as temporary newTab.setStoredTable(false); // Try to create table in db if (newTab.createTableInDb(pNdb) != 0){ return NDBT_FAILED; } // Verify that table is in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } if (pTab2->getStoredTable() != false){ ndbout << pTab->getName() << " was not temporary in DB"<< endl; result = NDBT_FAILED; goto drop_the_tab; } while (i < loops && result == NDBT_OK){ ndbout << i << ": "; HugoTransactions hugoTrans(*pTab2); CHECK(hugoTrans.loadTable(pNdb, records) == 0); int count = 0; UtilTransactions utilTrans(*pTab2); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == records); // restart all ndbout << "Restarting cluster" << endl; CHECK(restarter.restartAll() == 0); int timeout = 120; CHECK(restarter.waitClusterStarted(timeout) == 0); CHECK(pNdb->waitUntilReady(timeout) == 0); ndbout << "Verifying records..." << endl; CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == 0); i++; } drop_the_tab: if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ ndbout << "Failed to drop "<<pTab2->getName()<<" in db" << endl; result = NDBT_FAILED; } // Verify that table is not in db const NdbDictionary::Table* pTab3 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab3 != NULL){ ndbout << pTab3->getName() << " was found in DB"<< endl; result = NDBT_FAILED; } return result; } int runPkSizes(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; char tabName[256]; int minPkSize = 1; ndbout << "minPkSize=" <<minPkSize<<endl; int maxPkSize = MAX_KEY_SIZE_IN_WORDS * 4; ndbout << "maxPkSize=" <<maxPkSize<<endl; Ndb* pNdb = GETNDB(step); int numRecords = ctx->getNumRecords(); for (int i = minPkSize; i < maxPkSize; i++){ BaseString::snprintf(tabName, 256, "TPK_%d", i); int records = numRecords; int max = ~0; // Limit num records for small PKs if (i == 1) max = 99; if (i == 2) max = 999; if (i == 3) max = 9999; if (records > max) records = max; ndbout << "records =" << records << endl; if (pNdb->waitUntilReady(30) != 0){ // Db is not ready, return with failure return NDBT_FAILED; } ndbout << "|- " << tabName << endl; if (NDBT_Tables::createTable(pNdb, tabName) != 0){ ndbout << tabName << " could not be created"<< endl; return NDBT_FAILED; } // Verify that table exists in db const NdbDictionary::Table* pTab3 = NDBT_Table::discoverTableFromDb(pNdb, tabName) ; if (pTab3 == NULL){ g_err << tabName << " was not found in DB"<< endl; return NDBT_FAILED; } // ndbout << *pTab3 << endl; if (pTab3->equal(*NDBT_Tables::getTable(tabName)) == false){ g_err << "It was not equal" << endl; return NDBT_FAILED; } do { // Do it all HugoTransactions hugoTrans(*pTab3); UtilTransactions utilTrans(*pTab3); int count; CHECK(hugoTrans.loadTable(pNdb, records) == 0); CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == records); CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0); CHECK(hugoTrans.scanUpdateRecords(pNdb, records) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == (records/2)); CHECK(utilTrans.clearTable(pNdb, records) == 0); #if 0 // Fill table CHECK(hugoTrans.fillTable(pNdb) == 0); CHECK(utilTrans.clearTable2(pNdb, records) == 0); CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0); CHECK(count == 0); #endif } while(false); // Drop table if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){ ndbout << "Failed to drop "<<pTab3->getName()<<" in db" << endl; return NDBT_FAILED; } } return result; } int runStoreFrm(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); const NdbDictionary::Table* pTab = ctx->getTab(); int result = NDBT_OK; int loops = ctx->getNumLoops(); for (int l = 0; l < loops && result == NDBT_OK ; l++){ Uint32 dataLen = (Uint32)myRandom48(MAX_FRM_DATA_SIZE); // size_t dataLen = 10; unsigned char data[MAX_FRM_DATA_SIZE]; char start = l + 248; for(Uint32 i = 0; i < dataLen; i++){ data[i] = start; start++; } #if 0 ndbout << "dataLen="<<dataLen<<endl; for (Uint32 i = 0; i < dataLen; i++){ unsigned char c = data[i]; ndbout << hex << c << ", "; } ndbout << endl; #endif NdbDictionary::Table newTab(* pTab); void* pData = &data; newTab.setFrm(pData, dataLen); // Try to create table in db if (newTab.createTableInDb(pNdb) != 0){ result = NDBT_FAILED; continue; } // Verify that table is in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ g_err << pTab->getName() << " was not found in DB"<< endl; result = NDBT_FAILED; continue; } const void* pData2 = pTab2->getFrmData(); Uint32 resultLen = pTab2->getFrmLength(); if (dataLen != resultLen){ g_err << "Length of data failure" << endl << " expected = " << dataLen << endl << " got = " << resultLen << endl; result = NDBT_FAILED; } // Verfiy the frm data if (memcmp(pData, pData2, resultLen) != 0){ g_err << "Wrong data recieved" << endl; for (size_t i = 0; i < dataLen; i++){ unsigned char c = ((unsigned char*)pData2)[i]; g_err << hex << c << ", "; } g_err << endl; result = NDBT_FAILED; } if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ g_err << "It can NOT be dropped" << endl; result = NDBT_FAILED; } } return result; } int runStoreFrmError(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); const NdbDictionary::Table* pTab = ctx->getTab(); int result = NDBT_OK; int loops = ctx->getNumLoops(); for (int l = 0; l < loops && result == NDBT_OK ; l++){ const Uint32 dataLen = MAX_FRM_DATA_SIZE + 10; unsigned char data[dataLen]; char start = l + 248; for(Uint32 i = 0; i < dataLen; i++){ data[i] = start; start++; } #if 0 ndbout << "dataLen="<<dataLen<<endl; for (Uint32 i = 0; i < dataLen; i++){ unsigned char c = data[i]; ndbout << hex << c << ", "; } ndbout << endl; #endif NdbDictionary::Table newTab(* pTab); void* pData = &data; newTab.setFrm(pData, dataLen); // Try to create table in db if (newTab.createTableInDb(pNdb) == 0){ result = NDBT_FAILED; continue; } const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 != NULL){ g_err << pTab->getName() << " was found in DB"<< endl; result = NDBT_FAILED; if (pNdb->getDictionary()->dropTable(pTab2->getName()) != 0){ g_err << "It can NOT be dropped" << endl; result = NDBT_FAILED; } continue; } } return result; } int verifyTablesAreEqual(const NdbDictionary::Table* pTab, const NdbDictionary::Table* pTab2){ // Verify that getPrimaryKey only returned true for primary keys for (int i = 0; i < pTab2->getNoOfColumns(); i++){ const NdbDictionary::Column* col = pTab->getColumn(i); const NdbDictionary::Column* col2 = pTab2->getColumn(i); if (col->getPrimaryKey() != col2->getPrimaryKey()){ g_err << "col->getPrimaryKey() != col2->getPrimaryKey()" << endl; return NDBT_FAILED; } } if (!pTab->equal(*pTab2)){ g_err << "equal failed" << endl; g_info << *(NDBT_Table*)pTab; // gcc-4.1.2 g_info << *(NDBT_Table*)pTab2; return NDBT_FAILED; } return NDBT_OK; } int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); const NdbDictionary::Table* pTab = ctx->getTab(); ndbout << "|- " << pTab->getName() << endl; g_info << *(NDBT_Table*)pTab; // Try to create table in db if (pTab->createTableInDb(pNdb) != 0){ return NDBT_FAILED; } const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } int result = NDBT_OK; if (verifyTablesAreEqual(pTab, pTab2) != NDBT_OK) result = NDBT_FAILED; #if 0 // Create an index on the table and see what // the function returns now char name[200]; sprintf(name, "%s_X007", pTab->getName()); NDBT_Index* pInd = new NDBT_Index(name); pInd->setTable(pTab->getName()); pInd->setType(NdbDictionary::Index::UniqueHashIndex); // pInd->setLogging(false); for (int i = 0; i < 2; i++){ const NDBT_Attribute* pAttr = pTab->getAttribute(i); pInd->addAttribute(*pAttr); } g_info << "Create index:" << endl << *pInd; if (pInd->createIndexInDb(pNdb, false) != 0){ result = NDBT_FAILED; } delete pInd; const NdbDictionary::Table* pTab3 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab3 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } if (verifyTablesAreEqual(pTab, pTab3) != NDBT_OK) result = NDBT_FAILED; if (verifyTablesAreEqual(pTab2, pTab3) != NDBT_OK) result = NDBT_FAILED; #endif #if 0 if (pTab2->getDictionary()->dropTable(pNdb) != 0){ ndbout << "Failed to drop "<<pTab2->getName()<<" in db" << endl; return NDBT_FAILED; } // Verify that table is not in db const NdbDictionary::Table* pTab4 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab4 != NULL){ ndbout << pTab4->getName() << " was found in DB"<< endl; return NDBT_FAILED; } #endif return result; } struct ErrorCodes { int error_id; bool crash;}; ErrorCodes NF_codes[] = { {6003, true} ,{6004, true} //,6005, true, //{7173, false} }; int runNF1(NDBT_Context* ctx, NDBT_Step* step){ NdbRestarter restarter; if(restarter.getNumDbNodes() < 2) return NDBT_OK; myRandom48Init(NdbTick_CurrentMillisecond()); Ndb* pNdb = GETNDB(step); const NdbDictionary::Table* pTab = ctx->getTab(); NdbDictionary::Dictionary* dict = pNdb->getDictionary(); dict->dropTable(pTab->getName()); int result = NDBT_OK; const int loops = ctx->getNumLoops(); for (int l = 0; l < loops && result == NDBT_OK ; l++){ const int sz = sizeof(NF_codes)/sizeof(NF_codes[0]); for(int i = 0; i<sz; i++){ int rand = myRandom48(restarter.getNumDbNodes()); int nodeId = restarter.getRandomNotMasterNodeId(rand); struct ErrorCodes err_struct = NF_codes[i]; int error = err_struct.error_id; bool crash = err_struct.crash; g_info << "NF1: node = " << nodeId << " error code = " << error << endl; int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 3}; CHECK2(restarter.dumpStateOneNode(nodeId, val2, 2) == 0, "failed to set RestartOnErrorInsert"); CHECK2(restarter.insertErrorInNode(nodeId, error) == 0, "failed to set error insert"); CHECK2(dict->createTable(* pTab) == 0, "failed to create table"); if (crash) { CHECK2(restarter.waitNodesNoStart(&nodeId, 1) == 0, "waitNodesNoStart failed"); if(myRandom48(100) > 50){ CHECK2(restarter.startNodes(&nodeId, 1) == 0, "failed to start node"); CHECK2(restarter.waitClusterStarted() == 0, "waitClusterStarted failed"); CHECK2(dict->dropTable(pTab->getName()) == 0, "drop table failed"); } else { CHECK2(dict->dropTable(pTab->getName()) == 0, "drop table failed"); CHECK2(restarter.startNodes(&nodeId, 1) == 0, "failed to start node"); CHECK2(restarter.waitClusterStarted() == 0, "waitClusterStarted failed"); } } } } end: dict->dropTable(pTab->getName()); return result; } #define APIERROR(error) \ { g_err << "Error in " << __FILE__ << ", line:" << __LINE__ << ", code:" \ << error.code << ", msg: " << error.message << "." << endl; \ } int runCreateAutoincrementTable(NDBT_Context* ctx, NDBT_Step* step){ Uint32 startvalues[5] = {256-2, 0, 256*256-2, ~0, 256*256*256-2}; int ret = NDBT_OK; for (int jj = 0; jj < 5 && ret == NDBT_OK; jj++) { char tabname[] = "AUTOINCTAB"; Uint32 startvalue = startvalues[jj]; NdbDictionary::Table myTable; NdbDictionary::Column myColumn; Ndb* myNdb = GETNDB(step); NdbDictionary::Dictionary* myDict = myNdb->getDictionary(); if (myDict->getTable(tabname) != NULL) { g_err << "NDB already has example table: " << tabname << endl; APIERROR(myNdb->getNdbError()); return NDBT_FAILED; } myTable.setName(tabname); myColumn.setName("ATTR1"); myColumn.setType(NdbDictionary::Column::Unsigned); myColumn.setLength(1); myColumn.setPrimaryKey(true); myColumn.setNullable(false); myColumn.setAutoIncrement(true); if (startvalue != ~0) // check that default value starts with 1 myColumn.setAutoIncrementInitialValue(startvalue); myTable.addColumn(myColumn); if (myDict->createTable(myTable) == -1) { g_err << "Failed to create table " << tabname << endl; APIERROR(myNdb->getNdbError()); return NDBT_FAILED; } if (startvalue == ~0) // check that default value starts with 1 startvalue = 1; for (int i = 0; i < 16; i++) { Uint64 value; if (myNdb->getAutoIncrementValue(tabname, value, 1) == -1) { g_err << "getAutoIncrementValue failed on " << tabname << endl; APIERROR(myNdb->getNdbError()); return NDBT_FAILED; } else if (value != (startvalue+i)) { g_err << "value = " << value << " expected " << startvalue+i << endl;; APIERROR(myNdb->getNdbError()); // ret = NDBT_FAILED; // break; } } if (myDict->dropTable(tabname) == -1) { g_err << "Failed to drop table " << tabname << endl; APIERROR(myNdb->getNdbError()); ret = NDBT_FAILED; } } return ret; } int runTableRename(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* dict = pNdb->getDictionary(); int records = ctx->getNumRecords(); const int loops = ctx->getNumLoops(); ndbout << "|- " << ctx->getTab()->getName() << endl; for (int l = 0; l < loops && result == NDBT_OK ; l++){ const NdbDictionary::Table* pTab = ctx->getTab(); // Try to create table in db if (pTab->createTableInDb(pNdb) != 0){ return NDBT_FAILED; } // Verify that table is in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } ctx->setTab(pTab2); // Load table HugoTransactions hugoTrans(*ctx->getTab()); if (hugoTrans.loadTable(pNdb, records) != 0){ return NDBT_FAILED; } // Rename table BaseString pTabName(pTab->getName()); BaseString pTabNewName(pTabName); pTabNewName.append("xx"); const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); if (oldTable) { NdbDictionary::Table newTable = *oldTable; newTable.setName(pTabNewName.c_str()); CHECK2(dict->alterTable(newTable) == 0, "TableRename failed"); } else { result = NDBT_FAILED; } // Verify table contents NdbDictionary::Table pNewTab(pTabNewName.c_str()); UtilTransactions utilTrans(pNewTab); if (utilTrans.clearTable(pNdb, records) != 0){ continue; } // Drop table dict->dropTable(pNewTab.getName()); } end: return result; } int runTableRenameNF(NDBT_Context* ctx, NDBT_Step* step){ NdbRestarter restarter; if(restarter.getNumDbNodes() < 2) return NDBT_OK; int result = NDBT_OK; Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* dict = pNdb->getDictionary(); int records = ctx->getNumRecords(); const int loops = ctx->getNumLoops(); ndbout << "|- " << ctx->getTab()->getName() << endl; for (int l = 0; l < loops && result == NDBT_OK ; l++){ const NdbDictionary::Table* pTab = ctx->getTab(); // Try to create table in db if (pTab->createTableInDb(pNdb) != 0){ return NDBT_FAILED; } // Verify that table is in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } ctx->setTab(pTab2); // Load table HugoTransactions hugoTrans(*ctx->getTab()); if (hugoTrans.loadTable(pNdb, records) != 0){ return NDBT_FAILED; } BaseString pTabName(pTab->getName()); BaseString pTabNewName(pTabName); pTabNewName.append("xx"); const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); if (oldTable) { NdbDictionary::Table newTable = *oldTable; newTable.setName(pTabNewName.c_str()); CHECK2(dict->alterTable(newTable) == 0, "TableRename failed"); } else { result = NDBT_FAILED; } // Restart one node at a time /** * Need to run LCP at high rate otherwise * packed replicas become "to many" */ int val = DumpStateOrd::DihMinTimeBetweenLCP; if(restarter.dumpStateAllNodes(&val, 1) != 0){ do { CHECK(0); } while(0); g_err << "Failed to set LCP to min value" << endl; return NDBT_FAILED; } const int numNodes = restarter.getNumDbNodes(); for(int i = 0; i<numNodes; i++){ int nodeId = restarter.getDbNodeId(i); int error = NF_codes[i].error_id; g_info << "NF1: node = " << nodeId << " error code = " << error << endl; CHECK2(restarter.restartOneDbNode(nodeId) == 0, "failed to set restartOneDbNode"); CHECK2(restarter.waitClusterStarted() == 0, "waitClusterStarted failed"); } // Verify table contents NdbDictionary::Table pNewTab(pTabNewName.c_str()); UtilTransactions utilTrans(pNewTab); if (utilTrans.clearTable(pNdb, records) != 0){ continue; } // Drop table dict->dropTable(pTabNewName.c_str()); } end: return result; } int runTableRenameSR(NDBT_Context* ctx, NDBT_Step* step){ NdbRestarter restarter; if(restarter.getNumDbNodes() < 2) return NDBT_OK; int result = NDBT_OK; Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* dict = pNdb->getDictionary(); int records = ctx->getNumRecords(); const int loops = ctx->getNumLoops(); ndbout << "|- " << ctx->getTab()->getName() << endl; for (int l = 0; l < loops && result == NDBT_OK ; l++){ // Rename table const NdbDictionary::Table* pTab = ctx->getTab(); // Try to create table in db if (pTab->createTableInDb(pNdb) != 0){ return NDBT_FAILED; } // Verify that table is in db const NdbDictionary::Table* pTab2 = NDBT_Table::discoverTableFromDb(pNdb, pTab->getName()); if (pTab2 == NULL){ ndbout << pTab->getName() << " was not found in DB"<< endl; return NDBT_FAILED; } ctx->setTab(pTab2); // Load table HugoTransactions hugoTrans(*ctx->getTab()); if (hugoTrans.loadTable(pNdb, records) != 0){ return NDBT_FAILED; } BaseString pTabName(pTab->getName()); BaseString pTabNewName(pTabName); pTabNewName.append("xx"); const NdbDictionary::Table * oldTable = dict->getTable(pTabName.c_str()); if (oldTable) { NdbDictionary::Table newTable = *oldTable; newTable.setName(pTabNewName.c_str()); CHECK2(dict->alterTable(newTable) == 0, "TableRename failed"); } else { result = NDBT_FAILED; } // Restart cluster /** * Need to run LCP at high rate otherwise * packed replicas become "to many" */ int val = DumpStateOrd::DihMinTimeBetweenLCP; if(restarter.dumpStateAllNodes(&val, 1) != 0){ do { CHECK(0); } while(0); g_err << "Failed to set LCP to min value" << endl; return NDBT_FAILED; } CHECK2(restarter.restartAll() == 0, "failed to set restartOneDbNode"); CHECK2(restarter.waitClusterStarted() == 0, "waitClusterStarted failed"); // Verify table contents NdbDictionary::Table pNewTab(pTabNewName.c_str()); UtilTransactions utilTrans(pNewTab); if (utilTrans.clearTable(pNdb, records) != 0){ continue; } // Drop table dict->dropTable(pTabNewName.c_str()); } end: return result; } static void f(const NdbDictionary::Column * col){ if(col == 0){ abort(); } } int runTestDictionaryPerf(NDBT_Context* ctx, NDBT_Step* step){ Vector<char*> cols; Vector<const NdbDictionary::Table*> tabs; int i; Ndb* pNdb = GETNDB(step); const Uint32 count = NDBT_Tables::getNumTables(); for (i=0; i < count; i++){ const NdbDictionary::Table * tab = NDBT_Tables::getTable(i); pNdb->getDictionary()->createTable(* tab); const NdbDictionary::Table * tab2 = pNdb->getDictionary()->getTable(tab->getName()); for(size_t j = 0; j<tab->getNoOfColumns(); j++){ cols.push_back((char*)tab2); cols.push_back(strdup(tab->getColumn(j)->getName())); } } const Uint32 times = 10000000; ndbout_c("%d tables and %d columns", NDBT_Tables::getNumTables(), cols.size()/2); char ** tcols = cols.getBase(); srand(time(0)); Uint32 size = cols.size() / 2; char ** columns = &cols[0]; Uint64 start = NdbTick_CurrentMillisecond(); for(i = 0; i<times; i++){ int j = 2 * (rand() % size); const NdbDictionary::Table* tab = (const NdbDictionary::Table*)tcols[j]; const char * col = tcols[j+1]; const NdbDictionary::Column* column = tab->getColumn(col); f(column); } Uint64 stop = NdbTick_CurrentMillisecond(); stop -= start; Uint64 per = stop; per *= 1000; per /= times; ndbout_c("%d random getColumn(name) in %Ld ms -> %d us/get", times, stop, per); return NDBT_OK; } int runCreateLogfileGroup(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); NdbDictionary::LogfileGroup lg; lg.setName("DEFAULT-LG"); lg.setUndoBufferSize(8*1024*1024); int res; res = pNdb->getDictionary()->createLogfileGroup(lg); if(res != 0){ g_err << "Failed to create logfilegroup:" << endl << pNdb->getDictionary()->getNdbError() << endl; return NDBT_FAILED; } NdbDictionary::Undofile uf; uf.setPath("undofile01.dat"); uf.setSize(5*1024*1024); uf.setLogfileGroup("DEFAULT-LG"); res = pNdb->getDictionary()->createUndofile(uf); if(res != 0){ g_err << "Failed to create undofile:" << endl << pNdb->getDictionary()->getNdbError() << endl; return NDBT_FAILED; } uf.setPath("undofile02.dat"); uf.setSize(5*1024*1024); uf.setLogfileGroup("DEFAULT-LG"); res = pNdb->getDictionary()->createUndofile(uf); if(res != 0){ g_err << "Failed to create undofile:" << endl << pNdb->getDictionary()->getNdbError() << endl; return NDBT_FAILED; } return NDBT_OK; } int runCreateTablespace(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); NdbDictionary::Tablespace lg; lg.setName("DEFAULT-TS"); lg.setExtentSize(1024*1024); lg.setDefaultLogfileGroup("DEFAULT-LG"); int res; res = pNdb->getDictionary()->createTablespace(lg); if(res != 0){ g_err << "Failed to create tablespace:" << endl << pNdb->getDictionary()->getNdbError() << endl; return NDBT_FAILED; } NdbDictionary::Datafile uf; uf.setPath("datafile01.dat"); uf.setSize(10*1024*1024); uf.setTablespace("DEFAULT-TS"); res = pNdb->getDictionary()->createDatafile(uf); if(res != 0){ g_err << "Failed to create datafile:" << endl << pNdb->getDictionary()->getNdbError() << endl; return NDBT_FAILED; } return NDBT_OK; } int runCreateDiskTable(NDBT_Context* ctx, NDBT_Step* step){ Ndb* pNdb = GETNDB(step); NdbDictionary::Table tab = *ctx->getTab(); tab.setTablespaceName("DEFAULT-TS"); for(Uint32 i = 0; i<tab.getNoOfColumns(); i++) if(!tab.getColumn(i)->getPrimaryKey()) tab.getColumn(i)->setStorageType(NdbDictionary::Column::StorageTypeDisk); int res; res = pNdb->getDictionary()->createTable(tab); if(res != 0){ g_err << "Failed to create table:" << endl << pNdb->getDictionary()->getNdbError() << endl; return NDBT_FAILED; } return NDBT_OK; } int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){ static int acclst[] = { 3001 }; static int tuplst[] = { 4007, 4008, 4009, 4010, 4011, 4012 }; static int tuxlst[] = { 12001, 12002, 12003, 12004, 12005, 12006 }; static unsigned acccnt = sizeof(acclst)/sizeof(acclst[0]); static unsigned tupcnt = sizeof(tuplst)/sizeof(tuplst[0]); static unsigned tuxcnt = sizeof(tuxlst)/sizeof(tuxlst[0]); NdbRestarter restarter; int nodeId = restarter.getMasterNodeId(); Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); NdbDictionary::Table tab(*ctx->getTab()); tab.setFragmentType(NdbDictionary::Object::FragAllLarge); // ordered index on first few columns NdbDictionary::Index idx("X"); idx.setTable(tab.getName()); idx.setType(NdbDictionary::Index::OrderedIndex); idx.setLogging(false); for (int i_hate_broken_compilers = 0; i_hate_broken_compilers < 3 && i_hate_broken_compilers < tab.getNoOfColumns(); i_hate_broken_compilers++) { idx.addColumn(*tab.getColumn(i_hate_broken_compilers)); } const int loops = ctx->getNumLoops(); int result = NDBT_OK; (void)pDic->dropTable(tab.getName()); for (int l = 0; l < loops; l++) { for (unsigned i0 = 0; i0 < acccnt; i0++) { unsigned j = (l == 0 ? i0 : myRandom48(acccnt)); int errval = acclst[j]; g_info << "insert error node=" << nodeId << " value=" << errval << endl; CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0, "failed to set error insert"); CHECK2(pDic->createTable(tab) != 0, "failed to fail after error insert " << errval); CHECK2(pDic->createTable(tab) == 0, pDic->getNdbError()); CHECK2(pDic->dropTable(tab.getName()) == 0, pDic->getNdbError()); } for (unsigned i1 = 0; i1 < tupcnt; i1++) { unsigned j = (l == 0 ? i1 : myRandom48(tupcnt)); int errval = tuplst[j]; g_info << "insert error node=" << nodeId << " value=" << errval << endl; CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0, "failed to set error insert"); CHECK2(pDic->createTable(tab) != 0, "failed to fail after error insert " << errval); CHECK2(pDic->createTable(tab) == 0, pDic->getNdbError()); CHECK2(pDic->dropTable(tab.getName()) == 0, pDic->getNdbError()); } for (unsigned i2 = 0; i2 < tuxcnt; i2++) { unsigned j = (l == 0 ? i2 : myRandom48(tuxcnt)); int errval = tuxlst[j]; g_info << "insert error node=" << nodeId << " value=" << errval << endl; CHECK2(restarter.insertErrorInNode(nodeId, errval) == 0, "failed to set error insert"); CHECK2(pDic->createTable(tab) == 0, pDic->getNdbError()); CHECK2(pDic->createIndex(idx) != 0, "failed to fail after error insert " << errval); CHECK2(pDic->createIndex(idx) == 0, pDic->getNdbError()); CHECK2(pDic->dropTable(tab.getName()) == 0, pDic->getNdbError()); } } end: return result; } // NFNR // Restarter controls dict ops : 1-run 2-pause 3-stop // synced by polling... static bool send_dict_ops_cmd(NDBT_Context* ctx, Uint32 cmd) { ctx->setProperty("DictOps_CMD", cmd); while (1) { if (ctx->isTestStopped()) return false; if (ctx->getProperty("DictOps_ACK") == cmd) break; NdbSleep_MilliSleep(100); } return true; } static bool recv_dict_ops_run(NDBT_Context* ctx) { while (1) { if (ctx->isTestStopped()) return false; Uint32 cmd = ctx->getProperty("DictOps_CMD"); ctx->setProperty("DictOps_ACK", cmd); if (cmd == 1) break; if (cmd == 3) return false; NdbSleep_MilliSleep(100); } return true; } int runRestarts(NDBT_Context* ctx, NDBT_Step* step) { static int errlst_master[] = { // non-crashing 7175, // send one fake START_PERMREF 0 }; static int errlst_node[] = { 7174, // crash before sending DICT_LOCK_REQ 7176, // pretend master does not support DICT lock 7121, // crash at receive START_PERMCONF 0 }; const uint errcnt_master = sizeof(errlst_master)/sizeof(errlst_master[0]); const uint errcnt_node = sizeof(errlst_node)/sizeof(errlst_node[0]); myRandom48Init(NdbTick_CurrentMillisecond()); NdbRestarter restarter; int result = NDBT_OK; const int loops = ctx->getNumLoops(); for (int l = 0; l < loops && result == NDBT_OK; l++) { g_info << "1: === loop " << l << " ===" << endl; // assuming 2-way replicated int numnodes = restarter.getNumDbNodes(); CHECK(numnodes >= 1); if (numnodes == 1) break; int masterNodeId = restarter.getMasterNodeId(); CHECK(masterNodeId != -1); // for more complex cases need more restarter support methods int nodeIdList[2] = { 0, 0 }; int nodeIdCnt = 0; if (numnodes >= 2) { int rand = myRandom48(numnodes); int nodeId = restarter.getRandomNotMasterNodeId(rand); CHECK(nodeId != -1); nodeIdList[nodeIdCnt++] = nodeId; } if (numnodes >= 4 && myRandom48(2) == 0) { int rand = myRandom48(numnodes); int nodeId = restarter.getRandomNodeOtherNodeGroup(nodeIdList[0], rand); CHECK(nodeId != -1); if (nodeId != masterNodeId) nodeIdList[nodeIdCnt++] = nodeId; } g_info << "1: master=" << masterNodeId << " nodes=" << nodeIdList[0] << "," << nodeIdList[1] << endl; const uint timeout = 60; //secs for node wait const unsigned maxsleep = 2000; //ms bool NF_ops = ctx->getProperty("Restart_NF_ops"); uint NF_type = ctx->getProperty("Restart_NF_type"); bool NR_ops = ctx->getProperty("Restart_NR_ops"); bool NR_error = ctx->getProperty("Restart_NR_error"); g_info << "1: " << (NF_ops ? "run" : "pause") << " dict ops" << endl; if (! send_dict_ops_cmd(ctx, NF_ops ? 1 : 2)) break; NdbSleep_MilliSleep(myRandom48(maxsleep)); { for (int i = 0; i < nodeIdCnt; i++) { int nodeId = nodeIdList[i]; bool nostart = true; bool abort = NF_type == 0 ? myRandom48(2) : (NF_type == 2); bool initial = myRandom48(2); char flags[40]; strcpy(flags, "flags: nostart"); if (abort) strcat(flags, ",abort"); if (initial) strcat(flags, ",initial"); g_info << "1: restart " << nodeId << " " << flags << endl; CHECK(restarter.restartOneDbNode(nodeId, initial, nostart, abort) == 0); } } g_info << "1: wait for nostart" << endl; CHECK(restarter.waitNodesNoStart(nodeIdList, nodeIdCnt, timeout) == 0); NdbSleep_MilliSleep(myRandom48(maxsleep)); int err_master = 0; int err_node[2] = { 0, 0 }; if (NR_error) { err_master = errlst_master[l % errcnt_master]; // limitation: cannot have 2 node restarts and crash_insert // one node may die for real (NF during startup) for (int i = 0; i < nodeIdCnt && nodeIdCnt == 1; i++) { err_node[i] = errlst_node[l % errcnt_node]; // 7176 - no DICT lock protection if (err_node[i] == 7176) { g_info << "1: no dict ops due to error insert " << err_node[i] << endl; NR_ops = false; } } } g_info << "1: " << (NR_ops ? "run" : "pause") << " dict ops" << endl; if (! send_dict_ops_cmd(ctx, NR_ops ? 1 : 2)) break; NdbSleep_MilliSleep(myRandom48(maxsleep)); g_info << "1: start nodes" << endl; CHECK(restarter.startNodes(nodeIdList, nodeIdCnt) == 0); if (NR_error) { { int err = err_master; if (err != 0) { g_info << "1: insert master error " << err << endl; CHECK(restarter.insertErrorInNode(masterNodeId, err) == 0); } } for (int i = 0; i < nodeIdCnt; i++) { int nodeId = nodeIdList[i]; int err = err_node[i]; if (err != 0) { g_info << "1: insert node " << nodeId << " error " << err << endl; CHECK(restarter.insertErrorInNode(nodeId, err) == 0); } } } NdbSleep_MilliSleep(myRandom48(maxsleep)); g_info << "1: wait cluster started" << endl; CHECK(restarter.waitClusterStarted(timeout) == 0); NdbSleep_MilliSleep(myRandom48(maxsleep)); g_info << "1: restart done" << endl; } g_info << "1: stop dict ops" << endl; send_dict_ops_cmd(ctx, 3); return result; } int runDictOps(NDBT_Context* ctx, NDBT_Step* step) { myRandom48Init(NdbTick_CurrentMillisecond()); int result = NDBT_OK; for (int l = 0; result == NDBT_OK; l++) { if (! recv_dict_ops_run(ctx)) break; g_info << "2: === loop " << l << " ===" << endl; Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); const NdbDictionary::Table* pTab = ctx->getTab(); //const char* tabName = pTab->getName(); //XXX what goes on? char tabName[40]; strcpy(tabName, pTab->getName()); const unsigned long maxsleep = 100; //ms g_info << "2: create table" << endl; { uint count = 0; try_create: count++; if (pDic->createTable(*pTab) != 0) { const NdbError err = pDic->getNdbError(); if (count == 1) g_err << "2: " << tabName << ": create failed: " << err << endl; if (err.code != 711) { result = NDBT_FAILED; break; } NdbSleep_MilliSleep(myRandom48(maxsleep)); goto try_create; } } NdbSleep_MilliSleep(myRandom48(maxsleep)); g_info << "2: verify create" << endl; const NdbDictionary::Table* pTab2 = pDic->getTable(tabName); if (pTab2 == NULL) { const NdbError err = pDic->getNdbError(); g_err << "2: " << tabName << ": verify create: " << err << endl; result = NDBT_FAILED; break; } NdbSleep_MilliSleep(myRandom48(maxsleep)); // replace by the Retrieved table pTab = pTab2; // create indexes const char** indlist = NDBT_Tables::getIndexes(tabName); uint indnum = 0; while (indlist != 0 && *indlist != 0) { uint count = 0; try_create_index: count++; if (count == 1) g_info << "2: create index " << indnum << " " << *indlist << endl; NdbDictionary::Index ind; char indName[200]; sprintf(indName, "%s_X%u", tabName, indnum); ind.setName(indName); ind.setTable(tabName); if (strcmp(*indlist, "UNIQUE") == 0) { ind.setType(NdbDictionary::Index::UniqueHashIndex); ind.setLogging(pTab->getLogging()); } else if (strcmp(*indlist, "ORDERED") == 0) { ind.setType(NdbDictionary::Index::OrderedIndex); ind.setLogging(false); } else { assert(false); } const char** indtemp = indlist; while (*++indtemp != 0) { ind.addColumn(*indtemp); } if (pDic->createIndex(ind) != 0) { const NdbError err = pDic->getNdbError(); if (count == 1) g_err << "2: " << indName << ": create failed: " << err << endl; if (err.code != 711) { result = NDBT_FAILED; break; } NdbSleep_MilliSleep(myRandom48(maxsleep)); goto try_create_index; } indlist = ++indtemp; indnum++; } if (result == NDBT_FAILED) break; uint indcount = indnum; int records = myRandom48(ctx->getNumRecords()); g_info << "2: load " << records << " records" << endl; HugoTransactions hugoTrans(*pTab); if (hugoTrans.loadTable(pNdb, records) != 0) { // XXX get error code from hugo g_err << "2: " << tabName << ": load failed" << endl; result = NDBT_FAILED; break; } NdbSleep_MilliSleep(myRandom48(maxsleep)); // drop indexes indnum = 0; while (indnum < indcount) { uint count = 0; try_drop_index: count++; if (count == 1) g_info << "2: drop index " << indnum << endl; char indName[200]; sprintf(indName, "%s_X%u", tabName, indnum); if (pDic->dropIndex(indName, tabName) != 0) { const NdbError err = pDic->getNdbError(); if (count == 1) g_err << "2: " << indName << ": drop failed: " << err << endl; if (err.code != 711) { result = NDBT_FAILED; break; } NdbSleep_MilliSleep(myRandom48(maxsleep)); goto try_drop_index; } indnum++; } if (result == NDBT_FAILED) break; g_info << "2: drop" << endl; { uint count = 0; try_drop: count++; if (pDic->dropTable(tabName) != 0) { const NdbError err = pDic->getNdbError(); if (count == 1) g_err << "2: " << tabName << ": drop failed: " << err << endl; if (err.code != 711) { result = NDBT_FAILED; break; } NdbSleep_MilliSleep(myRandom48(maxsleep)); goto try_drop; } } NdbSleep_MilliSleep(myRandom48(maxsleep)); g_info << "2: verify drop" << endl; const NdbDictionary::Table* pTab3 = pDic->getTable(tabName); if (pTab3 != NULL) { g_err << "2: " << tabName << ": verify drop: table exists" << endl; result = NDBT_FAILED; break; } if (pDic->getNdbError().code != 709 && pDic->getNdbError().code != 723) { const NdbError err = pDic->getNdbError(); g_err << "2: " << tabName << ": verify drop: " << err << endl; result = NDBT_FAILED; break; } NdbSleep_MilliSleep(myRandom48(maxsleep)); } return result; } int runBug21755(NDBT_Context* ctx, NDBT_Step* step) { char buf[256]; NdbRestarter res; NdbDictionary::Table pTab0 = * ctx->getTab(); NdbDictionary::Table pTab1 = pTab0; if (res.getNumDbNodes() < 2) return NDBT_OK; Ndb* pNdb = GETNDB(step); NdbDictionary::Dictionary* pDic = pNdb->getDictionary(); if (pDic->createTable(pTab0)) { ndbout << pDic->getNdbError() << endl; return NDBT_FAILED; } NdbDictionary::Index idx0; BaseString::snprintf(buf, sizeof(buf), "%s-idx", pTab0.getName()); idx0.setName(buf); idx0.setType(NdbDictionary::Index::OrderedIndex); idx0.setTable(pTab0.getName()); idx0.setStoredIndex(false); for (Uint32 i = 0; i<pTab0.getNoOfColumns(); i++) { const NdbDictionary::Column * col = pTab0.getColumn(i); if(col->getPrimaryKey()){ idx0.addIndexColumn(col->getName()); } } if (pDic->createIndex(idx0)) { ndbout << pDic->getNdbError() << endl; return NDBT_FAILED; } BaseString::snprintf(buf, sizeof(buf), "%s-2", pTab1.getName()); pTab1.setName(buf); if (pDic->createTable(pTab1)) { ndbout << pDic->getNdbError() << endl; return NDBT_FAILED; } { HugoTransactions t0 (*pDic->getTable(pTab0.getName())); t0.loadTable(pNdb, 1000); } { HugoTransactions t1 (*pDic->getTable(pTab1.getName())); t1.loadTable(pNdb, 1000); } int node = res.getRandomNotMasterNodeId(rand()); res.restartOneDbNode(node, false, true, true); if (pDic->dropTable(pTab1.getName())) { ndbout << pDic->getNdbError() << endl; return NDBT_FAILED; } BaseString::snprintf(buf, sizeof(buf), "%s-idx2", pTab0.getName()); idx0.setName(buf); if (pDic->createIndex(idx0)) { ndbout << pDic->getNdbError() << endl; return NDBT_FAILED; } res.waitNodesNoStart(&node, 1); res.startNodes(&node, 1); if (res.waitClusterStarted()) { return NDBT_FAILED; } if (pDic->dropTable(pTab0.getName())) { ndbout << pDic->getNdbError() << endl; return NDBT_FAILED; } return NDBT_OK; } struct RandSchemaOp { struct Obj { BaseString m_name; Uint32 m_type; struct Obj* m_parent; Vector<Obj*> m_dependant; }; Vector<Obj*> m_objects; int schema_op(Ndb*); int validate(Ndb*); int cleanup(Ndb*); Obj* get_obj(Uint32 mask); int create_table(Ndb*); int create_index(Ndb*, Obj*); int drop_obj(Ndb*, Obj*); void remove_obj(Obj*); }; template class Vector<RandSchemaOp::Obj*>; int RandSchemaOp::schema_op(Ndb* ndb) { struct Obj* obj = 0; Uint32 type = 0; loop: switch((rand() >> 16) & 3){ case 0: return create_table(ndb); case 1: if ((obj = get_obj(1 << NdbDictionary::Object::UserTable)) == 0) goto loop; return create_index(ndb, obj); case 2: type = (1 << NdbDictionary::Object::UserTable); goto drop_object; case 3: type = (1 << NdbDictionary::Object::UniqueHashIndex) | (1 << NdbDictionary::Object::OrderedIndex); goto drop_object; default: goto loop; } drop_object: if ((obj = get_obj(type)) == 0) goto loop; return drop_obj(ndb, obj); } RandSchemaOp::Obj* RandSchemaOp::get_obj(Uint32 mask) { Vector<Obj*> tmp; for (Uint32 i = 0; i<m_objects.size(); i++) { if ((1 << m_objects[i]->m_type) & mask) tmp.push_back(m_objects[i]); } if (tmp.size()) { return tmp[rand()%tmp.size()]; } return 0; } int RandSchemaOp::create_table(Ndb* ndb) { int numTables = NDBT_Tables::getNumTables(); int num = myRandom48(numTables); NdbDictionary::Table pTab = * NDBT_Tables::getTable(num); NdbDictionary::Dictionary* pDict = ndb->getDictionary(); if (pDict->getTable(pTab.getName())) { char buf[100]; BaseString::snprintf(buf, sizeof(buf), "%s-%d", pTab.getName(), rand()); pTab.setName(buf); if (pDict->createTable(pTab)) return NDBT_FAILED; } else { if (NDBT_Tables::createTable(ndb, pTab.getName())) { return NDBT_FAILED; } } ndbout_c("create table %s", pTab.getName()); const NdbDictionary::Table* tab2 = pDict->getTable(pTab.getName()); HugoTransactions trans(*tab2); trans.loadTable(ndb, 1000); Obj *obj = new Obj; obj->m_name.assign(pTab.getName()); obj->m_type = NdbDictionary::Object::UserTable; obj->m_parent = 0; m_objects.push_back(obj); return NDBT_OK; } int RandSchemaOp::create_index(Ndb* ndb, Obj* tab) { NdbDictionary::Dictionary* pDict = ndb->getDictionary(); const NdbDictionary::Table * pTab = pDict->getTable(tab->m_name.c_str()); if (pTab == 0) { return NDBT_FAILED; } bool ordered = (rand() >> 16) & 1; bool stored = (rand() >> 16) & 1; Uint32 type = ordered ? NdbDictionary::Index::OrderedIndex : NdbDictionary::Index::UniqueHashIndex; char buf[255]; BaseString::snprintf(buf, sizeof(buf), "%s-%s", pTab->getName(), ordered ? "OI" : "UI"); if (pDict->getIndex(buf, pTab->getName())) { // Index exists...let it be ok return NDBT_OK; } ndbout_c("create index %s", buf); NdbDictionary::Index idx0; idx0.setName(buf); idx0.setType((NdbDictionary::Index::Type)type); idx0.setTable(pTab->getName()); idx0.setStoredIndex(ordered ? false : stored); for (Uint32 i = 0; i<pTab->getNoOfColumns(); i++) { if (pTab->getColumn(i)->getPrimaryKey()) idx0.addColumn(pTab->getColumn(i)->getName()); } if (pDict->createIndex(idx0)) { ndbout << pDict->getNdbError() << endl; return NDBT_FAILED; } Obj *obj = new Obj; obj->m_name.assign(buf); obj->m_type = type; obj->m_parent = tab; m_objects.push_back(obj); tab->m_dependant.push_back(obj); return NDBT_OK; } int RandSchemaOp::drop_obj(Ndb* ndb, Obj* obj) { NdbDictionary::Dictionary* pDict = ndb->getDictionary(); if (obj->m_type == NdbDictionary::Object::UserTable) { ndbout_c("drop table %s", obj->m_name.c_str()); /** * Drop of table automatically drops all indexes */ if (pDict->dropTable(obj->m_name.c_str())) { return NDBT_FAILED; } while(obj->m_dependant.size()) { remove_obj(obj->m_dependant[0]); } remove_obj(obj); } else if (obj->m_type == NdbDictionary::Object::UniqueHashIndex || obj->m_type == NdbDictionary::Object::OrderedIndex) { ndbout_c("drop index %s", obj->m_name.c_str()); if (pDict->dropIndex(obj->m_name.c_str(), obj->m_parent->m_name.c_str())) { return NDBT_FAILED; } remove_obj(obj); } return NDBT_OK; } void RandSchemaOp::remove_obj(Obj* obj) { Uint32 i; if (obj->m_parent) { bool found = false; for (i = 0; i<obj->m_parent->m_dependant.size(); i++) { if (obj->m_parent->m_dependant[i] == obj) { found = true; obj->m_parent->m_dependant.erase(i); break; } } assert(found); } { bool found = false; for (i = 0; i<m_objects.size(); i++) { if (m_objects[i] == obj) { found = true; m_objects.erase(i); break; } } assert(found); } delete obj; } int RandSchemaOp::validate(Ndb* ndb) { NdbDictionary::Dictionary* pDict = ndb->getDictionary(); for (Uint32 i = 0; i<m_objects.size(); i++) { if (m_objects[i]->m_type == NdbDictionary::Object::UserTable) { const NdbDictionary::Table* tab2 = pDict->getTable(m_objects[i]->m_name.c_str()); HugoTransactions trans(*tab2); trans.scanUpdateRecords(ndb, 1000); trans.clearTable(ndb); trans.loadTable(ndb, 1000); } } return NDBT_OK; } /* SystemTable = 1, ///< System table UserTable = 2, ///< User table (may be temporary) UniqueHashIndex = 3, ///< Unique un-ordered hash index OrderedIndex = 6, ///< Non-unique ordered index HashIndexTrigger = 7, ///< Index maintenance, internal IndexTrigger = 8, ///< Index maintenance, internal SubscriptionTrigger = 9,///< Backup or replication, internal ReadOnlyConstraint = 10,///< Trigger, internal Tablespace = 20, ///< Tablespace LogfileGroup = 21, ///< Logfile group Datafile = 22, ///< Datafile Undofile = 23 ///< Undofile */ int RandSchemaOp::cleanup(Ndb* ndb) { Int32 i; for (i = m_objects.size() - 1; i >= 0; i--) { switch(m_objects[i]->m_type){ case NdbDictionary::Object::UniqueHashIndex: case NdbDictionary::Object::OrderedIndex: if (drop_obj(ndb, m_objects[i])) return NDBT_FAILED; break; default: break; } } for (i = m_objects.size() - 1; i >= 0; i--) { switch(m_objects[i]->m_type){ case NdbDictionary::Object::UserTable: if (drop_obj(ndb, m_objects[i])) return NDBT_FAILED; break; default: break; } } assert(m_objects.size() == 0); return NDBT_OK; } int runDictRestart(NDBT_Context* ctx, NDBT_Step* step) { Ndb* pNdb = GETNDB(step); int loops = ctx->getNumLoops(); NdbMixRestarter res; RandSchemaOp dict; if (res.getNumDbNodes() < 2) return NDBT_OK; if (res.init(ctx, step)) return NDBT_FAILED; for (Uint32 i = 0; i<loops; i++) { for (Uint32 j = 0; j<10; j++) if (dict.schema_op(pNdb)) return NDBT_FAILED; if (res.dostep(ctx, step)) return NDBT_FAILED; if (dict.validate(pNdb)) return NDBT_FAILED; } if (res.finish(ctx, step)) return NDBT_FAILED; if (dict.validate(pNdb)) return NDBT_FAILED; if (dict.cleanup(pNdb)) return NDBT_FAILED; return NDBT_OK; } NDBT_TESTSUITE(testDict); TESTCASE("CreateAndDrop", "Try to create and drop the table loop number of times\n"){ INITIALIZER(runCreateAndDrop); } TESTCASE("CreateAndDropAtRandom", "Try to create and drop table at random loop number of times\n" "Uses all available tables\n" "Uses error insert 4013 to make TUP verify table descriptor"){ INITIALIZER(runCreateAndDropAtRandom); } TESTCASE("CreateAndDropWithData", "Try to create and drop the table when it's filled with data\n" "do this loop number of times\n"){ INITIALIZER(runCreateAndDropWithData); } TESTCASE("CreateAndDropDuring", "Try to create and drop the table when other thread is using it\n" "do this loop number of times\n"){ STEP(runCreateAndDropDuring); STEP(runUseTableUntilStopped); } TESTCASE("CreateInvalidTables", "Try to create the invalid tables we have defined\n"){ INITIALIZER(runCreateInvalidTables); } TESTCASE("CreateTableWhenDbIsFull", "Try to create a new table when db already is full\n"){ INITIALIZER(runCreateTheTable); INITIALIZER(runFillTable); INITIALIZER(runCreateTableWhenDbIsFull); INITIALIZER(runDropTableWhenDbIsFull); FINALIZER(runDropTheTable); } TESTCASE("FragmentTypeSingle", "Create the table with fragment type Single\n"){ TC_PROPERTY("FragmentType", NdbDictionary::Table::FragSingle); INITIALIZER(runTestFragmentTypes); } TESTCASE("FragmentTypeAllSmall", "Create the table with fragment type AllSmall\n"){ TC_PROPERTY("FragmentType", NdbDictionary::Table::FragAllSmall); INITIALIZER(runTestFragmentTypes); } TESTCASE("FragmentTypeAllMedium", "Create the table with fragment type AllMedium\n"){ TC_PROPERTY("FragmentType", NdbDictionary::Table::FragAllMedium); INITIALIZER(runTestFragmentTypes); } TESTCASE("FragmentTypeAllLarge", "Create the table with fragment type AllLarge\n"){ TC_PROPERTY("FragmentType", NdbDictionary::Table::FragAllLarge); INITIALIZER(runTestFragmentTypes); } TESTCASE("TemporaryTables", "Create the table as temporary and make sure it doesn't\n" "contain any data when system is restarted\n"){ INITIALIZER(runTestTemporaryTables); } TESTCASE("CreateMaxTables", "Create tables until db says that it can't create any more\n"){ TC_PROPERTY("tables", 1000); INITIALIZER(runCreateMaxTables); INITIALIZER(runDropMaxTables); } TESTCASE("PkSizes", "Create tables with all different primary key sizes.\n"\ "Test all data operations insert, update, delete etc.\n"\ "Drop table."){ INITIALIZER(runPkSizes); } TESTCASE("StoreFrm", "Test that a frm file can be properly stored as part of the\n" "data in Dict."){ INITIALIZER(runStoreFrm); } TESTCASE("GetPrimaryKey", "Test the function NdbDictionary::Column::getPrimaryKey\n" "It should return true only if the column is part of \n" "the primary key in the table"){ INITIALIZER(runGetPrimaryKey); } TESTCASE("StoreFrmError", "Test that a frm file with too long length can't be stored."){ INITIALIZER(runStoreFrmError); } TESTCASE("NF1", "Test that create table can handle NF (not master)"){ INITIALIZER(runNF1); } TESTCASE("TableRename", "Test basic table rename"){ INITIALIZER(runTableRename); } TESTCASE("TableRenameNF", "Test that table rename can handle node failure"){ INITIALIZER(runTableRenameNF); } TESTCASE("TableRenameSR", "Test that table rename can handle system restart"){ INITIALIZER(runTableRenameSR); } TESTCASE("DictionaryPerf", ""){ INITIALIZER(runTestDictionaryPerf); } TESTCASE("CreateLogfileGroup", ""){ INITIALIZER(runCreateLogfileGroup); } TESTCASE("CreateTablespace", ""){ INITIALIZER(runCreateTablespace); } TESTCASE("CreateDiskTable", ""){ INITIALIZER(runCreateDiskTable); } TESTCASE("FailAddFragment", "Fail add fragment or attribute in ACC or TUP or TUX\n"){ INITIALIZER(runFailAddFragment); } TESTCASE("Restart_NF1", "DICT ops during node graceful shutdown (not master)"){ TC_PROPERTY("Restart_NF_ops", 1); TC_PROPERTY("Restart_NF_type", 1); STEP(runRestarts); STEP(runDictOps); } TESTCASE("Restart_NF2", "DICT ops during node shutdown abort (not master)"){ TC_PROPERTY("Restart_NF_ops", 1); TC_PROPERTY("Restart_NF_type", 2); STEP(runRestarts); STEP(runDictOps); } TESTCASE("Restart_NR1", "DICT ops during node startup (not master)"){ TC_PROPERTY("Restart_NR_ops", 1); STEP(runRestarts); STEP(runDictOps); } TESTCASE("Restart_NR2", "DICT ops during node startup with crash inserts (not master)"){ TC_PROPERTY("Restart_NR_ops", 1); TC_PROPERTY("Restart_NR_error", 1); STEP(runRestarts); STEP(runDictOps); } TESTCASE("Bug21755", ""){ INITIALIZER(runBug21755); } TESTCASE("DictRestart", ""){ INITIALIZER(runDictRestart); } NDBT_TESTSUITE_END(testDict); int main(int argc, const char** argv){ ndb_init(); // Tables should not be auto created testDict.setCreateTable(false); myRandom48Init(NdbTick_CurrentMillisecond()); return testDict.execute(argc, argv); }