From: Date: July 3 2009 4:15pm Subject: bzr commit into mysql-5.1-telco-6.3 branch (frazer:2994) List-Archive: http://lists.mysql.com/commits/77908 Message-Id: <200907031415.n63EFFcD012050@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; CHARSET=US-ASCII Content-Transfer-Encoding: 7BIT #At file:///home/frazer/bzr/mysql-5.1-telco-6.3/ 2994 Frazer Clement 2009-07-03 WL4675 - improve unique index test coverage and testability modified: storage/ndb/test/include/NDBT_Test.hpp storage/ndb/test/ndbapi/testIndex.cpp storage/ndb/test/src/NDBT_Test.cpp storage/ndb/test/tools/create_index.cpp === modified file 'storage/ndb/test/include/NDBT_Test.hpp' --- a/storage/ndb/test/include/NDBT_Test.hpp 2009-05-27 12:11:46 +0000 +++ b/storage/ndb/test/include/NDBT_Test.hpp 2009-07-03 14:15:09 +0000 @@ -402,6 +402,7 @@ private: bool createAllTables; bool temporaryTables; bool nologging; + bool noddl; }; === modified file 'storage/ndb/test/ndbapi/testIndex.cpp' --- a/storage/ndb/test/ndbapi/testIndex.cpp 2009-05-26 18:53:34 +0000 +++ b/storage/ndb/test/ndbapi/testIndex.cpp 2009-07-03 14:15:09 +0000 @@ -197,21 +197,42 @@ int create_index(NDBT_Context* ctx, int 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; + bool noddl= ctx->getProperty("NoDDL"); - if (err.status == NdbError::TemporaryError) - return SKIP_INDEX; - - return NDBT_FAILED; - } else { - ndbout << "OK!" << endl; - attr->indexCreated = true; + if (noddl) + { + const NdbDictionary::Index* idx= pNdb-> + getDictionary()->getIndex(pIdx.getName(), pTab->getName()); + + if (!idx) + { + ndbout << "Failed - Index does not exist and DDL not allowed" << endl; + return NDBT_FAILED; + } + else + { + attr->indexCreated = false; + // TODO : Check index definition is ok + } + } + else + { + 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; + + if (err.status == NdbError::TemporaryError) + return SKIP_INDEX; + + return NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + attr->indexCreated = true; + } } return result; } @@ -337,7 +358,8 @@ int createPkIndex(NDBT_Context* ctx, NDB Ndb* pNdb = GETNDB(step); bool logged = ctx->getProperty("LoggedIndexes", 1); - + bool noddl= ctx->getProperty("NoDDL"); + // Create index BaseString::snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName()); if (orderedIndex) @@ -363,11 +385,30 @@ int createPkIndex(NDBT_Context* ctx, NDB pIdx.setStoredIndex(logged); ndbout << ") "; - if (pNdb->getDictionary()->createIndex(pIdx) != 0){ - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - return NDBT_FAILED; + if (noddl) + { + const NdbDictionary::Index* idx= pNdb-> + getDictionary()->getIndex(pkIdxName, pTab->getName()); + + if (!idx) + { + ndbout << "Failed - Index does not exist and DDL not allowed" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } + else + { + // TODO : Check index definition is ok + } + } + else + { + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + return NDBT_FAILED; + } } ndbout << "OK!" << endl; @@ -378,15 +419,20 @@ int createPkIndex_Drop(NDBT_Context* ctx const NdbDictionary::Table* pTab = ctx->getTab(); Ndb* pNdb = GETNDB(step); + bool noddl= ctx->getProperty("NoDDL"); + // 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; + if (!noddl) + { + 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; @@ -755,7 +801,6 @@ int runSystemRestart1(NDBT_Context* ctx, 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; @@ -887,6 +932,17 @@ int runSystemRestart1(NDBT_Context* ctx, } #define CHECK2(b, t) if(!b){ g_err << __LINE__ << ": " << t << endl; break;} +#define CHECKOKORTIMEOUT(e, t) { int rc= (e); \ + if (rc != 0) { \ + if (rc == 266) { \ + g_err << "Timeout : retries left : " \ + << timeoutRetries \ + << endl; \ + continue; \ + } \ + g_err << __LINE__ << ": " << (t) << endl; break; \ + } } + int runMixed1(NDBT_Context* ctx, NDBT_Step* step){ @@ -895,6 +951,7 @@ runMixed1(NDBT_Context* ctx, NDBT_Step* Ndb* pNdb = GETNDB(step); HugoOperations hugoOps(*ctx->getTab()); + /* Old, rather ineffective testcase which nonetheless passes on 6.3 */ do { // TC1 @@ -950,6 +1007,413 @@ runMixed1(NDBT_Context* ctx, NDBT_Step* return NDBT_FAILED; } + + +int +runMixedUpdateInterleaved(Ndb* pNdb, + HugoOperations& hugoOps, + int outOfRangeRec, + int testSize, + bool commit, + bool abort, + int pkFailRec, + int ixFailRec, + bool invertFail, + AbortOption ao, + int whatToUpdate, + int updatesValue, + bool ixFirst) +{ + Uint32 execRc= 0; + if ((pkFailRec != -1) || (ixFailRec != -1)) + { + execRc= 626; + } + + bool updateViaPk= whatToUpdate & 1; + bool updateViaIx= whatToUpdate & 2; + + int ixOpNum= (ixFirst?0:1); + int pkOpNum= (ixFirst?1:0); + + int timeoutRetries= 3; + + while (timeoutRetries--) + { + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + for (int i=0; i < testSize; i++) + { + /* invertFail causes all issued reads *except* the fail record number + * to fail + */ + int indxKey= ((i == ixFailRec)^invertFail)? outOfRangeRec : i; + int pkKey= ((i == pkFailRec)^invertFail)? outOfRangeRec : i; + + for (int opNum=0; opNum < 2; opNum++) + { + if (opNum == ixOpNum) + { + if (updateViaIx) + { + CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, indxKey, 1, updatesValue) == 0, + "indexUpdateRecord"); + } + else + { + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, indxKey) == 0, "indexReadRecords"); + } + } + + if (opNum == pkOpNum) + { + if (updateViaPk) + { + CHECK2(hugoOps.pkUpdateRecord(pNdb, pkKey, 1, updatesValue) == 0, + "pkUpdateRecord"); + } + else + { + CHECK2(hugoOps.pkReadRecord(pNdb, pkKey) == 0, "pkReadRecord"); + } + } + } + } + if (commit) + { + int rc= hugoOps.execute_Commit(pNdb, ao); + if (rc == 266) + { + /* Timeout */ + g_err << "Timeout : retries left=" << timeoutRetries << endl; + hugoOps.closeTransaction(pNdb); + continue; + } + CHECK2(rc == execRc, "execute_Commit"); + NdbError err= hugoOps.getTransaction()->getNdbError(); + CHECK2(err.code == execRc, "getNdbError"); + } + else + { + int rc= hugoOps.execute_NoCommit(pNdb, ao); + if (rc == 266) + { + /* Timeout */ + g_err << "Timeout : retries left=" << timeoutRetries << endl; + hugoOps.closeTransaction(pNdb); + continue; + } + CHECK2(rc == execRc, "execute_NoCommit"); + NdbError err= hugoOps.getTransaction()->getNdbError(); + CHECK2(err.code == execRc, "getNdbError"); + if (execRc && (ao == AO_IgnoreError)) + { + /* Transaction should still be open, let's commit it */ + CHECK2(hugoOps.execute_Commit(pNdb, ao) == 0, "executeCommit"); + } + else if (abort) + { + CHECK2(hugoOps.execute_Rollback(pNdb) == 0, "executeRollback"); + } + } + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + return 1; + } + + hugoOps.closeTransaction(pNdb); + return 0; +} + + + +int +runMixed2(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + HugoOperations hugoOps(*ctx->getTab()); + + int numRecordsInTable= ctx->getNumRecords(); + const int maxTestSize= 10000; + int testSize= MIN(numRecordsInTable, maxTestSize); + + /* Avoid overloading Send Buffers */ + Uint32 rowSize= NdbDictionary::getRecordRowLength(ctx->getTab()->getDefaultRecord()); + Uint32 dataXfer= 2 * rowSize * testSize; + const Uint32 MaxDataXfer= 500000; // 0.5M + + if (dataXfer > MaxDataXfer) + { + testSize= MIN((int)(MaxDataXfer/rowSize), testSize); + } + + g_err << "testSize= " << testSize << endl; + g_err << "rowSize= " << rowSize << endl; + + int updatesValue= 1; + const int maxTimeoutRetries= 3; + + do { + // TC0 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC0 : indexRead, pkread, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + ok= true; + break; + } + if (!ok) { break; }; + } + + + // TC1 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC1 : pkRead, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC2 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC2 : pkRead, indexRead, NoCommit, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, + "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_NoCommit(pNdb), "executeNoCommit"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC3 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC3 : pkRead, pkRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords "); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC4 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC4 : indexRead, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC5 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC5 : indexRead, pkUpdate, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECK2(hugoOps.pkUpdateRecord(pNdb, 0, testSize, updatesValue++) == 0, "pkUpdateRecord"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC6 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC6 : pkUpdate, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkUpdateRecord(pNdb, 0, testSize, updatesValue++) == 0, "pkUpdateRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC7 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC7 : pkRead, indexUpdate, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, 0, testSize, updatesValue++) == 0, + "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC8 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC8 : indexUpdate, pkRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, 0, testSize, updatesValue++) == 0, + "indexReadRecords "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords "); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + ok= true; + break; + } + if (!ok) { break; }; + } + + for (int ao=0; ao < 2; ao++) + { + AbortOption abortOption= ao?AO_IgnoreError:AbortOnError; + + for (int exType=0; exType < 3; exType++) + { + bool commit= (exType == 1); + bool abort= (exType == 2); + + const char* exTypeStr= ((exType == 0) ? "NoCommit" : + (exType == 1) ? "Commit" : + "Abort"); + + for (int failType= 0; failType < 4; failType++) + { + for (int failPos= 0; failPos < 2; failPos++) + { + int failRec= (failPos == 0)? 0 : testSize -1; + int pkFailRec= -1; + int ixFailRec= -1; + if (failType) + { + if (failType & 1) + pkFailRec= failRec; + if (failType & 2) + ixFailRec= failRec; + } + + for (int invFail= 0; + invFail < ((failType==0)?1:2); + invFail++) + { + bool invertFail= (invFail)?true:false; + const char* failTypeStr= ((failType==0)? "None" : + ((failType==1)? "Pk": + ((failType==2)?"Ix": "Both"))); + for (int updateVia= 0; updateVia < 3; updateVia++) + { + const char* updateViaStr= ((updateVia == 0)? "None" : + (updateVia == 1)? "Pk" : + (updateVia == 2)? "Ix" : + "Both"); + for (int updateOrder= 0; updateOrder < 2; updateOrder++) + { + bool updateIxFirst= (updateOrder == 0); + g_err << endl + << "AbortOption : " << (ao?"IgnoreError":"AbortOnError") << endl + << "ExecType : " << exTypeStr << endl + << "Failtype : " << failTypeStr << endl + << "Failpos : " << ((failPos == 0)? "Early" : "Late") << endl + << "Failure scenarios : " << (invFail?"All but one":"one") << endl + << "UpdateVia : " << updateViaStr << endl + << "Order : " << (updateIxFirst? "Index First" : "Pk first") << endl; + bool ok= false; + do + { + g_err << "Mixed read/update interleaved" << endl; + CHECK2(runMixedUpdateInterleaved(pNdb, hugoOps, numRecordsInTable, testSize, + commit, // Commit + abort, // Abort + pkFailRec, // PkFail + ixFailRec, // IxFail + invertFail, // Invertfail + abortOption, + updateVia, + updatesValue++, + updateIxFirst), + "TC4"); + + ok= true; + } while (false); + + if (!ok) + { + hugoOps.closeTransaction(pNdb); + return NDBT_FAILED; + } + } + } + } + } + } + } + } + + 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 @@ -1139,13 +1603,33 @@ runUniqueNullTransactions(NDBT_Context* return NDBT_FAILED; } - if (pNdb->getDictionary()->createIndex(pIdx) != 0){ - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - return NDBT_FAILED; + bool noddl= ctx->getProperty("NoDDL"); + if (noddl) + { + const NdbDictionary::Index* idx= pNdb-> + getDictionary()->getIndex(pIdx.getName(), pTab->getName()); + + if (!idx) + { + ndbout << "Failed - Index does not exist and DDL not allowed" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } + else + { + // TODO : Check index definition is ok + } } - + else + { + 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()); @@ -1172,7 +1656,6 @@ runUniqueNullTransactions(NDBT_Context* result = NDBT_FAILED; pTrans = pNdb->startTransaction(); NdbScanOperation * sOp; - NdbOperation * uOp; int eof; if(!pTrans) goto done; sOp = pTrans->getNdbScanOperation(pTab->getName()); @@ -1196,7 +1679,6 @@ runUniqueNullTransactions(NDBT_Context* } int runLQHKEYREF(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; int loops = ctx->getNumLoops() * 100; NdbRestarter restarter; @@ -1286,7 +1768,7 @@ runBug25059(NDBT_Context* ctx, NDBT_Step ops.startTransaction(pNdb); ops.pkReadRecord(pNdb, 10 + rand() % rows, rows); int tmp; - if (tmp = ops.execute_Commit(pNdb, AO_IgnoreError)) + if ((tmp = ops.execute_Commit(pNdb, AO_IgnoreError))) { if (tmp == 4012) res = NDBT_FAILED; @@ -1313,7 +1795,7 @@ runBug25059(NDBT_Context* ctx, NDBT_Step ndbout_c("ignore error"); break; } - if (tmp = ops.execute_Commit(pNdb, (AbortOption)arg)) + if ((tmp = ops.execute_Commit(pNdb, (AbortOption)arg))) { if (tmp == 4012) res = NDBT_FAILED; @@ -1343,7 +1825,6 @@ int tcSaveINDX_test(NDBT_Context* ctx, N int loops = ctx->getNumLoops(); const int rows = ctx->getNumRecords(); - const int batchsize = ctx->getProperty("BatchSize", 1); for(int bs=1; bs < loops; bs++) { @@ -1687,6 +2168,16 @@ TESTCASE("MixedTransaction", FINALIZER(createPkIndex_Drop); FINALIZER(runClearTable); } +TESTCASE("MixedTransaction2", + "Test mixing of index and normal operations with batching"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runMixed2); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} TESTCASE("SR1_O", "Test that indexes are correctly maintained during SR"){ TC_PROPERTY("OrderedIndex", 1); === modified file 'storage/ndb/test/src/NDBT_Test.cpp' --- a/storage/ndb/test/src/NDBT_Test.cpp 2009-05-27 12:11:46 +0000 +++ b/storage/ndb/test/src/NDBT_Test.cpp 2009-07-03 14:15:09 +0000 @@ -775,6 +775,7 @@ NDBT_TestSuite::NDBT_TestSuite(const cha createAllTables = false; temporaryTables = false; nologging = false; + noddl= false; } @@ -867,26 +868,48 @@ int NDBT_TestSuite::executeAll(Ndb_clust const NdbDictionary::Table* pTab = NDBT_Tables::getTable(t); const NdbDictionary::Table* pTab2 = pDict->getTable(pTab->getName()); - if(pTab2 != 0 && pDict->dropTable(pTab->getName()) != 0) - { - numTestsFail++; - numTestsExecuted++; - g_err << "ERROR0: Failed to drop table " << pTab->getName() << endl; - tests[i]->saveTestResult(pTab, FAILED_TO_CREATE); - continue; - } - - if (NDBT_Tables::createTable(&ndb, pTab->getName(), - nologging, false, - g_create_hook, this) != 0) { - numTestsFail++; - numTestsExecuted++; - g_err << "ERROR1: Failed to create table " << pTab->getName() - << pDict->getNdbError() << endl; - tests[i]->saveTestResult(pTab, FAILED_TO_CREATE); - continue; - } - pTab2 = pDict->getTable(pTab->getName()); + if (noddl) + { + if (!pTab2) + { + numTestsFail++; + numTestsExecuted++; + g_err << "ERROR : Table not defined and DDL not allowed " + << pTab->getName() << endl; + g_err << "Required schema : " << *((NDBT_Table*)pTab) << endl; + tests[i]->saveTestResult(pTab, FAILED_TO_CREATE); + continue; + } + else + { + /* TODO : Check that table in DB is sufficiently similar to + * what we expect + */ + } + } + else + { + if(pTab2 != 0 && pDict->dropTable(pTab->getName()) != 0) + { + numTestsFail++; + numTestsExecuted++; + g_err << "ERROR0: Failed to drop table " << pTab->getName() << endl; + tests[i]->saveTestResult(pTab, FAILED_TO_CREATE); + continue; + } + + if (NDBT_Tables::createTable(&ndb, pTab->getName(), + nologging, false, + g_create_hook, this) != 0) { + numTestsFail++; + numTestsExecuted++; + g_err << "ERROR1: Failed to create table " << pTab->getName() + << pDict->getNdbError() << endl; + tests[i]->saveTestResult(pTab, FAILED_TO_CREATE); + continue; + } + pTab2 = pDict->getTable(pTab->getName()); + } ctx->addTab(pTab2); } @@ -896,6 +919,7 @@ int NDBT_TestSuite::executeAll(Ndb_clust if(remote_mgm != NULL) ctx->setRemoteMgm(remote_mgm); ctx->setSuite(this); + ctx->setProperty("NoDDL", (Uint32)noddl); const NdbDictionary::Table** tables= ctx->getTables(); @@ -909,10 +933,13 @@ int NDBT_TestSuite::executeAll(Ndb_clust if(result == NDBT_OK) { - for(t = 0; tables[t] != 0; t++) - { - pDict->dropTable(tables[t]->getName()); - } + if (!noddl) + { + for(t = 0; tables[t] != 0; t++) + { + pDict->dropTable(tables[t]->getName()); + } + } } delete ctx; @@ -990,6 +1017,7 @@ NDBT_TestSuite::executeOneCtx(Ndb_cluste if(remote_mgm != NULL) ctx->setRemoteMgm(remote_mgm); ctx->setSuite(this); + ctx->setProperty("NoDDL", (Uint32) noddl); result = tests[t]->execute(ctx); if (result != NDBT_OK) @@ -1062,28 +1090,51 @@ void NDBT_TestSuite::execute(Ndb_cluster NdbDictionary::Dictionary* pDict = ndb->getDictionary(); const NdbDictionary::Table* pTab2 = pDict->getTable(pTab->getName()); - if (createTable == true){ - - if(pTab2 != 0 && pDict->dropTable(pTab->getName()) != 0){ - numTestsFail++; - numTestsExecuted++; - g_err << "ERROR0: Failed to drop table " << pTab->getName() << endl; - tests[t]->saveTestResult(pTab, FAILED_TO_CREATE); - continue; + if (noddl) + { + if (!pTab2) + { + numTestsFail++; + numTestsExecuted++; + g_err << "ERROR : Table not defined and DDL not allowed " + << pTab->getName() << endl; + g_err << "Required schema : " << *((NDBT_Table*)pTab) << endl; + tests[t]->saveTestResult(pTab, FAILED_TO_CREATE); + continue; } - - if (NDBT_Tables::createTable(ndb, pTab->getName(), nologging, false, - g_create_hook, this) != 0) { - numTestsFail++; - numTestsExecuted++; - g_err << "ERROR1: Failed to create table " << pTab->getName() - << pDict->getNdbError() << endl; - tests[t]->saveTestResult(pTab, FAILED_TO_CREATE); - continue; + else + { + /* TODO : Check that table in DB is sufficiently similar to + * what we expect + */ + } + } + else + { + if (createTable) + { + if(pTab2 != 0 && pDict->dropTable(pTab->getName()) != 0){ + numTestsFail++; + numTestsExecuted++; + g_err << "ERROR0: Failed to drop table " << pTab->getName() << endl; + tests[t]->saveTestResult(pTab, FAILED_TO_CREATE); + continue; + } + + if (NDBT_Tables::createTable(ndb, pTab->getName(), nologging, false, + g_create_hook, this) != 0) { + numTestsFail++; + numTestsExecuted++; + g_err << "ERROR1: Failed to create table " << pTab->getName() + << pDict->getNdbError() << endl; + tests[t]->saveTestResult(pTab, FAILED_TO_CREATE); + continue; + } + pTab2 = pDict->getTable(pTab->getName()); + } else if(!pTab2) { + // Weird - used in testDict? + pTab2 = pTab; } - pTab2 = pDict->getTable(pTab->getName()); - } else if(!pTab2) { - pTab2 = pTab; } ctx = new NDBT_Context(con); @@ -1093,6 +1144,7 @@ void NDBT_TestSuite::execute(Ndb_cluster if(remote_mgm != NULL) ctx->setRemoteMgm(remote_mgm); ctx->setSuite(this); + ctx->setProperty("NoDDL", (Uint32) noddl); result = tests[t]->execute(ctx); tests[t]->saveTestResult(pTab, result); @@ -1102,7 +1154,10 @@ void NDBT_TestSuite::execute(Ndb_cluster numTestsOk++; numTestsExecuted++; - if (result == NDBT_OK && createTable == true && createAllTables == false){ + if (result == NDBT_OK && + createTable == true && + createAllTables == false && + !noddl){ pDict->dropTable(pTab->getName()); } @@ -1194,6 +1249,7 @@ static int opt_verbose; static int opt_seed = 0; static int opt_nologging = 0; static int opt_temporary = 0; +static int opt_noddl = 0; static struct my_option my_long_options[] = { @@ -1235,6 +1291,9 @@ static struct my_option my_long_options[ { "nologging", 0, "Create table(s) wo/ logging", (uchar **) &opt_nologging, (uchar **) &opt_nologging, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "noddl", 0, "Don't create/drop tables as part of running tests", + (uchar**) &opt_noddl, (uchar**) &opt_noddl, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1315,6 +1374,7 @@ int NDBT_TestSuite::execute(int argc, co timer = opt_timer; nologging = opt_nologging; temporaryTables = opt_temporary; + noddl = opt_noddl; Ndb_cluster_connection con; if(con.connect(12, 5, 1)) @@ -1355,18 +1415,36 @@ int NDBT_TestSuite::execute(int argc, co { const char *tab_name= m_tables_in_test[i].c_str(); const NdbDictionary::Table* pTab = pDict->getTable(tab_name); - if (pTab && pDict->dropTable(tab_name) != 0) - { - g_err << "ERROR0: Failed to drop table " << tab_name - << pDict->getNdbError() << endl; - return NDBT_ProgramExit(NDBT_FAILED); - } - if(NDBT_Tables::createTable(&ndb, tab_name, nologging) != 0) - { - g_err << "ERROR1: Failed to create table " << tab_name - << pDict->getNdbError() << endl; - return NDBT_ProgramExit(NDBT_FAILED); - } + if (noddl) + { + if (!pTab) + { + g_err << "ERROR : Table " << tab_name + << " does not exist and DDL not allowed" << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + else + { + /* TODO : Check that table in DB is sufficiently similar to + * what we expect + */ + } + } + else + { + if (pTab && pDict->dropTable(tab_name) != 0) + { + g_err << "ERROR0: Failed to drop table " << tab_name + << pDict->getNdbError() << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + if(NDBT_Tables::createTable(&ndb, tab_name, nologging) != 0) + { + g_err << "ERROR1: Failed to create table " << tab_name + << pDict->getNdbError() << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + } } } } @@ -1383,7 +1461,9 @@ int NDBT_TestSuite::execute(int argc, co res = report(opt_testname); } - if (res == NDBT_OK && createAllTables == true) + if (res == NDBT_OK && + createAllTables == true && + !noddl) { Ndb ndb(&con, "TEST_DB"); ndb.init(1024); === modified file 'storage/ndb/test/tools/create_index.cpp' --- a/storage/ndb/test/tools/create_index.cpp 2009-05-26 18:53:34 +0000 +++ b/storage/ndb/test/tools/create_index.cpp 2009-07-03 14:15:09 +0000 @@ -33,12 +33,16 @@ main(int argc, const char** argv){ const char* _dbname = "TEST_DB"; int _help = 0; int _ordered = 0, _pk = 1; + char* _iname= NULL; + char* _tname= NULL; struct getargs args[] = { { "database", 'd', arg_string, &_dbname, "dbname", "Name of database table is in"}, { "ordered", 'o', arg_flag, &_ordered, "Create ordered index", "" }, { "pk", 'p', arg_flag, &_pk, "Create index on primary key", "" }, + { "idxname", 'i', arg_string, &_iname, "idxname", "Override default name for index" }, + { "tabname", 't', arg_string, &_tname, "tabname", "Specify single tabname and list of col names as args" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; @@ -73,16 +77,15 @@ main(int argc, const char** argv){ NdbDictionary::Dictionary * dict = MyNdb.getDictionary(); for(int i = optind; igetTable(argv[i]); + const char* tabName= (_tname)? _tname : argv[i]; + const NdbDictionary::Table * tab = dict->getTable(tabName); if(tab == 0){ - g_err << "Unknown table: " << argv[i] << endl; + g_err << "Unknown table: " << tabName << endl; + if (_tname) + return NDBT_ProgramExit(NDBT_FAILED); continue; } - if(tab->getNoOfColumns() > 16){ - g_err << "Table " << argv[i] << " has more than 16 columns" << endl; - } - NdbDictionary::Index ind; if(_ordered){ ind.setType(NdbDictionary::Index::OrderedIndex); @@ -91,20 +94,59 @@ main(int argc, const char** argv){ ind.setType(NdbDictionary::Index::UniqueHashIndex); } char buf[512]; - sprintf(buf, "IND_%s_%s_%c", - argv[i], (_pk ? "PK" : "FULL"), (_ordered ? 'O' : 'U')); - ind.setName(buf); - ind.setTable(argv[i]); - for(int c = 0; cgetNoOfColumns(); c++){ - if(!_pk || tab->getColumn(c)->getPrimaryKey()) - ind.addIndexColumn(tab->getColumn(c)->getName()); + if (!_iname) + { + sprintf(buf, "IND_%s_%s_%c", + argv[i], (_pk ? "PK" : "FULL"), (_ordered ? 'O' : 'U')); + ind.setName(buf); + } + else + { + ind.setName(_iname); + } + + ind.setTable(tabName); + + if (!_tname) + { + ndbout << "creating index " << ind.getName() << " on table " << tabName + << "("; + for(int c = 0; cgetNoOfColumns(); c++){ + if(!_pk || tab->getColumn(c)->getPrimaryKey()) + { + ndbout << tab->getColumn(c)->getName() << ", "; + ind.addIndexColumn(tab->getColumn(c)->getName()); + } + } + ndbout << ")" << endl; + } + else + { + /* Treat args as column names */ + ndbout << "creating index " << ind.getName() << " on table " << tabName + << "("; + for(int argNum=i; argNum < argc; argNum++) + { + const char* colName= argv[argNum]; + if (tab->getColumn(colName) == NULL) + { + g_err << "Column " << colName << " does not exist in table " << tabName + << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + ndbout << colName << ", "; + ind.addIndexColumn(colName); + } + ndbout << ")" << endl; } - ndbout << "creating index " << buf << " on table " << argv[i] << "..."; const int res = dict->createIndex(ind); if(res != 0) ndbout << endl << dict->getNdbError() << endl; else ndbout << "OK" << endl; + + if (_tname) // Just create a single index + return NDBT_ProgramExit(NDBT_OK); } return NDBT_ProgramExit(NDBT_OK);