MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
testNdbinfo.cpp
1 /*
2  Copyright (c) 2009, 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 #include <NDBT.hpp>
19 #include <NDBT_Test.hpp>
20 #include "../../src/ndbapi/NdbInfo.hpp"
21 
22 #include <NdbRestarter.hpp>
23 
24 
25 int runTestNdbInfo(NDBT_Context* ctx, NDBT_Step* step)
26 {
27  NdbInfo ndbinfo(&ctx->m_cluster_connection, "ndbinfo/");
28  if (!ndbinfo.init())
29  {
30  g_err << "ndbinfo.init failed" << endl;
31  return NDBT_FAILED;
32  }
33 
34  const NdbInfo::Table* table;
35  if (ndbinfo.openTable("ndbinfo/tables", &table) != 0)
36  {
37  g_err << "Failed to openTable(tables)" << endl;
38  return NDBT_FAILED;
39  }
40 
41  for (int l = 0; l < ctx->getNumLoops(); l++)
42  {
43 
44  NdbInfoScanOperation* scanOp = NULL;
45  if (ndbinfo.createScanOperation(table, &scanOp))
46  {
47  g_err << "No NdbInfoScanOperation" << endl;
48  return NDBT_FAILED;
49  }
50 
51  if (scanOp->readTuples() != 0)
52  {
53  g_err << "scanOp->readTuples failed" << endl;
54  return NDBT_FAILED;
55  }
56 
57  const NdbInfoRecAttr* tableName = scanOp->getValue("table_name");
58  const NdbInfoRecAttr* comment = scanOp->getValue("comment");
59 
60  if(scanOp->execute() != 0)
61  {
62  g_err << "scanOp->execute failed" << endl;
63  return NDBT_FAILED;
64  }
65 
66  while(scanOp->nextResult() == 1)
67  {
68  g_info << "NAME: " << tableName->c_str() << endl;
69  g_info << "COMMENT: " << comment->c_str() << endl;
70  }
71  ndbinfo.releaseScanOperation(scanOp);
72  }
73 
74  ndbinfo.closeTable(table);
75  return NDBT_OK;
76 }
77 
78 static bool
79 scan_table(NdbInfo& ndbinfo, const NdbInfo::Table* table, int &rows)
80 {
81  NdbInfoScanOperation* scanOp = NULL;
82  if (ndbinfo.createScanOperation(table, &scanOp))
83  {
84  g_err << "No NdbInfoScanOperation" << endl;
85  return false;
86  }
87 
88  if (scanOp->readTuples() != 0)
89  {
90  g_err << "scanOp->readTuples failed" << endl;
91  ndbinfo.releaseScanOperation(scanOp);
92  return false;
93  }
94 
95  int columnId = 0;
96  while (scanOp->getValue(columnId))
97  columnId++;
98  // At least one column
99  assert(columnId >= 1);
100  int ret;
101  if((ret = scanOp->execute()) != 0)
102  {
103  g_err << "scanOp->execute failed, ret: " << ret << endl;
104  ndbinfo.releaseScanOperation(scanOp);
105  return false;
106  }
107 
108  while((ret = scanOp->nextResult()) == 1)
109  rows++;
110 
111  ndbinfo.releaseScanOperation(scanOp);
112 
113  if (ret != 0)
114  {
115  g_err << "scanOp->nextResult failed, ret: " << ret << endl;
116  return false;
117  }
118 
119  return true;
120 }
121 
122 
123 int runScanAll(NDBT_Context* ctx, NDBT_Step* step)
124 {
125  NdbInfo ndbinfo(&ctx->m_cluster_connection, "ndbinfo/");
126  if (!ndbinfo.init())
127  {
128  g_err << "ndbinfo.init failed" << endl;
129  return NDBT_FAILED;
130  }
131 
132  Uint32 tableId = 0;
133  while(true) {
134  const NdbInfo::Table* table;
135 
136  int err = ndbinfo.openTable(tableId, &table);
137  if (err == NdbInfo::ERR_NoSuchTable)
138  {
139  // No more tables -> return
140  return NDBT_OK;
141  }
142  else if (err != 0)
143  {
144  // Unexpected return code
145  g_err << "Failed to openTable(" << tableId << "), err: " << err << endl;
146  return NDBT_FAILED;
147  }
148  ndbout << "table("<<tableId<<"): " << table->getName() << endl;
149 
150  int last_rows;
151  for (int l = 0; l < ctx->getNumLoops(); l++)
152  {
153  if (ctx->isTestStopped())
154  return NDBT_OK;
155 
156  int rows = 0;
157  if (!scan_table(ndbinfo, table, rows))
158  {
159  ctx->stopTest();
160  return NDBT_FAILED;
161  }
162  // Check that the number of rows is same as last round on same table
163  if (l > 0 &&
164  last_rows != rows)
165  {
166  g_err << "Got different number of rows this round, expected: "
167  << last_rows << ", got: " << rows << endl;
168  ndbinfo.closeTable(table);
169  ctx->stopTest();
170  return NDBT_FAILED;
171  }
172  last_rows = rows;
173  }
174  ndbinfo.closeTable(table);
175  tableId++;
176  }
177 
178  // Should never come here
179  assert(false);
180  return NDBT_FAILED;
181 }
182 
183 
184 int runScanAllUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
185  int i = 0;
186  while (ctx->isTestStopped() == false) {
187  g_info << i << ": ";
188  if (runScanAll(ctx, step) != NDBT_OK){
189  return NDBT_FAILED;
190  }
191  i++;
192  }
193  return NDBT_OK;
194 }
195 
196 
197 int runScanStop(NDBT_Context* ctx, NDBT_Step* step)
198 {
199  NdbInfo ndbinfo(&ctx->m_cluster_connection, "ndbinfo/");
200  if (!ndbinfo.init())
201  {
202  g_err << "ndbinfo.init failed" << endl;
203  return NDBT_FAILED;
204  }
205 
206  Uint32 tableId = 0;
207  while(true) {
208  const NdbInfo::Table* table;
209 
210  int err = ndbinfo.openTable(tableId, &table);
211  if (err == NdbInfo::ERR_NoSuchTable)
212  {
213  // No more tables -> return
214  return NDBT_OK;
215  }
216  else if (err != 0)
217  {
218  // Unexpected return code
219  g_err << "Failed to openTable(" << tableId << "), err: " << err << endl;
220  return NDBT_FAILED;
221  }
222  ndbout << "table: " << table->getName() << endl;
223 
224  for (int l = 0; l < ctx->getNumLoops()*10; l++)
225  {
226  NdbInfoScanOperation* scanOp = NULL;
227  if (ndbinfo.createScanOperation(table, &scanOp))
228  {
229  g_err << "No NdbInfoScanOperation" << endl;
230  return NDBT_FAILED;
231  }
232 
233  if (scanOp->readTuples() != 0)
234  {
235  g_err << "scanOp->readTuples failed" << endl;
236  return NDBT_FAILED;
237  }
238 
239  int columnId = 0;
240  while (scanOp->getValue(columnId))
241  columnId++;
242  // At least one column
243  assert(columnId >= 1);
244 
245  if(scanOp->execute() != 0)
246  {
247  g_err << "scanOp->execute failed" << endl;
248  return NDBT_FAILED;
249  }
250 
251  int stopRow = rand() % 100;
252  int row = 0;
253  while(scanOp->nextResult() == 1)
254  {
255  row++;
256  if (row == stopRow)
257  {
258  ndbout_c("Aborting scan at row %d", stopRow);
259  break;
260  }
261  }
262  ndbinfo.releaseScanOperation(scanOp);
263  }
264  ndbinfo.closeTable(table);
265  tableId++;
266  }
267 
268  // Should never come here
269  assert(false);
270  return NDBT_FAILED;
271 }
272 
273 
274 int runRatelimit(NDBT_Context* ctx, NDBT_Step* step)
275 {
276  NdbInfo ndbinfo(&ctx->m_cluster_connection, "ndbinfo/");
277  if (!ndbinfo.init())
278  {
279  g_err << "ndbinfo.init failed" << endl;
280  return NDBT_FAILED;
281  }
282 
283  Uint32 tableId = 0;
284  while(true) {
285 
286  const NdbInfo::Table* table;
287 
288  int err = ndbinfo.openTable(tableId, &table);
289  if (err == NdbInfo::ERR_NoSuchTable)
290  {
291  // No more tables -> return
292  return NDBT_OK;
293  }
294  else if (err != 0)
295  {
296  // Unexpected return code
297  g_err << "Failed to openTable(" << tableId << "), err: " << err << endl;
298  return NDBT_FAILED;
299  }
300  ndbout << "table: " << table->getName() << endl;
301 
302 
303  struct { Uint32 rows; Uint32 bytes; } limits[] = {
304  { 0, 0 },
305  { 1, 0 }, { 2, 0 }, { 10, 0 }, { 37, 0 }, { 1000, 0 },
306  { 0, 1 }, { 0, 2 }, { 0, 10 }, { 0, 37 }, { 0, 1000 },
307  { 1, 1 }, { 2, 2 }, { 10, 10 }, { 37, 37 }, { 1000, 1000 }
308  };
309 
310  int lastRows = 0;
311  for (int l = 0; l < (int)(sizeof(limits)/sizeof(limits[0])); l++)
312  {
313 
314  Uint32 maxRows = limits[l].rows;
315  Uint32 maxBytes = limits[l].bytes;
316 
317  NdbInfoScanOperation* scanOp = NULL;
318  if (ndbinfo.createScanOperation(table, &scanOp, maxRows, maxBytes))
319  {
320  g_err << "No NdbInfoScanOperation" << endl;
321  return NDBT_FAILED;
322  }
323 
324  if (scanOp->readTuples() != 0)
325  {
326  g_err << "scanOp->readTuples failed" << endl;
327  return NDBT_FAILED;
328  }
329 
330  int columnId = 0;
331  while (scanOp->getValue(columnId))
332  columnId++;
333  // At least one column
334  assert(columnId >= 1);
335 
336  if(scanOp->execute() != 0)
337  {
338  g_err << "scanOp->execute failed" << endl;
339  return NDBT_FAILED;
340  }
341 
342  int row = 0;
343  while(scanOp->nextResult() == 1)
344  row++;
345  ndbinfo.releaseScanOperation(scanOp);
346 
347  ndbout_c("[%u,%u] rows: %d", maxRows, maxBytes, row);
348  if (lastRows != 0)
349  {
350  // Check that the number of rows is same as last round on same table
351  if (lastRows != row)
352  {
353  g_err << "Got different number of rows this round, expected: "
354  << lastRows << ", got: " << row << endl;
355  ndbinfo.closeTable(table);
356  return NDBT_FAILED;
357  }
358  }
359  lastRows = row;
360  }
361  ndbinfo.closeTable(table);
362  tableId++;
363  }
364 
365  // Should never come here
366  assert(false);
367  return NDBT_FAILED;
368 }
369 
370 int runTestTable(NDBT_Context* ctx, NDBT_Step* step)
371 {
372  NdbInfo ndbinfo(&ctx->m_cluster_connection, "ndbinfo/");
373  if (!ndbinfo.init())
374  {
375  g_err << "ndbinfo.init failed" << endl;
376  return NDBT_FAILED;
377  }
378 
379  const NdbInfo::Table* table;
380  if (ndbinfo.openTable("ndbinfo/test", &table) != 0)
381  {
382  g_err << "Failed to openTable(test)" << endl;
383  return NDBT_FAILED;
384  }
385 
386  for (int l = 0; l < ctx->getNumLoops(); l++)
387  {
388 
389  NdbInfoScanOperation* scanOp = NULL;
390  if (ndbinfo.createScanOperation(table, &scanOp))
391  {
392  ndbinfo.closeTable(table);
393  g_err << "No NdbInfoScanOperation" << endl;
394  return NDBT_FAILED;
395  }
396 
397  if (scanOp->readTuples() != 0)
398  {
399  ndbinfo.releaseScanOperation(scanOp);
400  ndbinfo.closeTable(table);
401  g_err << "scanOp->readTuples failed" << endl;
402  return NDBT_FAILED;
403  }
404 
405  const NdbInfoRecAttr* nodeId= scanOp->getValue("node_id");
406  const NdbInfoRecAttr* blockNumber= scanOp->getValue("block_number");
407  const NdbInfoRecAttr* blockInstance= scanOp->getValue("block_instance");
408  const NdbInfoRecAttr* counter= scanOp->getValue("counter");
409  const NdbInfoRecAttr* counter2= scanOp->getValue("counter2");
410 
411  if(scanOp->execute() != 0)
412  {
413  ndbinfo.releaseScanOperation(scanOp);
414  ndbinfo.closeTable(table);
415  g_err << "scanOp->execute failed" << endl;
416  return NDBT_FAILED;
417  }
418 
419  int ret;
420  int rows = 0;
421  while((ret = scanOp->nextResult()) == 1)
422  {
423  rows++;
424  (void)nodeId->u_32_value();
425  (void)blockNumber->u_32_value();
426  (void)blockInstance->u_32_value();
427  (void)counter->u_32_value();
428  (void)counter2->u_64_value();
429  }
430  ndbinfo.releaseScanOperation(scanOp);
431  if (ret != 0)
432  {
433  ndbinfo.closeTable(table);
434  g_err << "scan failed, ret: " << ret << endl;
435  return NDBT_FAILED;
436  }
437  ndbout << "rows: " << rows << endl;
438 
439  }
440 
441  ndbinfo.closeTable(table);
442  return NDBT_OK;
443 }
444 
445 
446 int runTestTableUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
447  int i = 0;
448  while (ctx->isTestStopped() == false) {
449  g_info << i << ": ";
450  (void)runTestTable(ctx, step);
451  i++;
452  }
453  return NDBT_OK;
454 }
455 
456 
457 int runRestarter(NDBT_Context* ctx, NDBT_Step* step){
458  int result = NDBT_OK;
459  int loops = ctx->getNumLoops();
460  int sync_threads = ctx->getProperty("SyncThreads", (unsigned)0);
461  int sleep0 = ctx->getProperty("Sleep0", (unsigned)0);
462  int sleep1 = ctx->getProperty("Sleep1", (unsigned)0);
463  int randnode = ctx->getProperty("RandNode", (unsigned)0);
464  NdbRestarter restarter;
465  int i = 0;
466  int lastId = 0;
467 
468  if (restarter.getNumDbNodes() < 2){
469  ctx->stopTest();
470  return NDBT_OK;
471  }
472 
473  if(restarter.waitClusterStarted() != 0){
474  g_err << "Cluster failed to start" << endl;
475  return NDBT_FAILED;
476  }
477 
478  if (loops > restarter.getNumDbNodes())
479  loops = restarter.getNumDbNodes();
480 
481  while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){
482 
483  int id = lastId % restarter.getNumDbNodes();
484  if (randnode == 1)
485  {
486  id = rand() % restarter.getNumDbNodes();
487  }
488  int nodeId = restarter.getDbNodeId(id);
489  ndbout << "Restart node " << nodeId << endl;
490  if(restarter.restartOneDbNode(nodeId, false, true, true) != 0){
491  g_err << "Failed to restartNextDbNode" << endl;
492  result = NDBT_FAILED;
493  break;
494  }
495 
496  if (restarter.waitNodesNoStart(&nodeId, 1))
497  {
498  g_err << "Failed to waitNodesNoStart" << endl;
499  result = NDBT_FAILED;
500  break;
501  }
502 
503  if (sleep1)
504  NdbSleep_MilliSleep(sleep1);
505 
506  if (restarter.startNodes(&nodeId, 1))
507  {
508  g_err << "Failed to start node" << endl;
509  result = NDBT_FAILED;
510  break;
511  }
512 
513  if(restarter.waitClusterStarted() != 0){
514  g_err << "Cluster failed to start" << endl;
515  result = NDBT_FAILED;
516  break;
517  }
518 
519  if (sleep0)
520  NdbSleep_MilliSleep(sleep0);
521 
522  ctx->sync_up_and_wait("PauseThreads", sync_threads);
523 
524  lastId++;
525  i++;
526  }
527 
528  ctx->stopTest();
529 
530  return result;
531 }
532 
533 
534 
535 NDBT_TESTSUITE(testNdbinfo);
536 #ifndef NDB_WIN
537 
540 TESTCASE("NodeRestart", "Scan NdbInfo tables while restarting nodes"){
541  STEP(runRestarter);
542  STEPS(runTestTableUntilStopped, 1);
543 }
544 #endif
545 TESTCASE("Ndbinfo",
546  "Test ndbapi interface to NDB$INFO"){
547  INITIALIZER(runTestNdbInfo);
548 }
549 TESTCASE("Ndbinfo10",
550  "Test ndbapi interface to NDB$INFO"){
551  STEPS(runTestNdbInfo, 10);
552 }
553 TESTCASE("ScanAll",
554  "Scan all colums of all table known to NdbInfo"
555  "check that number of rows returned are constant"){
556  STEPS(runScanAll, 1);
557 }
558 TESTCASE("ScanAll10",
559  "Scan all columns of all table known to NdbInfo from "
560  "10 parallel threads, check that number of rows returned "
561  "are constant"){
562  STEPS(runScanAll, 10);
563 }
564 TESTCASE("ScanStop",
565  "Randomly stop the scan"){
566  STEPS(runScanStop, 1);
567 }
568 TESTCASE("Ratelimit",
569  "Scan wit different combinations of ratelimit"){
570  STEPS(runRatelimit, 1);
571 }
572 TESTCASE("TestTable",
573  "Scan the test table and make sure it returns correct number "
574  "of rows which will depend on how many TUP blocks are configured"){
575  STEP(runTestTable);
576 }
577 NDBT_TESTSUITE_END(testNdbinfo);
578 
579 
580 int main(int argc, const char** argv){
581  ndb_init();
582  NDBT_TESTSUITE_INSTANCE(testNdbinfo);
583  testNdbinfo.setCreateTable(false);
584  testNdbinfo.setRunAllTables(true);
585  return testNdbinfo.execute(argc, argv);
586 }