📄 ndbt_test.cpp
字号:
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */#include <ndb_global.h>#include <my_pthread.h>#include "NDBT.hpp"#include "NDBT_Test.hpp"#include <PortDefs.h>#include <getarg.h>#include <time.h>// No verbose outxputNDBT_Context::NDBT_Context(Ndb_cluster_connection& con) : m_cluster_connection(con){ tab = NULL; suite = NULL; testcase = NULL; ndb = NULL; records = 1; loops = 1; stopped = false; remote_mgm =""; propertyMutexPtr = NdbMutex_Create(); propertyCondPtr = NdbCondition_Create();} char * NDBT_Context::getRemoteMgm() const { return remote_mgm;} void NDBT_Context::setRemoteMgm(char * mgm) { remote_mgm = strdup(mgm);} NDBT_Context::~NDBT_Context(){ NdbCondition_Destroy(propertyCondPtr); NdbMutex_Destroy(propertyMutexPtr);}const NdbDictionary::Table* NDBT_Context::getTab(){ assert(tab != NULL); return tab;}NDBT_TestSuite* NDBT_Context::getSuite(){ assert(suite != NULL); return suite;}NDBT_TestCase* NDBT_Context::getCase(){ assert(testcase != NULL); return testcase;}int NDBT_Context::getNumRecords() const{ return records; }int NDBT_Context::getNumLoops() const{ return loops;}int NDBT_Context::getNoOfRunningSteps() const { return testcase->getNoOfRunningSteps(); }int NDBT_Context::getNoOfCompletedSteps() const { return testcase->getNoOfCompletedSteps();}Uint32 NDBT_Context::getProperty(const char* _name, Uint32 _default){ Uint32 val; NdbMutex_Lock(propertyMutexPtr); if(!props.get(_name, &val)) val = _default; NdbMutex_Unlock(propertyMutexPtr); return val;}bool NDBT_Context::getPropertyWait(const char* _name, Uint32 _waitVal){ bool result; NdbMutex_Lock(propertyMutexPtr); Uint32 val =! _waitVal; while((!props.get(_name, &val) || (props.get(_name, &val) && val != _waitVal)) && !stopped) NdbCondition_Wait(propertyCondPtr, propertyMutexPtr); result = (val == _waitVal); NdbMutex_Unlock(propertyMutexPtr); return stopped;}const char* NDBT_Context::getProperty(const char* _name, const char* _default){ const char* val; NdbMutex_Lock(propertyMutexPtr); if(!props.get(_name, &val)) val = _default; NdbMutex_Unlock(propertyMutexPtr); return val;}const char* NDBT_Context::getPropertyWait(const char* _name, const char* _waitVal){ const char* val; NdbMutex_Lock(propertyMutexPtr); while(!props.get(_name, &val) && (strcmp(val, _waitVal)==0)) NdbCondition_Wait(propertyCondPtr, propertyMutexPtr); NdbMutex_Unlock(propertyMutexPtr); return val;}void NDBT_Context::setProperty(const char* _name, Uint32 _val){ NdbMutex_Lock(propertyMutexPtr); const bool b = props.put(_name, _val, true); assert(b == true); NdbMutex_Unlock(propertyMutexPtr);}voidNDBT_Context::decProperty(const char * name){ NdbMutex_Lock(propertyMutexPtr); Uint32 val = 0; if(props.get(name, &val)){ assert(val > 0); props.put(name, (val - 1), true); } NdbCondition_Broadcast(propertyCondPtr); NdbMutex_Unlock(propertyMutexPtr);}voidNDBT_Context::incProperty(const char * name){ NdbMutex_Lock(propertyMutexPtr); Uint32 val = 0; props.get(name, &val); props.put(name, (val + 1), true); NdbCondition_Broadcast(propertyCondPtr); NdbMutex_Unlock(propertyMutexPtr);}void NDBT_Context::setProperty(const char* _name, const char* _val){ NdbMutex_Lock(propertyMutexPtr); const bool b = props.put(_name, _val); assert(b == true); NdbMutex_Unlock(propertyMutexPtr);}void NDBT_Context::stopTest(){ NdbMutex_Lock(propertyMutexPtr); g_info << "|- stopTest called" << endl; stopped = true; NdbCondition_Broadcast(propertyCondPtr); NdbMutex_Unlock(propertyMutexPtr);}bool NDBT_Context::isTestStopped(){ NdbMutex_Lock(propertyMutexPtr); bool val = stopped; NdbMutex_Unlock(propertyMutexPtr); return val;}void NDBT_Context::wait(){ NdbMutex_Lock(propertyMutexPtr); NdbCondition_Wait(propertyCondPtr, propertyMutexPtr); NdbMutex_Unlock(propertyMutexPtr);}void NDBT_Context::wait_timeout(int msec){ NdbMutex_Lock(propertyMutexPtr); NdbCondition_WaitTimeout(propertyCondPtr, propertyMutexPtr, msec); NdbMutex_Unlock(propertyMutexPtr);}void NDBT_Context::broadcast(){ NdbMutex_Lock(propertyMutexPtr); NdbCondition_Broadcast(propertyCondPtr); NdbMutex_Unlock(propertyMutexPtr);}Uint32 NDBT_Context::getDbProperty(const char*){ abort(); return 0;}bool NDBT_Context::setDbProperty(const char*, Uint32){ abort(); return true;}void NDBT_Context::setTab(const NdbDictionary::Table* ptab){ assert(ptab != NULL); tab = ptab;}void NDBT_Context::setSuite(NDBT_TestSuite* psuite){ assert(psuite != NULL); suite = psuite;}void NDBT_Context::setCase(NDBT_TestCase* pcase){ assert(pcase != NULL); testcase = pcase;}void NDBT_Context::setNumRecords(int _records){ records = _records; }void NDBT_Context::setNumLoops(int _loops){ loops = _loops;}NDBT_Step::NDBT_Step(NDBT_TestCase* ptest, const char* pname, NDBT_TESTFUNC* pfunc): name(pname){ assert(pfunc != NULL); func = pfunc; testcase = ptest; step_no = -1;}int NDBT_Step::execute(NDBT_Context* ctx) { assert(ctx != NULL); int result; g_info << " |- " << name << " started [" << ctx->suite->getDate() << "]" << endl; result = setUp(ctx->m_cluster_connection); if (result != NDBT_OK){ return result; } result = func(ctx, this); if (result != NDBT_OK) { g_err << " |- " << name << " FAILED [" << ctx->suite->getDate() << "]" << endl; } else { g_info << " |- " << name << " PASSED [" << ctx->suite->getDate() << "]" << endl; } tearDown(); return result;}void NDBT_Step::setContext(NDBT_Context* pctx){ assert(pctx != NULL); m_ctx = pctx;}NDBT_Context* NDBT_Step::getContext(){ assert(m_ctx != NULL); return m_ctx;}NDBT_NdbApiStep::NDBT_NdbApiStep(NDBT_TestCase* ptest, const char* pname, NDBT_TESTFUNC* pfunc) : NDBT_Step(ptest, pname, pfunc), ndb(NULL) {}intNDBT_NdbApiStep::setUp(Ndb_cluster_connection& con){ ndb = new Ndb(&con, "TEST_DB" ); ndb->init(1024); int result = ndb->waitUntilReady(300); // 5 minutes if (result != 0){ g_err << name << ": Ndb was not ready" << endl; return NDBT_FAILED; } return NDBT_OK;}void NDBT_NdbApiStep::tearDown(){ delete ndb; ndb = NULL;}Ndb* NDBT_NdbApiStep::getNdb(){ assert(ndb != NULL); return ndb;}NDBT_ParallelStep::NDBT_ParallelStep(NDBT_TestCase* ptest, const char* pname, NDBT_TESTFUNC* pfunc) : NDBT_NdbApiStep(ptest, pname, pfunc) {}NDBT_Verifier::NDBT_Verifier(NDBT_TestCase* ptest, const char* pname, NDBT_TESTFUNC* pfunc) : NDBT_NdbApiStep(ptest, pname, pfunc) {}NDBT_Initializer::NDBT_Initializer(NDBT_TestCase* ptest, const char* pname, NDBT_TESTFUNC* pfunc) : NDBT_NdbApiStep(ptest, pname, pfunc) {}NDBT_Finalizer::NDBT_Finalizer(NDBT_TestCase* ptest, const char* pname, NDBT_TESTFUNC* pfunc) : NDBT_NdbApiStep(ptest, pname, pfunc) {}NDBT_TestCase::NDBT_TestCase(NDBT_TestSuite* psuite, const char* pname, const char* pcomment) : name(strdup(pname)) , comment(strdup(pcomment)), suite(psuite){ _name.assign(pname); _comment.assign(pcomment); name= _name.c_str(); comment= _comment.c_str(); assert(suite != NULL);}NDBT_TestCaseImpl1::NDBT_TestCaseImpl1(NDBT_TestSuite* psuite, const char* pname, const char* pcomment) : NDBT_TestCase(psuite, pname, pcomment){ numStepsOk = 0; numStepsFail = 0; numStepsCompleted = 0; waitThreadsMutexPtr = NdbMutex_Create(); waitThreadsCondPtr = NdbCondition_Create();}NDBT_TestCaseImpl1::~NDBT_TestCaseImpl1(){ NdbCondition_Destroy(waitThreadsCondPtr); NdbMutex_Destroy(waitThreadsMutexPtr); size_t i; for(i = 0; i < initializers.size(); i++) delete initializers[i]; initializers.clear(); for(i = 0; i < verifiers.size(); i++) delete verifiers[i]; verifiers.clear(); for(i = 0; i < finalizers.size(); i++) delete finalizers[i]; finalizers.clear(); for(i = 0; i < steps.size(); i++) delete steps[i]; steps.clear(); results.clear(); for(i = 0; i < testTables.size(); i++) delete testTables[i]; testTables.clear(); for(i = 0; i < testResults.size(); i++) delete testResults[i]; testResults.clear();}int NDBT_TestCaseImpl1::addStep(NDBT_Step* pStep){ assert(pStep != NULL); steps.push_back(pStep); pStep->setStepNo(steps.size()); int res = NORESULT; results.push_back(res); return 0;}int NDBT_TestCaseImpl1::addVerifier(NDBT_Verifier* pVerifier){ assert(pVerifier != NULL); verifiers.push_back(pVerifier); return 0;}int NDBT_TestCaseImpl1::addInitializer(NDBT_Initializer* pInitializer){ assert(pInitializer != NULL); initializers.push_back(pInitializer); return 0;}int NDBT_TestCaseImpl1::addFinalizer(NDBT_Finalizer* pFinalizer){ assert(pFinalizer != NULL); finalizers.push_back(pFinalizer); return 0;}void NDBT_TestCaseImpl1::addTable(const char* tableName, bool isVerify) { assert(tableName != NULL); const NdbDictionary::Table* pTable = NDBT_Tables::getTable(tableName); assert(pTable != NULL); testTables.push_back(pTable); isVerifyTables = isVerify;}bool NDBT_TestCaseImpl1::tableExists(NdbDictionary::Table* aTable) { for (unsigned i = 0; i < testTables.size(); i++) { if (strcasecmp(testTables[i]->getName(), aTable->getName()) == 0) { return true; } } return false;}bool NDBT_TestCaseImpl1::isVerify(const NdbDictionary::Table* aTable) { if (testTables.size() > 0) { int found = false; // OK, we either exclude or include this table in the actual test for (unsigned i = 0; i < testTables.size(); i++) { if (strcasecmp(testTables[i]->getName(), aTable->getName()) == 0) { // Found one! if (isVerifyTables) { // Found one to test found = true; } else { // Skip this one! found = false; } } } // for return found; } else { // No included or excluded test tables, i.e., all tables should be // tested return true; } return true;}void NDBT_TestCase::setProperty(const char* _name, Uint32 _val){ const bool b = props.put(_name, _val); assert(b == true);}void NDBT_TestCase::setProperty(const char* _name, const char* _val){ const bool b = props.put(_name, _val); assert(b == true);}void *runStep(void * s){ assert(s != NULL); NDBT_Step* pStep = (NDBT_Step*)s; NDBT_Context* ctx = pStep->getContext(); assert(ctx != NULL); // Execute function int res = pStep->execute(ctx); if(res != NDBT_OK){ ctx->stopTest(); } // Report NDBT_TestCaseImpl1* pCase = (NDBT_TestCaseImpl1*)ctx->getCase(); assert(pCase != NULL); pCase->reportStepResult(pStep, res); return NULL;}extern "C" void *runStep_C(void * s){ runStep(s); return NULL;}void NDBT_TestCaseImpl1::startStepInThread(int stepNo, NDBT_Context* ctx){ NDBT_Step* pStep = steps[stepNo]; pStep->setContext(ctx); char buf[16]; BaseString::snprintf(buf, sizeof(buf), "step_%d", stepNo); NdbThread* pThread = NdbThread_Create(runStep_C, (void**)pStep, 65535, buf, NDB_THREAD_PRIO_LOW); threads.push_back(pThread);}void NDBT_TestCaseImpl1::waitSteps(){ NdbMutex_Lock(waitThreadsMutexPtr); while(numStepsCompleted != steps.size()) NdbCondition_Wait(waitThreadsCondPtr, waitThreadsMutexPtr); unsigned completedSteps = 0; unsigned i; for(i=0; i<steps.size(); i++){ if (results[i] != NORESULT){ completedSteps++; if (results[i] == NDBT_OK) numStepsOk++; else numStepsFail++; } } assert(completedSteps == steps.size()); assert(completedSteps == numStepsCompleted); NdbMutex_Unlock(waitThreadsMutexPtr); void *status; for(i=0; i<steps.size();i++){ NdbThread_WaitFor(threads[i], &status); NdbThread_Destroy(&threads[i]); } threads.clear();}intNDBT_TestCaseImpl1::getNoOfRunningSteps() const { return steps.size() - getNoOfCompletedSteps();}int NDBT_TestCaseImpl1::getNoOfCompletedSteps() const { return numStepsCompleted;}void NDBT_TestCaseImpl1::reportStepResult(const NDBT_Step* pStep, int result){ NdbMutex_Lock(waitThreadsMutexPtr); assert(pStep != NULL); for (unsigned i = 0; i < steps.size(); i++){ if(steps[i] != NULL && steps[i] == pStep){ results[i] = result; numStepsCompleted++; } } if(numStepsCompleted == steps.size()){ NdbCondition_Signal(waitThreadsCondPtr); } NdbMutex_Unlock(waitThreadsMutexPtr);}int NDBT_TestCase::execute(NDBT_Context* ctx){ int res; ndbout << "- " << name << " started [" << ctx->suite->getDate() << "]" << endl; ctx->setCase(this); // Copy test case properties to ctx Properties::Iterator it(&props); for(const char * key = it.first(); key != 0; key = it.next()){ PropertiesType pt; const bool b = props.getTypeOf(key, &pt); assert(b == true); switch(pt){ case PropertiesType_Uint32:{ Uint32 val; props.get(key, &val); ctx->setProperty(key, val); break; } case PropertiesType_char:{ const char * val; props.get(key, &val); ctx->setProperty(key, val); break; } default: abort(); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -