MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
NDBT_Test.hpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef NDBT_TEST_HPP
19 #define NDBT_TEST_HPP
20 
21 #include <ndb_global.h>
22 #include <kernel/ndb_limits.h>
23 
24 #include "NDBT_ReturnCodes.h"
25 #include <Properties.hpp>
26 #include <NdbThread.h>
27 #include <NdbSleep.h>
28 #include <NdbCondition.h>
29 #include <NdbTimer.hpp>
30 #include <Vector.hpp>
31 #include <NdbApi.hpp>
32 #include <NdbDictionary.hpp>
33 #include <ndb_rand.h>
34 
35 class NDBT_Step;
36 class NDBT_TestCase;
37 class NDBT_TestSuite;
38 class NDBT_TestCaseImpl1;
39 
40 class NDBT_Context {
41 public:
42  Ndb_cluster_connection& m_cluster_connection;
43 
45  ~NDBT_Context();
46  const NdbDictionary::Table* getTab();
47  const NdbDictionary::Table** getTables();
48  int getNumTables() const;
49  const char * getTableName(int) const;
50  NDBT_TestSuite* getSuite();
51  NDBT_TestCase* getCase();
52 
53  // Get arguments
54  int getNumRecords() const;
55  int getNumLoops() const;
56 
57  // Common place to store state between
58  // steps, for example information from one step to the
59  // verifier about how many records have been inserted
60  Uint32 getProperty(const char*, Uint32 = 0 );
61  const char* getProperty(const char*, const char* );
62  void setProperty(const char*, Uint32);
63  void setProperty(const char*, const char*);
64 
65  // Signal that a property value that another
66  // thread might be waiting for has changed
67  void broadcast();
68  // Wait for the signal that a property has changed
69  void wait();
70  void wait_timeout(int msec);
71 
72  // Wait until the property has been set to a certain value
73  bool getPropertyWait(const char*, Uint32);
74  const char* getPropertyWait(const char*, const char* );
75 
76  void decProperty(const char *);
77  void incProperty(const char *);
78  Uint32 casProperty(const char *, Uint32 oldValue, Uint32 newValue);
79 
80  // Communicate with other tests
81  void stopTest();
82  bool isTestStopped();
83 
84  // Communicate with tests in other API nodes
85  // This is done using a "system" table in the database
86  Uint32 getDbProperty(const char*);
87  bool setDbProperty(const char*, Uint32);
88 
89  void setTab(const NdbDictionary::Table*);
90  void addTab(const NdbDictionary::Table*);
91 
95  int getNoOfRunningSteps() const ;
96  int getNoOfCompletedSteps() const ;
97 
101  void sync_down(const char * key);
102  void sync_up_and_wait(const char * key, Uint32 count = 0);
103 private:
104  friend class NDBT_Step;
105  friend class NDBT_TestSuite;
106  friend class NDBT_TestCase;
107  friend class NDBT_TestCaseImpl1;
108 
109  void setSuite(NDBT_TestSuite*);
110  void setCase(NDBT_TestCase*);
111  void setNumRecords(int);
112  void setNumLoops(int);
114  NDBT_TestSuite* suite;
116  Ndb* ndb;
117  int records;
118  int loops;
119  bool stopped;
120  Properties props;
121  NdbMutex* propertyMutexPtr;
122  NdbCondition* propertyCondPtr;
123 };
124 
125 typedef int (NDBT_TESTFUNC)(NDBT_Context*, NDBT_Step*);
126 
127 class NDBT_Step {
128 public:
129  NDBT_Step(NDBT_TestCase* ptest,
130  const char* pname,
131  NDBT_TESTFUNC* pfunc);
132  virtual ~NDBT_Step() {}
133  int execute(NDBT_Context*);
134  void setContext(NDBT_Context*);
135  NDBT_Context* getContext();
136  void print();
137  const char* getName() { return name; }
138  int getStepNo() { return step_no; }
139  void setStepNo(int n) { step_no = n; }
140 protected:
141  NDBT_Context* m_ctx;
142  const char* name;
143  NDBT_TESTFUNC* func;
145  int step_no;
146 
147 private:
148  int setUp(Ndb_cluster_connection&);
149  void tearDown();
150  Ndb* m_ndb;
151 
152 public:
153  Ndb* getNdb() const;
154 
155 };
156 
157 class NDBT_ParallelStep : public NDBT_Step {
158 public:
160  const char* pname,
161  NDBT_TESTFUNC* pfunc);
162  virtual ~NDBT_ParallelStep() {}
163 };
164 
165 class NDBT_Verifier : public NDBT_Step {
166 public:
168  const char* name,
169  NDBT_TESTFUNC* func);
170  virtual ~NDBT_Verifier() {}
171 };
172 
173 class NDBT_Initializer : public NDBT_Step {
174 public:
176  const char* name,
177  NDBT_TESTFUNC* func);
178  virtual ~NDBT_Initializer() {}
179 };
180 
181 class NDBT_Finalizer : public NDBT_Step {
182 public:
184  const char* name,
185  NDBT_TESTFUNC* func);
186  virtual ~NDBT_Finalizer() {}
187 };
188 
189 
190 enum NDBT_DriverType {
191  DummyDriver,
193 };
194 
195 
197 public:
198  NDBT_TestCase(NDBT_TestSuite* psuite,
199  const char* name,
200  const char* comment);
201  virtual ~NDBT_TestCase() {}
202 
203  static const char* getStepThreadStackSizePropName()
204  { return "StepThreadStackSize"; };
205 
206  // This is the default executor of a test case
207  // When a test case is executed it will need to be suplied with a number of
208  // different parameters and settings, these are passed to the test in the
209  // NDBT_Context object
210  virtual int execute(NDBT_Context*);
211  void setProperty(const char*, Uint32);
212  void setProperty(const char*, const char*);
213  virtual void print() = 0;
214  virtual void printHTML() = 0;
215 
216  const char* getName() const { return _name.c_str(); };
217  virtual bool tableExists(NdbDictionary::Table* aTable) = 0;
218  virtual bool isVerify(const NdbDictionary::Table* aTable) = 0;
219 
220  virtual void saveTestResult(const char*, int result) = 0;
221  virtual void printTestResult() = 0;
222  void initBeforeTest(){ timer.doReset();};
223 
224  void setDriverType(NDBT_DriverType type) { m_driverType= type; }
225  NDBT_DriverType getDriverType() const { return m_driverType; }
226 
230  virtual int getNoOfRunningSteps() const = 0;
231  virtual int getNoOfCompletedSteps() const = 0;
232 
233  bool m_all_tables;
234  bool m_has_run;
235 
236 protected:
237  virtual int runInit(NDBT_Context* ctx) = 0;
238  virtual int runSteps(NDBT_Context* ctx) = 0;
239  virtual int runVerifier(NDBT_Context* ctx) = 0;
240  virtual int runFinal(NDBT_Context* ctx) = 0;
241  virtual void addTable(const char* aTableName, bool isVerify=true) = 0;
242 
243  void startTimer(NDBT_Context*);
244  void stopTimer(NDBT_Context*);
245  void printTimer(NDBT_Context*);
246 
247  BaseString _name;
248  BaseString _comment;
249  NDBT_TestSuite* suite;
250  Properties props;
251  NdbTimer timer;
252  bool isVerifyTables;
253  NDBT_DriverType m_driverType;
254 };
255 
256 static const int FAILED_TO_CREATE = 1000;
257 static const int FAILED_TO_DISCOVER = 1001;
258 
259 
261 public:
262  NDBT_TestCaseResult(const char* name, int _result, NDB_TICKS _ticks):
263  m_result(_result){
264  m_name.assign(name);
265  m_ticks = _ticks;
266 
267  };
268  const char* getName(){return m_name.c_str(); };
269  int getResult(){return m_result; };
270  const char* getTimeStr(){
271  // Convert to Uint32 in order to be able to print it to screen
272  Uint32 lapTime = (Uint32)m_ticks;
273  Uint32 secTime = lapTime/1000;
274  BaseString::snprintf(buf, 255, "%d secs (%d ms)", secTime, lapTime);
275  return buf;
276  }
277 private:
278  char buf[255];
279  int m_result;
280  BaseString m_name;
281  NDB_TICKS m_ticks;
282 };
283 
285 public:
287  const char* name,
288  const char* comment);
289  virtual ~NDBT_TestCaseImpl1();
290  int addStep(NDBT_Step*);
291  int addVerifier(NDBT_Verifier*);
292  int addInitializer(NDBT_Initializer*, bool first= false);
293  int addFinalizer(NDBT_Finalizer*);
294  void addTable(const char*, bool);
295  bool tableExists(NdbDictionary::Table*);
296  bool isVerify(const NdbDictionary::Table*);
297  void reportStepResult(const NDBT_Step*, int result);
298  // int execute(NDBT_Context* ctx);
299  int runInit(NDBT_Context* ctx);
300  int runSteps(NDBT_Context* ctx);
301  int runVerifier(NDBT_Context* ctx);
302  int runFinal(NDBT_Context* ctx);
303  void print();
304  void printHTML();
305 
306  virtual int getNoOfRunningSteps() const;
307  virtual int getNoOfCompletedSteps() const;
308 private:
309  static const int NORESULT = 999;
310 
311  void saveTestResult(const char*, int result);
312  void printTestResult();
313 
314  void startStepInThread(int stepNo, NDBT_Context* ctx);
315  void waitSteps();
316  Vector<NDBT_Step*> steps;
317  Vector<NdbThread*> threads;
318  Vector<int> results;
319  Vector<NDBT_Verifier*> verifiers;
320  Vector<NDBT_Initializer*> initializers;
321  Vector<NDBT_Finalizer*> finalizers;
323  Vector<NDBT_TestCaseResult*> testResults;
324  unsigned numStepsFail;
325  unsigned numStepsOk;
326  unsigned numStepsCompleted;
327  NdbMutex* waitThreadsMutexPtr;
328  NdbCondition* waitThreadsCondPtr;
329 };
330 
331 
332 // A NDBT_TestSuite is a collection of TestCases
333 // the test suite will know how to execute the test cases
335 public:
336  NDBT_TestSuite(const char* name);
337  ~NDBT_TestSuite();
338 
339  // Default executor of a test suite
340  // supply argc and argv as parameters
341  int execute(int, const char**);
342 
343  // NDBT's test tables are fixed and it always create
344  // and drop fixed table when execute, add this method
345  // in order to run CTX only and adapt to some new
346  // customized testsuite
347  int executeOneCtx(Ndb_cluster_connection&,
348  const NdbDictionary::Table* ptab, const char* testname = NULL);
349 
350  // These function can be used from main in the test program
351  // to control the behaviour of the testsuite
352  void setCreateTable(bool); // Create table before test func is called
353  void setCreateAllTables(bool); // Create all tables before testsuite is executed
354  void setRunAllTables(bool); // Run once with all tables
355  void setConnectCluster(bool); // Connect to cluster before testsuite is executed
356 
357  // Prints the testsuite, testcases and teststeps
358  void printExecutionTree();
359  void printExecutionTreeHTML();
360 
361  // Prints list of testcases
362  void printCases();
363 
364  // Print summary of executed tests
365  void printTestCaseSummary(const char* tcname = NULL);
366 
370  const char* getDate();
371 
372  // Returns true if timing info should be printed
373  bool timerIsOn();
374 
375  int addTest(NDBT_TestCase* pTest);
376 
377  // Table create tweaks
378  int createHook(Ndb*, NdbDictionary::Table&, int when);
379  Vector<BaseString> m_tables_in_test;
380 
381  void setTemporaryTables(bool val);
382  bool getTemporaryTables() const;
383 
384  void setLogging(bool val);
385  bool getLogging() const;
386 
387  bool getForceShort() const;
388 
389  int createTables(Ndb_cluster_connection&) const;
390  int dropTables(Ndb_cluster_connection&) const;
391 
392  void setDriverType(NDBT_DriverType type) { m_driverType= type; }
393  NDBT_DriverType getDriverType() const { return m_driverType; }
394 
395 private:
396  int executeOne(Ndb_cluster_connection&,
397  const char* _tabname, const char* testname = NULL);
398  int executeAll(Ndb_cluster_connection&,
399  const char* testname = NULL);
400  void execute(Ndb_cluster_connection&,
401  const NdbDictionary::Table*, const char* testname = NULL);
402 
403  int report(const char* _tcname = NULL);
404  int reportAllTables(const char* );
405  const char* name;
406  char* remote_mgm;
407  int numTestsOk;
408  int numTestsFail;
409  int numTestsExecuted;
411  NDBT_Context* ctx;
412  int records;
413  int loops;
414  int timer;
415  NdbTimer testSuiteTimer;
416  bool m_createTable;
417  bool m_createAll;
418  bool m_connect_cluster;
419  bool diskbased;
420  bool runonce;
421  const char* tsname;
422  bool temporaryTables;
423  bool m_logging;
424  NDBT_DriverType m_driverType;
425  bool m_noddl;
426  bool m_forceShort;
427 };
428 
429 
430 
431 #define NDBT_TESTSUITE(suitname) \
432 class C##suitname : public NDBT_TestSuite { \
433 public: \
434 C##suitname():NDBT_TestSuite(#suitname){ \
435  NDBT_TestCaseImpl1* pt; pt = NULL; \
436  NDBT_Step* pts; pts = NULL; \
437  NDBT_Verifier* ptv; ptv = NULL; \
438  NDBT_Initializer* pti; pti = NULL; \
439  NDBT_Finalizer* ptf; ptf = NULL;
440 
441 // The default driver type to use for all tests in suite
442 #define DRIVER(type) \
443  setDriverType(type)
444 
445 #define TESTCASE(testname, comment) \
446  pt = new NDBT_TestCaseImpl1(this, testname, comment); \
447  addTest(pt);
448 
449 // The driver type to use for a particular testcase
450 #define TESTCASE_DRIVER(type) \
451  pt->setDriverType(type);
452 
453 #define TC_PROPERTY(propname, propval) \
454  pt->setProperty(propname, propval);
455 
456 #define STEP(stepfunc) \
457  pts = new NDBT_ParallelStep(pt, #stepfunc, stepfunc); \
458  pt->addStep(pts);
459 
460 // Add a number of equal steps to the testcase
461 #define STEPS(stepfunc, num) \
462  { int i; for (i = 0; i < num; i++){ \
463  pts = new NDBT_ParallelStep(pt, #stepfunc, stepfunc); \
464  pt->addStep(pts);\
465  } }
466 
467 #define VERIFIER(stepfunc) \
468  ptv = new NDBT_Verifier(pt, #stepfunc, stepfunc); \
469  pt->addVerifier(ptv);
470 
471 #define INITIALIZER(stepfunc) \
472  pti = new NDBT_Initializer(pt, #stepfunc, stepfunc); \
473  pt->addInitializer(pti);
474 
475 #define FINALIZER(stepfunc) \
476  ptf = new NDBT_Finalizer(pt, #stepfunc, stepfunc); \
477  pt->addFinalizer(ptf);
478 
479 // Test case can be run only on this table(s), can be multiple tables
480 // Ex TABLE("T1")
481 // TABLE("T3")
482 // Means test will only be run on T1 and T3
483 #define TABLE(tableName) \
484  pt->addTable(tableName, true);
485 
486 // Test case can be run on all tables except
487 // Ex NOT_TABLE("T10")
488 // Means test will be run on all tables execept T10
489 #define NOT_TABLE(tableName) \
490  pt->addTable(tableName, false);
491 
492 // Text case will only be run once, not once per table as normally
493 #define ALL_TABLES() \
494  pt->m_all_tables= true;
495 
496 #define NDBT_TESTSUITE_END(suitname) \
497  } } ;
498 
499 #define NDBT_TESTSUITE_INSTANCE(suitname) \
500  C##suitname suitname
501 
502 // Helper functions for retrieving variables from NDBT_Step
503 #define GETNDB(ps) ((NDBT_Step*)ps)->getNdb()
504 
505 #define POSTUPGRADE(testname) \
506  TESTCASE(testname "--post-upgrade", \
507  "checks being run after upgrade has completed")
508 
509 #endif