static int runCheckTableExists(NDBT_Context* ctx, NDBT_Step* step) { Ndb ndb(&ctx->m_cluster_connection, "TEST_DB"); ndb.init(1); NdbDictionary::Dictionary* pDict = ndb.getDictionary(); const NdbDictionary::Table* pTab = ctx->getTab(); const char *tab_name= pTab->getName(); const NdbDictionary::Table* pDictTab = pDict->getTable(tab_name); if (pDictTab == NULL) { g_err << "runCheckTableExists : Failed to find table " << tab_name << endl; g_err << "Required schema : " << *((NDBT_Table*)pTab) << endl; return NDBT_FAILED; } /* Todo : better check that table in DB is same as * table we expect */ // Update ctx with a pointer to dict table ctx->setTab(pDictTab); ctx->setProperty("$table", tab_name); return NDBT_OK; }
int NDBT_TestSuite::createTables(Ndb_cluster_connection& con) const { Ndb ndb(&con, "TEST_DB"); ndb.init(1); NdbDictionary::Dictionary* pDict = ndb.getDictionary(); for(unsigned i = 0; i<m_tables_in_test.size(); i++) { const char *tab_name= m_tables_in_test[i].c_str(); if (pDict->dropTable(tab_name) != 0 && pDict->getNdbError().code != 723) // No such table { g_err << "runCreateTables: Failed to drop table " << tab_name << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } if(NDBT_Tables::createTable(&ndb, tab_name, !getLogging()) != 0) { g_err << "runCreateTables: Failed to create table " << tab_name << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } if (i == 0){ // Update ctx with a pointer to the first created table const NdbDictionary::Table* pTab2 = pDict->getTable(tab_name); ctx->setTab(pTab2); } g_info << "created " << tab_name << endl; } return NDBT_OK; }
static int runCreateTable(NDBT_Context* ctx, NDBT_Step* step) { Ndb ndb(&ctx->m_cluster_connection, "TEST_DB"); ndb.init(1); NdbDictionary::Dictionary* pDict = ndb.getDictionary(); const NdbDictionary::Table* pTab = ctx->getTab(); const char *tab_name= pTab->getName(); if (pDict->dropTable(tab_name) != 0 && pDict->getNdbError().code != 723) // No such table { g_err << "runCreateTable: Failed to drop table " << tab_name << endl << pDict->getNdbError() << endl; return NDBT_FAILED; } if(NDBT_Tables::createTable(&ndb, tab_name, !ctx->getSuite()->getLogging()) != 0) { g_err << "runCreateTable: Failed to create table " << tab_name << pDict->getNdbError() << endl; return NDBT_FAILED; } // Update ctx with a pointer to the created table const NdbDictionary::Table* pTab2 = pDict->getTable(tab_name); ctx->setTab(pTab2); ctx->setProperty("$table", tab_name); return NDBT_OK; }
int NDBT_TestSuite::executeOne(Ndb_cluster_connection& con, const char* _tabname, const char* _testname){ if(tests.size() == 0) return NDBT_FAILED; Ndb 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; } ndbout << name << " started [" << getDate() << "]" << endl; const NdbDictionary::Table* ptab = NDBT_Tables::getTable(_tabname); if (ptab == NULL) return NDBT_FAILED; ndbout << "|- " << ptab->getName() << endl; execute(con, &ndb, ptab, _testname); if (numTestsFail > 0){ return NDBT_FAILED; }else{ return NDBT_OK; } }
int NDBT_TestSuite::executeOneCtx(Ndb_cluster_connection& con, const NdbDictionary::Table *ptab, const char* _testname) { testSuiteTimer.doStart(); do{ if(tests.size() == 0) break; if (opt_stop_on_error != 0 && numTestsFail > 0) break; Ndb ndb(&con, "TEST_DB"); ndb.init(1024); Ndb_internal::setForceShortRequests(&ndb, m_forceShort); int result = ndb.waitUntilReady(300); // 5 minutes if (result != 0){ g_err << name <<": Ndb was not ready" << endl; break; } char buf[64]; // For timestamp string ndbout << name << " started [" << getDate(buf, sizeof(buf)) << "]" << endl; ndbout << "|- " << ptab->getName() << endl; if (_testname == NULL) { for (unsigned t = 0; t < tests.size(); t++) { if (opt_stop_on_error != 0 && numTestsFail > 0) break; execute(con, tests[t], ptab); } if (numTestsFail > 0) break; } else { NDBT_TestCase * pt = findTest(_testname); if (pt != NULL) { execute(con, pt, ptab); } } } while(0); testSuiteTimer.doStop(); int res = report(_testname); return NDBT_ProgramExit(res); }
int NDBT_TestSuite::executeOneCtx(Ndb_cluster_connection& con, const NdbDictionary::Table *ptab, const char* _testname){ testSuiteTimer.doStart(); do{ if(tests.size() == 0) break; Ndb 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; break; } ndbout << name << " started [" << getDate() << "]" << endl; ndbout << "|- " << ptab->getName() << endl; for (unsigned t = 0; t < tests.size(); t++){ if (_testname != NULL && strcasecmp(tests[t]->getName(), _testname) != 0) continue; tests[t]->initBeforeTest(); ctx = new NDBT_Context(con); ctx->setTab(ptab); ctx->setNumRecords(records); ctx->setNumLoops(loops); if(remote_mgm != NULL) ctx->setRemoteMgm(remote_mgm); ctx->setSuite(this); result = tests[t]->execute(ctx); if (result != NDBT_OK) numTestsFail++; else numTestsOk++; numTestsExecuted++; delete ctx; } if (numTestsFail > 0) break; }while(0); testSuiteTimer.doStop(); int res = report(_testname); return NDBT_ProgramExit(res); }
static int runDropTable(NDBT_Context* ctx, NDBT_Step* step) { const char * tab_name = ctx->getProperty("$table", (const char*)0); if (tab_name) { Ndb ndb(&ctx->m_cluster_connection, "TEST_DB"); ndb.init(1); NdbDictionary::Dictionary* pDict = ndb.getDictionary(); pDict->dropTable(tab_name); } return NDBT_OK; }
int NDBT_TestSuite::dropTables(Ndb_cluster_connection& con) const { Ndb ndb(&con, "TEST_DB"); ndb.init(1); NdbDictionary::Dictionary* pDict = ndb.getDictionary(); for(unsigned i = 0; i<m_tables_in_test.size(); i++) { const char *tab_name= m_tables_in_test[i].c_str(); pDict->dropTable(tab_name); } return NDBT_OK; }
int main(int argc, char** argv) { NDB_INIT(argv[0]); const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&argv); int ho_error; #ifndef DBUG_OFF opt_debug= "d:t:F:L"; #endif if ((ho_error=handle_options(&argc, &argv, my_long_options, ndb_std_get_one_option))) return NDBT_ProgramExit(NDBT_WRONGARGS); DBUG_ENTER("main"); Ndb_cluster_connection con(opt_connect_str); if(con.connect(12, 5, 1)) { DBUG_RETURN(NDBT_ProgramExit(NDBT_FAILED)); } Ndb ndb(&con,_dbname); ndb.init(); while (ndb.waitUntilReady() != 0); NdbDictionary::Dictionary * dict = ndb.getDictionary(); int no_error= 1; int i; // create all tables Vector<const NdbDictionary::Table*> pTabs; if (argc == 0) { NDBT_Tables::dropAllTables(&ndb); NDBT_Tables::createAllTables(&ndb); for (i= 0; no_error && i < NDBT_Tables::getNumTables(); i++) { const NdbDictionary::Table *pTab= dict->getTable(NDBT_Tables::getTable(i)->getName()); if (pTab == 0) { ndbout << "Failed to create table" << endl; ndbout << dict->getNdbError() << endl; no_error= 0; break; } pTabs.push_back(pTab); } } else { for (i= 0; no_error && argc; argc--, i++) { dict->dropTable(argv[i]); NDBT_Tables::createTable(&ndb, argv[i]); const NdbDictionary::Table *pTab= dict->getTable(argv[i]); if (pTab == 0) { ndbout << "Failed to create table" << endl; ndbout << dict->getNdbError() << endl; no_error= 0; break; } pTabs.push_back(pTab); } } pTabs.push_back(NULL); // create an event for each table for (i= 0; no_error && pTabs[i]; i++) { HugoTransactions ht(*pTabs[i]); if (ht.createEvent(&ndb)){ no_error= 0; break; } } // create an event operation for each event Vector<NdbEventOperation *> pOps; for (i= 0; no_error && pTabs[i]; i++) { char buf[1024]; sprintf(buf, "%s_EVENT", pTabs[i]->getName()); NdbEventOperation *pOp= ndb.createEventOperation(buf, 1000); if ( pOp == NULL ) { no_error= 0; break; } pOps.push_back(pOp); } // get storage for each event operation for (i= 0; no_error && pTabs[i]; i++) { int n_columns= pTabs[i]->getNoOfColumns(); for (int j = 0; j < n_columns; j++) { pOps[i]->getValue(pTabs[i]->getColumn(j)->getName()); pOps[i]->getPreValue(pTabs[i]->getColumn(j)->getName()); } } // start receiving events for (i= 0; no_error && pTabs[i]; i++) { if ( pOps[i]->execute() ) { no_error= 0; break; } } // create a "shadow" table for each table Vector<const NdbDictionary::Table*> pShadowTabs; for (i= 0; no_error && pTabs[i]; i++) { char buf[1024]; sprintf(buf, "%s_SHADOW", pTabs[i]->getName()); dict->dropTable(buf); if (dict->getTable(buf)) { no_error= 0; break; } NdbDictionary::Table table_shadow(*pTabs[i]); table_shadow.setName(buf); dict->createTable(table_shadow); pShadowTabs.push_back(dict->getTable(buf)); if (!pShadowTabs[i]) { no_error= 0; break; } } // create a hugo operation per table Vector<HugoOperations *> hugo_ops; for (i= 0; no_error && pTabs[i]; i++) { hugo_ops.push_back(new HugoOperations(*pTabs[i])); } int n_records= 3; // insert n_records records per table do { if (start_transaction(&ndb, hugo_ops)) { no_error= 0; break; } for (i= 0; no_error && pTabs[i]; i++) { hugo_ops[i]->pkInsertRecord(&ndb, 0, n_records); } if (execute_commit(&ndb, hugo_ops)) { no_error= 0; break; } if(close_transaction(&ndb, hugo_ops)) { no_error= 0; break; } } while(0); // copy events and verify do { if (copy_events(&ndb) < 0) { no_error= 0; break; } if (verify_copy(&ndb, pTabs, pShadowTabs)) { no_error= 0; break; } } while (0); // update n_records-1 records in first table do { if (start_transaction(&ndb, hugo_ops)) { no_error= 0; break; } hugo_ops[0]->pkUpdateRecord(&ndb, n_records-1); if (execute_commit(&ndb, hugo_ops)) { no_error= 0; break; } if(close_transaction(&ndb, hugo_ops)) { no_error= 0; break; } } while(0); // copy events and verify do { if (copy_events(&ndb) < 0) { no_error= 0; break; } if (verify_copy(&ndb, pTabs, pShadowTabs)) { no_error= 0; break; } } while (0); { NdbRestarts restarts; for (int j= 0; j < 10; j++) { // restart a node if (no_error) { int timeout = 240; if (restarts.executeRestart("RestartRandomNodeAbort", timeout)) { no_error= 0; break; } } // update all n_records records on all tables if (start_transaction(&ndb, hugo_ops)) { no_error= 0; break; } for (int r= 0; r < n_records; r++) { for (i= 0; pTabs[i]; i++) { hugo_ops[i]->pkUpdateRecord(&ndb, r); } } if (execute_commit(&ndb, hugo_ops)) { no_error= 0; break; } if(close_transaction(&ndb, hugo_ops)) { no_error= 0; break; } // copy events and verify if (copy_events(&ndb) < 0) { no_error= 0; break; } if (verify_copy(&ndb, pTabs, pShadowTabs)) { no_error= 0; break; } } } // drop the event operations for (i= 0; i < (int)pOps.size(); i++) { if (ndb.dropEventOperation(pOps[i])) { no_error= 0; } } if (no_error) DBUG_RETURN(NDBT_ProgramExit(NDBT_OK)); DBUG_RETURN(NDBT_ProgramExit(NDBT_FAILED)); }
int NDBT_TestSuite::executeAll(Ndb_cluster_connection& con, const char* _testname){ if(tests.size() == 0) return NDBT_FAILED; Ndb ndb(&con, "TEST_DB"); ndb.init(1024); int result = ndb.waitUntilReady(500); // 5 minutes if (result != 0){ g_err << name <<": Ndb was not ready" << endl; return NDBT_FAILED; } ndbout << name << " started [" << getDate() << "]" << endl; if(!runonce) { testSuiteTimer.doStart(); for (int t=0; t < NDBT_Tables::getNumTables(); t++){ const NdbDictionary::Table* ptab = NDBT_Tables::getTable(t); ndbout << "|- " << ptab->getName() << endl; execute(con, &ndb, ptab, _testname); } testSuiteTimer.doStop(); } else { NdbDictionary::Dictionary* pDict= ndb.getDictionary(); for (unsigned i = 0; i < tests.size(); i++){ if (_testname != NULL && strcasecmp(tests[i]->getName(), _testname) != 0) continue; tests[i]->initBeforeTest(); ctx = new NDBT_Context(con); Uint32 t; for (t=0; t < (Uint32)NDBT_Tables::getNumTables(); t++) { 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(), false, 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); } ctx->setNumRecords(records); ctx->setNumLoops(loops); if(remote_mgm != NULL) ctx->setRemoteMgm(remote_mgm); ctx->setSuite(this); const NdbDictionary::Table** tables= ctx->getTables(); result = tests[i]->execute(ctx); tests[i]->saveTestResult(tables[0], result); if (result != NDBT_OK) numTestsFail++; else numTestsOk++; numTestsExecuted++; if(result == NDBT_OK) { for(t = 0; tables[t] != 0; t++) { pDict->dropTable(tables[t]->getName()); } } delete ctx; } } return reportAllTables(_testname); }
int NDBT_TestSuite::execute(int argc, const char** argv){ int res = NDBT_FAILED; /* Arguments: Run only a subset of tests -n testname Which test to run Recommendations to test functions: --records Number of records to use(default: 10000) --loops Number of loops to execute in the test(default: 100) Other parameters should: * be calculated from the above two parameters * be divided into different test cases, ex. one testcase runs with FragmentType = Single and another perfoms the same test with FragmentType = Large * let the test case iterate over all/subset of appropriate parameters ex. iterate over FragmentType = Single to FragmentType = AllLarge Remeber that the intention is that it should be _easy_ to run a complete test suite without any greater knowledge of what should be tested ie. keep arguments at a minimum */ char **_argv= (char **)argv; if (!my_progname) my_progname= _argv[0]; const char *load_default_groups[]= { "mysql_cluster",0 }; load_defaults("my",load_default_groups,&argc,&_argv); int ho_error; #ifndef DBUG_OFF opt_debug= "d:t:i:F:L"; #endif if ((ho_error=handle_options(&argc, &_argv, my_long_options, ndb_std_get_one_option))) { usage(); return NDBT_ProgramExit(NDBT_WRONGARGS); } if (opt_print == true){ printExecutionTree(); return 0; } if (opt_print_html == true){ printExecutionTreeHTML(); return 0; } if (opt_print_cases == true){ printCases(); return 0; } if (opt_verbose) setOutputLevel(2); // Show g_info else setOutputLevel(0); // Show only g_err ? remote_mgm = opt_remote_mgm; records = opt_records; loops = opt_loops; timer = opt_timer; Ndb_cluster_connection con; if(con.connect(12, 5, 1)) { return NDBT_ProgramExit(NDBT_FAILED); } if (opt_seed == 0) { opt_seed = NdbTick_CurrentMillisecond(); } ndbout_c("random seed: %u", opt_seed); srand(opt_seed); srandom(opt_seed); global_flag_skip_invalidate_cache = 1; { Ndb ndb(&con, "TEST_DB"); ndb.init(1024); if (ndb.waitUntilReady(500)){ g_err << "Ndb was not ready" << endl; return NDBT_ProgramExit(NDBT_FAILED); } NdbDictionary::Dictionary* pDict = ndb.getDictionary(); int num_tables= argc; if (argc == 0) num_tables = NDBT_Tables::getNumTables(); for(int i = 0; i<num_tables; i++) { if (argc == 0) m_tables_in_test.push_back(NDBT_Tables::getTable(i)->getName()); else m_tables_in_test.push_back(_argv[i]); if (createAllTables == true) { 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) != 0) { g_err << "ERROR1: Failed to create table " << tab_name << pDict->getNdbError() << endl; return NDBT_ProgramExit(NDBT_FAILED); } } } } if(argc == 0){ // No table specified res = executeAll(con, opt_testname); } else { testSuiteTimer.doStart(); for(int i = 0; i<argc; i++){ executeOne(con, _argv[i], opt_testname); } testSuiteTimer.doStop(); res = report(opt_testname); } if (res == NDBT_OK && createAllTables == true) { Ndb ndb(&con, "TEST_DB"); ndb.init(1024); if (ndb.waitUntilReady(500)){ g_err << "Ndb was not ready" << endl; return NDBT_ProgramExit(NDBT_FAILED); } NdbDictionary::Dictionary* pDict = ndb.getDictionary(); for(unsigned i = 0; i<m_tables_in_test.size(); i++) { pDict->dropTable(m_tables_in_test[i].c_str()); } } return NDBT_ProgramExit(res); }