MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
test_event.cpp
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 #include <NDBT_Test.hpp>
19 #include <NDBT_ReturnCodes.h>
20 #include <HugoTransactions.hpp>
21 #include <UtilTransactions.hpp>
22 #include <TestNdbEventOperation.hpp>
23 #include <NdbAutoPtr.hpp>
24 #include <NdbRestarter.hpp>
25 #include <NdbRestarts.hpp>
26 #include <signaldata/DumpStateOrd.hpp>
27 #include <NdbEnv.h>
28 #include <Bitmask.hpp>
29 
30 static int createEvent(Ndb *pNdb,
31  const NdbDictionary::Table &tab,
32  bool merge_events,
33  bool report)
34 {
35  char eventName[1024];
36  sprintf(eventName,"%s_EVENT",tab.getName());
37 
38  NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
39 
40  if (!myDict) {
41  g_err << "Dictionary not found "
42  << pNdb->getNdbError().code << " "
43  << pNdb->getNdbError().message << endl;
44  return NDBT_FAILED;
45  }
46 
47  myDict->dropEvent(eventName);
48 
49  NdbDictionary::Event myEvent(eventName);
50  myEvent.setTable(tab.getName());
51  myEvent.addTableEvent(NdbDictionary::Event::TE_ALL);
52  for(int a = 0; a < tab.getNoOfColumns(); a++){
53  myEvent.addEventColumn(a);
54  }
55  myEvent.mergeEvents(merge_events);
56 
57  if (report)
58  myEvent.setReport(NdbDictionary::Event::ER_SUBSCRIBE);
59 
60  int res = myDict->createEvent(myEvent); // Add event to database
61 
62  if (res == 0)
63  myEvent.print();
64  else if (myDict->getNdbError().classification ==
66  {
67  g_info << "Event creation failed event exists\n";
68  res = myDict->dropEvent(eventName);
69  if (res) {
70  g_err << "Failed to drop event: "
71  << myDict->getNdbError().code << " : "
72  << myDict->getNdbError().message << endl;
73  return NDBT_FAILED;
74  }
75  // try again
76  res = myDict->createEvent(myEvent); // Add event to database
77  if (res) {
78  g_err << "Failed to create event (1): "
79  << myDict->getNdbError().code << " : "
80  << myDict->getNdbError().message << endl;
81  return NDBT_FAILED;
82  }
83  }
84  else
85  {
86  g_err << "Failed to create event (2): "
87  << myDict->getNdbError().code << " : "
88  << myDict->getNdbError().message << endl;
89  return NDBT_FAILED;
90  }
91 
92  return NDBT_OK;
93 }
94 
95 static int createEvent(Ndb *pNdb,
96  const NdbDictionary::Table &tab,
97  NDBT_Context* ctx)
98 {
99  bool merge_events = ctx->getProperty("MergeEvents");
100  bool report = ctx->getProperty("ReportSubscribe");
101 
102  return createEvent(pNdb, tab, merge_events, report);
103 }
104 
105 static int dropEvent(Ndb *pNdb, const NdbDictionary::Table &tab)
106 {
107  char eventName[1024];
108  sprintf(eventName,"%s_EVENT",tab.getName());
109  NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
110  if (!myDict) {
111  g_err << "Dictionary not found "
112  << pNdb->getNdbError().code << " "
113  << pNdb->getNdbError().message << endl;
114  return NDBT_FAILED;
115  }
116  if (myDict->dropEvent(eventName)) {
117  g_err << "Failed to drop event: "
118  << myDict->getNdbError().code << " : "
119  << myDict->getNdbError().message << endl;
120  return NDBT_FAILED;
121  }
122  return NDBT_OK;
123 }
124 
125 static
126 NdbEventOperation *createEventOperation(Ndb *ndb,
127  const NdbDictionary::Table &tab,
128  int do_report_error = 1)
129 {
130  char buf[1024];
131  sprintf(buf, "%s_EVENT", tab.getName());
132  NdbEventOperation *pOp= ndb->createEventOperation(buf);
133  if (pOp == 0)
134  {
135  if (do_report_error)
136  g_err << "createEventOperation: "
137  << ndb->getNdbError().code << " "
138  << ndb->getNdbError().message << endl;
139  return 0;
140  }
141  int n_columns= tab.getNoOfColumns();
142  for (int j = 0; j < n_columns; j++)
143  {
144  pOp->getValue(tab.getColumn(j)->getName());
145  pOp->getPreValue(tab.getColumn(j)->getName());
146  }
147  if ( pOp->execute() )
148  {
149  if (do_report_error)
150  g_err << "pOp->execute(): "
151  << pOp->getNdbError().code << " "
152  << pOp->getNdbError().message << endl;
153  ndb->dropEventOperation(pOp);
154  return 0;
155  }
156  return pOp;
157 }
158 
159 static int runCreateEvent(NDBT_Context* ctx, NDBT_Step* step)
160 {
161  if (createEvent(GETNDB(step),* ctx->getTab(), ctx) != 0){
162  return NDBT_FAILED;
163  }
164  return NDBT_OK;
165 }
166 
167 Uint32 setAnyValue(Ndb* ndb, NdbTransaction* trans, int rowid, int updVal)
168 {
169  /* XOR 2 32bit words of transid together */
170  Uint64 transId = trans->getTransactionId();
171  return transId ^ (transId >> 32);
172 }
173 
174 bool checkAnyValueTransId(Uint64 transId, Uint32 anyValue)
175 {
176  return transId && (anyValue == Uint32(transId ^ (transId >> 32)));
177 }
178 
180  Uint32 pk;
181  Uint32 count;
182  Uint32 event;
183 };
184 
185 static int
186 eventOperation(Ndb* pNdb, const NdbDictionary::Table &tab, void* pstats, int records)
187 {
188  const char function[] = "HugoTransactions::eventOperation: ";
189  struct receivedEvent* recInsertEvent;
191  p00( recInsertEvent = new struct receivedEvent[3*records] );
192  struct receivedEvent* recUpdateEvent = &recInsertEvent[records];
193  struct receivedEvent* recDeleteEvent = &recInsertEvent[2*records];
194 
196 
197  stats.n_inserts = 0;
198  stats.n_deletes = 0;
199  stats.n_updates = 0;
200  stats.n_consecutive = 0;
201  stats.n_duplicates = 0;
202  stats.n_inconsistent_gcis = 0;
203 
204  for (int i = 0; i < records; i++) {
205  recInsertEvent[i].pk = 0xFFFFFFFF;
206  recInsertEvent[i].count = 0;
207  recInsertEvent[i].event = 0xFFFFFFFF;
208 
209  recUpdateEvent[i].pk = 0xFFFFFFFF;
210  recUpdateEvent[i].count = 0;
211  recUpdateEvent[i].event = 0xFFFFFFFF;
212 
213  recDeleteEvent[i].pk = 0xFFFFFFFF;
214  recDeleteEvent[i].count = 0;
215  recDeleteEvent[i].event = 0xFFFFFFFF;
216  }
217 
218  NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
219 
220  if (!myDict) {
221  g_err << function << "Event Creation failedDictionary not found\n";
222  return NDBT_FAILED;
223  }
224 
225  int r = 0;
226  NdbEventOperation *pOp;
227 
228  char eventName[1024];
229  sprintf(eventName,"%s_EVENT",tab.getName());
230  int noEventColumnName = tab.getNoOfColumns();
231 
232  g_info << function << "create EventOperation\n";
233  pOp = pNdb->createEventOperation(eventName);
234  if ( pOp == NULL ) {
235  g_err << function << "Event operation creation failed\n";
236  return NDBT_FAILED;
237  }
238 
239  g_info << function << "get values\n";
240  NdbRecAttr* recAttr[1024];
241  NdbRecAttr* recAttrPre[1024];
242 
243  const NdbDictionary::Table *_table = myDict->getTable(tab.getName());
244 
245  for (int a = 0; a < (int)noEventColumnName; a++) {
246  recAttr[a] = pOp->getValue(_table->getColumn(a)->getName());
247  recAttrPre[a] = pOp->getPreValue(_table->getColumn(a)->getName());
248  }
249 
250  // set up the callbacks
251  g_info << function << "execute\n";
252  if (pOp->execute()) { // This starts changes to "start flowing"
253  g_err << function << "operation execution failed: \n";
254  g_err << pOp->getNdbError().code << " "
255  << pOp->getNdbError().message << endl;
256  return NDBT_FAILED;
257  }
258 
259  g_info << function << "ok\n";
260 
261  int count = 0;
262  Uint64 last_inconsitant_gci = (Uint64)-1;
263 
264  while (r < records){
265  //printf("now waiting for event...\n");
266  int res = pNdb->pollEvents(1000); // wait for event or 1000 ms
267 
268  if (res > 0) {
269  //printf("got data! %d\n", r);
270  NdbEventOperation *tmp;
271  while ((tmp= pNdb->nextEvent()))
272  {
273  assert(tmp == pOp);
274  r++;
275  count++;
276 
277  Uint64 gci = pOp->getGCI();
278  Uint32 pk = recAttr[0]->u_32_value();
279 
280  if (!pOp->isConsistent()) {
281  if (last_inconsitant_gci != gci) {
282  last_inconsitant_gci = gci;
283  stats.n_inconsistent_gcis++;
284  }
285  g_warning << "A node failure has occured and events might be missing\n";
286  }
287  g_info << function << "GCI " << gci << ": " << count;
288  struct receivedEvent* recEvent;
289  switch (pOp->getEventType()) {
291  stats.n_inserts++;
292  g_info << " INSERT: ";
293  recEvent = recInsertEvent;
294  break;
296  stats.n_deletes++;
297  g_info << " DELETE: ";
298  recEvent = recDeleteEvent;
299  break;
301  stats.n_updates++;
302  g_info << " UPDATE: ";
303  recEvent = recUpdateEvent;
304  break;
305  default:
307  abort();
308  }
309 
310  /* Check event transaction id */
311  Uint32 anyValue = pOp->getAnyValue();
312  Uint64 transId = pOp->getTransId();
313  if (anyValue)
314  {
315  if (!checkAnyValueTransId(transId, anyValue))
316  {
317  g_err << "ERROR : TransId and AnyValue mismatch. "
318  << "Transid : " << transId
319  << ", AnyValue : " << anyValue
320  << ", Expected AnyValue : "
321  << (Uint32) ((transId >> 32) ^ transId)
322  << endl;
323  abort();
324  return NDBT_FAILED;
325  }
326  }
327 
328  if ((int)pk < records) {
329  recEvent[pk].pk = pk;
330  recEvent[pk].count++;
331  }
332 
333  for (int i = 1; i < (int)noEventColumnName; i++) {
334  if (recAttr[i]->isNULL() >= 0) { // we have a value
335  g_info << " post[" << i << "]=";
336  if (recAttr[i]->isNULL() == 0) // we have a non-null value
337  g_info << recAttr[i]->u_32_value();
338  else // we have a null value
339  g_info << "NULL";
340  }
341  if (recAttrPre[i]->isNULL() >= 0) { // we have a value
342  g_info << " pre[" << i << "]=";
343  if (recAttrPre[i]->isNULL() == 0) // we have a non-null value
344  g_info << recAttrPre[i]->u_32_value();
345  else // we have a null value
346  g_info << "NULL";
347  }
348  }
349  g_info << endl;
350  }
351  }
352  else
353  {
354  ;//printf("timed out\n");
355  }
356  }
357 
358  g_info << "dropping event operation" << endl;
359 
360  int res = pNdb->dropEventOperation(pOp);
361  if (res != 0) {
362  g_err << "operation execution failed\n";
363  return NDBT_FAILED;
364  }
365 
366  g_info << " ok" << endl;
367 
368  if (stats.n_inserts > 0) {
369  stats.n_consecutive++;
370  }
371  if (stats.n_deletes > 0) {
372  stats.n_consecutive++;
373  }
374  if (stats.n_updates > 0) {
375  stats.n_consecutive++;
376  }
377  for (int i = 0; i < (int)records/3; i++) {
378  if (recInsertEvent[i].pk != Uint32(i)) {
379  stats.n_consecutive ++;
380  ndbout << "missing insert pk " << i << endl;
381  } else if (recInsertEvent[i].count > 1) {
382  ndbout << "duplicates insert pk " << i
383  << " count " << recInsertEvent[i].count << endl;
384  stats.n_duplicates += recInsertEvent[i].count-1;
385  }
386  if (recUpdateEvent[i].pk != Uint32(i)) {
387  stats.n_consecutive ++;
388  ndbout << "missing update pk " << i << endl;
389  } else if (recUpdateEvent[i].count > 1) {
390  ndbout << "duplicates update pk " << i
391  << " count " << recUpdateEvent[i].count << endl;
392  stats.n_duplicates += recUpdateEvent[i].count-1;
393  }
394  if (recDeleteEvent[i].pk != Uint32(i)) {
395  stats.n_consecutive ++;
396  ndbout << "missing delete pk " << i << endl;
397  } else if (recDeleteEvent[i].count > 1) {
398  ndbout << "duplicates delete pk " << i
399  << " count " << recDeleteEvent[i].count << endl;
400  stats.n_duplicates += recDeleteEvent[i].count-1;
401  }
402  }
403 
404  return NDBT_OK;
405 }
406 
407 int runCreateShadowTable(NDBT_Context* ctx, NDBT_Step* step)
408 {
409  const NdbDictionary::Table *table= ctx->getTab();
410  char buf[1024];
411  sprintf(buf, "%s_SHADOW", table->getName());
412 
413  GETNDB(step)->getDictionary()->dropTable(buf);
414  if (GETNDB(step)->getDictionary()->getTable(buf))
415  {
416  g_err << "unsucessful drop of " << buf << endl;
417  return NDBT_FAILED;
418  }
419 
420  NdbDictionary::Table table_shadow(*table);
421  table_shadow.setName(buf);
422  // TODO should be removed
423  // This should work wo/ next line
424  //table_shadow.setNodeGroupIds(0, 0);
425  GETNDB(step)->getDictionary()->createTable(table_shadow);
426  if (GETNDB(step)->getDictionary()->getTable(buf))
427  return NDBT_OK;
428 
429  g_err << "unsucessful create of " << buf << endl;
430  return NDBT_FAILED;
431 }
432 
433 int runDropShadowTable(NDBT_Context* ctx, NDBT_Step* step)
434 {
435  const NdbDictionary::Table *table= ctx->getTab();
436  char buf[1024];
437  sprintf(buf, "%s_SHADOW", table->getName());
438 
439  GETNDB(step)->getDictionary()->dropTable(buf);
440  return NDBT_OK;
441 }
442 
443 int runCreateDropEventOperation(NDBT_Context* ctx, NDBT_Step* step)
444 {
445  int loops = ctx->getNumLoops();
446  //int records = ctx->getNumRecords();
447  HugoTransactions hugoTrans(*ctx->getTab());
448  EventOperationStats stats;
449 
450  //Ndb *pNdb=GETNDB(step);
451  const NdbDictionary::Table& tab= *ctx->getTab();
452  //NdbEventOperation *pOp;
453  char eventName[1024];
454  sprintf(eventName,"%s_EVENT",tab.getName());
455  //int noEventColumnName = tab.getNoOfColumns();
456 
457  for (int i= 0; i < loops; i++)
458  {
459 #if 1
460  if (eventOperation(GETNDB(step), tab, (void*)&stats, 0) != 0){
461  return NDBT_FAILED;
462  }
463 #else
464  g_info << "create EventOperation\n";
465  pOp = pNdb->createEventOperation(eventName);
466  if ( pOp == NULL ) {
467  g_err << "Event operation creation failed\n";
468  return NDBT_FAILED;
469  }
470 
471  g_info << "dropping event operation" << endl;
472  int res = pNdb->dropEventOperation(pOp);
473  if (res != 0) {
474  g_err << "operation execution failed\n";
475  return NDBT_FAILED;
476  }
477 #endif
478  }
479 
480  return NDBT_OK;
481 }
482 
483 int theThreadIdCounter = 0;
484 
485 int runEventOperation(NDBT_Context* ctx, NDBT_Step* step)
486 {
487  int tId = theThreadIdCounter++;
488  //int loops = ctx->getNumLoops();
489  int records = ctx->getNumRecords();
490  HugoTransactions hugoTrans(*ctx->getTab());
491 
492  EventOperationStats stats;
493 
494  g_info << "***** start Id " << tId << endl;
495 
496  // sleep(tId);
497 
498  if (eventOperation(GETNDB(step), *ctx->getTab(), (void*)&stats, 3*records) != 0){
499  return NDBT_FAILED;
500  }
501 
502  int ret;
503  if (stats.n_inserts == records &&
504  stats.n_deletes == records &&
505  stats.n_updates == records &&
506  stats.n_consecutive == 3 &&
507  stats.n_duplicates == 0)
508  ret = NDBT_OK;
509  else
510  ret = NDBT_FAILED;
511 
512  if (ret == NDBT_FAILED) {
513  g_info << "***** end Id " << tId << endl;
514  ndbout_c("n_inserts = %d (%d)", stats.n_inserts, records);
515  ndbout_c("n_deletes = %d (%d)", stats.n_deletes, records);
516  ndbout_c("n_updates = %d (%d)", stats.n_updates, records);
517  ndbout_c("n_consecutive = %d (%d)", stats.n_consecutive, 3);
518  ndbout_c("n_duplicates = %d (%d)", stats.n_duplicates, 0);
519  ndbout_c("n_inconsistent_gcis = %d (%d)", stats.n_inconsistent_gcis, 0);
520  }
521 
522  return ret;
523 }
524 
525 int runEventLoad(NDBT_Context* ctx, NDBT_Step* step)
526 {
527  int loops = ctx->getNumLoops();
528  int records = ctx->getNumRecords();
529  HugoTransactions hugoTrans(*ctx->getTab());
530 
531  hugoTrans.setAnyValueCallback(setAnyValue);
532 
533  sleep(1);
534 #if 0
535  sleep(5);
536  sleep(theThreadIdCounter);
537 #endif
538  if (hugoTrans.loadTable(GETNDB(step), records, 1, true, loops) != 0){
539  return NDBT_FAILED;
540  }
541  if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, loops) != 0){
542  return NDBT_FAILED;
543  }
544  if (hugoTrans.pkDelRecords(GETNDB(step), records, 1, true, loops) != 0){
545  return NDBT_FAILED;
546  }
547  return NDBT_OK;
548 }
549 
550 int runEventMixedLoad(NDBT_Context* ctx, NDBT_Step* step)
551 {
552  int loops = ctx->getNumLoops();
553  int records = ctx->getNumRecords();
554  HugoTransactions hugoTrans(*ctx->getTab());
555  hugoTrans.setAnyValueCallback(setAnyValue);
556 
557  if(ctx->getPropertyWait("LastGCI_hi", ~(Uint32)0))
558  {
559  g_err << "FAIL " << __LINE__ << endl;
560  return NDBT_FAILED;
561  }
562 
563  while(loops -- && !ctx->isTestStopped())
564  {
565  hugoTrans.clearTable(GETNDB(step), 0);
566 
567  if (hugoTrans.loadTable(GETNDB(step), 3*records, 1, true, 1) != 0){
568  g_err << "FAIL " << __LINE__ << endl;
569  return NDBT_FAILED;
570  }
571 
572  if (hugoTrans.pkDelRecords(GETNDB(step), 3*records, 1, true, 1) != 0){
573  g_err << "FAIL " << __LINE__ << endl;
574  return NDBT_FAILED;
575  }
576  if (hugoTrans.loadTable(GETNDB(step), records, 1, true, 1) != 0){
577  g_err << "FAIL " << __LINE__ << endl;
578  return NDBT_FAILED;
579  }
580  if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, 1) != 0){
581  g_err << "FAIL " << __LINE__ << endl;
582  return NDBT_FAILED;
583  }
584  if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, 1) != 0){
585  g_err << "FAIL " << __LINE__ << endl;
586  return NDBT_FAILED;
587  }
588  if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, 1) != 0){
589  g_err << "FAIL " << __LINE__ << endl;
590  return NDBT_FAILED;
591  }
592 
593  ndbout_c("set(LastGCI_hi): %u/%u",
594  Uint32(hugoTrans.m_latest_gci >> 32),
595  Uint32(hugoTrans.m_latest_gci));
596  ctx->setProperty("LastGCI_lo", Uint32(hugoTrans.m_latest_gci));
597  ctx->setProperty("LastGCI_hi", Uint32(hugoTrans.m_latest_gci >> 32));
598  if(ctx->getPropertyWait("LastGCI_hi", ~(Uint32)0))
599  {
600  g_err << "FAIL " << __LINE__ << endl;
601  return NDBT_FAILED;
602  }
603  }
604  ctx->stopTest();
605  return NDBT_OK;
606 }
607 
608 int runDropEvent(NDBT_Context* ctx, NDBT_Step* step)
609 {
610  return dropEvent(GETNDB(step), * ctx->getTab());
611 }
612 
613 int runVerify(NDBT_Context* ctx, NDBT_Step* step)
614 {
615  const NdbDictionary::Table * table= ctx->getTab();
616  char buf[1024];
617 
618  sprintf(buf, "%s_SHADOW", table->getName());
619 
620  HugoTransactions hugoTrans(*table);
621  if (hugoTrans.compare(GETNDB(step), buf, 0))
622  {
623  return NDBT_FAILED;
624  }
625 
626  return NDBT_OK;
627 }
628 
629 int runEventApplier(NDBT_Context* ctx, NDBT_Step* step)
630 {
631  DBUG_ENTER("runEventApplier");
632 
633  int result = NDBT_OK;
634  const NdbDictionary::Table * table= ctx->getTab();
635  HugoTransactions hugoTrans(* table);
636 
637  char shadow[1024], buf[1024];
638  sprintf(shadow, "%s_SHADOW", table->getName());
639  const NdbDictionary::Table * table_shadow;
640  if ((table_shadow = GETNDB(step)->getDictionary()->getTable(shadow)) == 0)
641  {
642  g_err << "Unable to get table " << shadow << endl;
643  DBUG_RETURN(NDBT_FAILED);
644  }
645 
646  sprintf(buf, "%s_EVENT", table->getName());
647  NdbEventOperation *pOp, *pCreate = 0;
648  pCreate = pOp = GETNDB(step)->createEventOperation(buf);
649  if ( pOp == NULL ) {
650  g_err << "Event operation creation failed on %s" << buf << endl;
651  DBUG_RETURN(NDBT_FAILED);
652  }
653  bool merge_events = ctx->getProperty("MergeEvents");
654  pOp->mergeEvents(merge_events);
655 
656  int i;
657  int n_columns= table->getNoOfColumns();
658  NdbRecAttr* recAttr[1024];
659  NdbRecAttr* recAttrPre[1024];
660  for (i = 0; i < n_columns; i++) {
661  recAttr[i] = pOp->getValue(table->getColumn(i)->getName());
662  recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
663  }
664 
665  if (pOp->execute()) { // This starts changes to "start flowing"
666  g_err << "execute operation execution failed: \n";
667  g_err << pOp->getNdbError().code << " "
668  << pOp->getNdbError().message << endl;
669  result = NDBT_FAILED;
670  goto end;
671  }
672 
673  ctx->setProperty("LastGCI_hi", ~(Uint32)0);
674  ctx->broadcast();
675 
676  while(!ctx->isTestStopped())
677  {
678  int count= 0;
679  Uint64 stop_gci= ~(Uint64)0;
680  Uint64 curr_gci = 0;
681  Ndb* ndb= GETNDB(step);
682 
683  while(!ctx->isTestStopped() && curr_gci <= stop_gci)
684  {
685  ndb->pollEvents(100, &curr_gci);
686  while ((pOp= ndb->nextEvent()) != 0)
687  {
688  assert(pOp == pCreate);
689 
690  if (pOp->getEventType() >=
691  NdbDictionary::Event::TE_FIRST_NON_DATA_EVENT)
692  continue;
693 
694  int noRetries= 0;
695  do
696  {
697  NdbTransaction *trans= GETNDB(step)->startTransaction();
698  if (trans == 0)
699  {
700  g_err << "startTransaction failed "
701  << GETNDB(step)->getNdbError().code << " "
702  << GETNDB(step)->getNdbError().message << endl;
703  result = NDBT_FAILED;
704  goto end;
705 
706  }
707 
708  NdbOperation *op= trans->getNdbOperation(table_shadow);
709  if (op == 0)
710  {
711  g_err << "getNdbOperation failed "
712  << trans->getNdbError().code << " "
713  << trans->getNdbError().message << endl;
714  result = NDBT_FAILED;
715  goto end;
716 
717  }
718 
719  switch (pOp->getEventType()) {
721  if (op->writeTuple())
722  {
723  g_err << "insertTuple "
724  << op->getNdbError().code << " "
725  << op->getNdbError().message << endl;
726  result = NDBT_FAILED;
727  goto end;
728 
729  }
730  break;
732  if (op->deleteTuple())
733  {
734  g_err << "deleteTuple "
735  << op->getNdbError().code << " "
736  << op->getNdbError().message << endl;
737  result = NDBT_FAILED;
738  goto end;
739 
740  }
741  break;
743  if (op->writeTuple())
744  {
745  g_err << "updateTuple "
746  << op->getNdbError().code << " "
747  << op->getNdbError().message << endl;
748  result = NDBT_FAILED;
749  goto end;
750 
751  }
752  break;
753  default:
754  abort();
755  }
756 
757  /* Check event transaction id */
758  Uint32 anyValue = pOp->getAnyValue();
759  Uint64 transId = pOp->getTransId();
760  if (anyValue)
761  {
762  if (!checkAnyValueTransId(transId, anyValue))
763  {
764  g_err << "ERROR : TransId and AnyValue mismatch. "
765  << "Transid : " << transId
766  << ", AnyValue : " << anyValue
767  << ", Expected AnyValue : "
768  << (Uint32) ((transId >> 32) ^ transId)
769  << endl;
770  abort();
771  return NDBT_FAILED;
772  }
773  }
774 
775  for (i= 0; i < n_columns; i++)
776  {
777  if (recAttr[i]->isNULL())
778  {
779  if (table->getColumn(i)->getPrimaryKey())
780  {
781  g_err << "internal error: primary key isNull()="
782  << recAttr[i]->isNULL() << endl;
783  result = NDBT_FAILED;
784  goto end;
785 
786  }
787  switch (pOp->getEventType()) {
789  if (recAttr[i]->isNULL() < 0)
790  {
791  g_err << "internal error: missing value for insert\n";
792  result = NDBT_FAILED;
793  goto end;
794 
795  }
796  break;
798  break;
800  break;
801  default:
802  abort();
803  }
804  }
805  if (table->getColumn(i)->getPrimaryKey() &&
806  op->equal(i,recAttr[i]->aRef()))
807  {
808  g_err << "equal " << i << " "
809  << op->getNdbError().code << " "
810  << op->getNdbError().message << endl;
811  result = NDBT_FAILED;
812  goto end;
813 
814  }
815  }
816 
817  switch (pOp->getEventType()) {
819  for (i= 0; i < n_columns; i++)
820  {
821  if (!table->getColumn(i)->getPrimaryKey() &&
822  op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef()))
823  {
824  g_err << "setValue(insert) " << i << " "
825  << op->getNdbError().code << " "
826  << op->getNdbError().message << endl;
827  result = NDBT_FAILED;
828  goto end;
829 
830  }
831  }
832  break;
834  break;
836  for (i= 0; i < n_columns; i++)
837  {
838  if (!table->getColumn(i)->getPrimaryKey() &&
839  recAttr[i]->isNULL() >= 0 &&
840  op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef()))
841  {
842  g_err << "setValue(update) " << i << " "
843  << op->getNdbError().code << " "
844  << op->getNdbError().message << endl;
845  result = NDBT_FAILED;
846  goto end;
847 
848  }
849  }
850  break;
851  default:
853  abort();
854  }
855  if (trans->execute(Commit) == 0)
856  {
857  trans->close();
858  count++;
859  // everything ok
860  break;
861  }
862 
864  {
865  g_err << "Ignoring execute failed "
866  << trans->getNdbError().code << " "
867  << trans->getNdbError().message << endl;
868 
869  trans->close();
870  count++;
871  break;
872  }
873  else if (noRetries++ == 10)
874  {
875  g_err << "execute failed "
876  << trans->getNdbError().code << " "
877  << trans->getNdbError().message << endl;
878  trans->close();
879  result = NDBT_FAILED;
880  goto end;
881 
882  }
883  trans->close();
884  NdbSleep_MilliSleep(100); // sleep before retying
885  } while(1);
886  }
887  Uint32 stop_gci_hi = ctx->getProperty("LastGCI_hi", ~(Uint32)0);
888  Uint32 stop_gci_lo = ctx->getProperty("LastGCI_lo", ~(Uint32)0);
889  stop_gci = Uint64(stop_gci_lo) | (Uint64(stop_gci_hi) << 32);
890  }
891 
892  ndbout_c("Applied gci: %u/%u, %d events",
893  Uint32(stop_gci >> 32), Uint32(stop_gci), count);
894  if (hugoTrans.compare(GETNDB(step), shadow, 0))
895  {
896  g_err << "compare failed" << endl;
897  result = NDBT_FAILED;
898  goto end;
899  }
900  ctx->setProperty("LastGCI_hi", ~(Uint32)0);
901  ctx->broadcast();
902  }
903 
904 end:
905  if(pCreate)
906  {
907  if (GETNDB(step)->dropEventOperation(pCreate)) {
908  g_err << "dropEventOperation execution failed "
909  << GETNDB(step)->getNdbError().code << " "
910  << GETNDB(step)->getNdbError().message << endl;
911  result = NDBT_FAILED;
912  }
913  }
914  ctx->stopTest();
915  DBUG_RETURN(result);
916 }
917 
918 int runEventConsumer(NDBT_Context* ctx, NDBT_Step* step)
919 {
920  DBUG_ENTER("runEventConsumer");
921  int result = NDBT_OK;
922  const NdbDictionary::Table * table= ctx->getTab();
923  HugoTransactions hugoTrans(* table);
924 
925  char buf[1024];
926  sprintf(buf, "%s_EVENT", table->getName());
927  NdbEventOperation *pOp, *pCreate = 0;
928  pCreate = pOp = GETNDB(step)->createEventOperation(buf);
929  if ( pOp == NULL ) {
930  g_err << "Event operation creation failed on %s" << buf << endl;
931  DBUG_RETURN(NDBT_FAILED);
932  }
933  bool merge_events = ctx->getProperty("MergeEvents");
934  pOp->mergeEvents(merge_events);
935 
936  int i;
937  int n_columns= table->getNoOfColumns();
938  NdbRecAttr* recAttr[1024];
939  NdbRecAttr* recAttrPre[1024];
940  for (i = 0; i < n_columns; i++) {
941  recAttr[i] = pOp->getValue(table->getColumn(i)->getName());
942  recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
943  }
944 
945  if (pOp->execute()) { // This starts changes to "start flowing"
946  g_err << "execute operation execution failed: \n";
947  g_err << pOp->getNdbError().code << " "
948  << pOp->getNdbError().message << endl;
949  result = NDBT_FAILED;
950  goto end;
951  }
952 
953  ctx->setProperty("LastGCI_hi", ~(Uint32)0);
954  ctx->broadcast();
955 
956  while(!ctx->isTestStopped())
957  {
958  //int count= 0;
959  Ndb* ndb= GETNDB(step);
960 
961  Uint64 last_gci = 0;
962  while(!ctx->isTestStopped())
963  {
964  Uint32 count = 0;
965  Uint64 curr_gci;
966  ndb->pollEvents(100, &curr_gci);
967  if (curr_gci != last_gci)
968  {
969  while ((pOp= ndb->nextEvent()) != 0)
970  {
971  count++;
972  }
973  last_gci = curr_gci;
974  }
975  ndbout_c("Consumed gci: %u/%u, %d events",
976  Uint32(last_gci >> 32), Uint32(last_gci), count);
977  }
978  }
979 
980 end:
981  if(pCreate)
982  {
983  if (GETNDB(step)->dropEventOperation(pCreate)) {
984  g_err << "dropEventOperation execution failed "
985  << GETNDB(step)->getNdbError().code << " "
986  << GETNDB(step)->getNdbError().message << endl;
987  result = NDBT_FAILED;
988  }
989  }
990  ctx->stopTest();
991  DBUG_RETURN(result);
992 }
993 
994 int runEventListenerUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
995 {
996 
997  int result = NDBT_OK;
998  const NdbDictionary::Table * table= ctx->getTab();
999  HugoTransactions hugoTrans(* table);
1000  Ndb* ndb= GETNDB(step);
1001 
1002  char buf[1024];
1003  sprintf(buf, "%s_EVENT", table->getName());
1004  NdbEventOperation *pOp, *pCreate = 0;
1005  pCreate = pOp = ndb->createEventOperation(buf);
1006  if ( pOp == NULL ) {
1007  g_err << "Event operation creation failed on %s" << buf << endl;
1008  return NDBT_FAILED;
1009  }
1010 
1011  int i;
1012  int n_columns= table->getNoOfColumns();
1013  NdbRecAttr* recAttr[1024];
1014  NdbRecAttr* recAttrPre[1024];
1015  for (i = 0; i < n_columns; i++) {
1016  recAttr[i] = pOp->getValue(table->getColumn(i)->getName());
1017  recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
1018  }
1019 
1020  if (pOp->execute())
1021  { // This starts changes to "start flowing"
1022  g_err << "execute operation execution failed: \n";
1023  g_err << pOp->getNdbError().code << " "
1024  << pOp->getNdbError().message << endl;
1025  result = NDBT_FAILED;
1026  goto end;
1027  }
1028 
1029  while(!ctx->isTestStopped())
1030  {
1031  Uint64 curr_gci = 0;
1032  while(!ctx->isTestStopped())
1033  {
1034  ndb->pollEvents(100, &curr_gci);
1035  while ((pOp= ndb->nextEvent()) != 0)
1036  {
1037  assert(pOp == pCreate);
1038  }
1039  }
1040  }
1041 
1042 end:
1043  if(pCreate)
1044  {
1045  if (ndb->dropEventOperation(pCreate)) {
1046  g_err << "dropEventOperation execution failed "
1047  << ndb->getNdbError().code << " "
1048  << ndb->getNdbError().message << endl;
1049  result = NDBT_FAILED;
1050  }
1051  }
1052  return result;
1053 }
1054 
1055 int runRestarter(NDBT_Context* ctx, NDBT_Step* step){
1056  int result = NDBT_OK;
1057  //int loops = ctx->getNumLoops();
1058  NdbRestarter restarter;
1059  int i = 0;
1060  int lastId = 0;
1061  bool abort = ctx->getProperty("Graceful", Uint32(0)) == 0;
1062 
1063  if (restarter.getNumDbNodes() < 2){
1064  ctx->stopTest();
1065  return NDBT_OK;
1066  }
1067 
1068  if(restarter.waitClusterStarted(60) != 0){
1069  g_err << "Cluster failed to start" << endl;
1070  return NDBT_FAILED;
1071  }
1072 
1073  while(result != NDBT_FAILED && !ctx->isTestStopped()){
1074 
1075  int id = lastId % restarter.getNumDbNodes();
1076  int nodeId = restarter.getDbNodeId(id);
1077  ndbout << "Restart node " << nodeId << endl;
1078  if (abort == false && ((i % 3) == 0))
1079  {
1080  restarter.insertErrorInNode(nodeId, 13043);
1081  }
1082 
1083  if(restarter.restartOneDbNode(nodeId, false, false, abort) != 0){
1084  g_err << "Failed to restartNextDbNode" << endl;
1085  result = NDBT_FAILED;
1086  break;
1087  }
1088 
1089  if(restarter.waitClusterStarted(60) != 0){
1090  g_err << "Cluster failed to start" << endl;
1091  result = NDBT_FAILED;
1092  break;
1093  }
1094 
1095  lastId++;
1096  i++;
1097  }
1098 
1099  return result;
1100 }
1101 
1102 int runRestarterLoop(NDBT_Context* ctx, NDBT_Step* step)
1103 {
1104  int result = NDBT_OK;
1105  int loops = ctx->getNumLoops();
1106  NdbRestarter restarter;
1107  int i = 0;
1108  int lastId = 0;
1109 
1110  if (restarter.getNumDbNodes() < 2){
1111  ctx->stopTest();
1112  return NDBT_OK;
1113  }
1114 
1115  if(restarter.waitClusterStarted(60) != 0){
1116  g_err << "Cluster failed to start" << endl;
1117  return NDBT_FAILED;
1118  }
1119 
1120  while(result != NDBT_FAILED
1121  && !ctx->isTestStopped()
1122  && i < loops)
1123  {
1124  int id = lastId % restarter.getNumDbNodes();
1125  int nodeId = restarter.getDbNodeId(id);
1126  ndbout << "Restart node " << nodeId << endl;
1127  if(restarter.restartOneDbNode(nodeId, false, false, true) != 0){
1128  g_err << "Failed to restartNextDbNode" << endl;
1129  result = NDBT_FAILED;
1130  break;
1131  }
1132 
1133  if(restarter.waitClusterStarted(60) != 0){
1134  g_err << "Cluster failed to start" << endl;
1135  result = NDBT_FAILED;
1136  break;
1137  }
1138 
1139  lastId++;
1140  i++;
1141  }
1142 
1143  ctx->stopTest();
1144  return result;
1145 }
1146 
1149 
1150 static int getAllTables(NDBT_Context* ctx, NDBT_Step* step)
1151 {
1152  DBUG_ENTER("getAllTables");
1153  Ndb * ndb= GETNDB(step);
1154  NdbDictionary::Dictionary * dict = ndb->getDictionary();
1155  pTabs.clear();
1156 
1157  for (int i= 0; i < ctx->getNumTables(); i++)
1158  {
1159  const NdbDictionary::Table *pTab= dict->getTable(ctx->getTableName(i));
1160  if (pTab == 0)
1161  {
1162  ndbout << "Failed to get table" << endl;
1163  ndbout << dict->getNdbError() << endl;
1164  DBUG_RETURN(NDBT_FAILED);
1165  }
1166  pTabs.push_back(pTab);
1167  ndbout << " " << ctx->getTableName(i);
1168  }
1169  pTabs.push_back(NULL);
1170  ndbout << endl;
1171 
1172  DBUG_RETURN(NDBT_OK);
1173 }
1174 
1175 static int createAllEvents(NDBT_Context* ctx, NDBT_Step* step)
1176 {
1177  DBUG_ENTER("createAllEvents");
1178  Ndb * ndb= GETNDB(step);
1179  for (int i= 0; pTabs[i]; i++)
1180  {
1181  if (createEvent(ndb,*pTabs[i], ctx))
1182  {
1183  DBUG_RETURN(NDBT_FAILED);
1184  }
1185  }
1186  DBUG_RETURN(NDBT_OK);
1187 }
1188 
1189 static int dropAllEvents(NDBT_Context* ctx, NDBT_Step* step)
1190 {
1191  DBUG_ENTER("dropAllEvents");
1192  Ndb * ndb= GETNDB(step);
1193  int i;
1194 
1195  for (i= 0; pTabs[i]; i++)
1196  {
1197  if (dropEvent(ndb,*pTabs[i]))
1198  {
1199  DBUG_RETURN(NDBT_FAILED);
1200  }
1201  }
1202  DBUG_RETURN(NDBT_OK);
1203 }
1204 
1205 static int createAllShadows(NDBT_Context* ctx, NDBT_Step* step)
1206 {
1207  DBUG_ENTER("createAllShadows");
1208  Ndb * ndb= GETNDB(step);
1209  NdbDictionary::Dictionary * dict = ndb->getDictionary();
1210  // create a "shadow" table for each table
1211  for (int i= 0; pTabs[i]; i++)
1212  {
1213  char buf[1024];
1214  sprintf(buf, "%s_SHADOW", pTabs[i]->getName());
1215 
1216  dict->dropTable(buf);
1217  if (dict->getTable(buf))
1218  {
1219  DBUG_RETURN(NDBT_FAILED);
1220  }
1221 
1222  NdbDictionary::Table table_shadow(*pTabs[i]);
1223  table_shadow.setName(buf);
1224  if (dict->createTable(table_shadow))
1225  {
1226  g_err << "createTable(" << buf << ") "
1227  << dict->getNdbError().code << " "
1228  << dict->getNdbError().message << endl;
1229  DBUG_RETURN(NDBT_FAILED);
1230  }
1231  pShadowTabs.push_back(dict->getTable(buf));
1232  if (!pShadowTabs[i])
1233  {
1234  g_err << "getTable(" << buf << ") "
1235  << dict->getNdbError().code << " "
1236  << dict->getNdbError().message << endl;
1237  DBUG_RETURN(NDBT_FAILED);
1238  }
1239  }
1240  DBUG_RETURN(NDBT_OK);
1241 }
1242 
1243 static int dropAllShadows(NDBT_Context* ctx, NDBT_Step* step)
1244 {
1245  DBUG_ENTER("dropAllShadows");
1246  Ndb * ndb= GETNDB(step);
1247  NdbDictionary::Dictionary * dict = ndb->getDictionary();
1248 
1249  for (int i= 0; pTabs[i]; i++)
1250  {
1251  char buf[1024];
1252  sprintf(buf, "%s_SHADOW", pTabs[i]->getName());
1253  if (dict->dropTable(buf))
1254  {
1255  DBUG_RETURN(NDBT_FAILED);
1256  }
1257  }
1258  DBUG_RETURN(NDBT_OK);
1259 }
1260 
1261 static int start_transaction(Ndb *ndb, Vector<HugoOperations*> &ops)
1262 {
1263  if (ops[0]->startTransaction(ndb) != NDBT_OK)
1264  return -1;
1265  NdbTransaction * t= ops[0]->getTransaction();
1266  for (int i= ops.size()-1; i > 0; i--)
1267  {
1268  ops[i]->setTransaction(t,true);
1269  }
1270  return 0;
1271 }
1272 
1273 static int close_transaction(Ndb *ndb, Vector<HugoOperations*> &ops)
1274 {
1275  if (ops[0]->closeTransaction(ndb) != NDBT_OK)
1276  return -1;
1277  for (int i= ops.size()-1; i > 0; i--)
1278  {
1279  ops[i]->setTransaction(NULL,true);
1280  }
1281  return 0;
1282 }
1283 
1284 static int execute_commit(Ndb *ndb, Vector<HugoOperations*> &ops)
1285 {
1286  if (ops[0]->execute_Commit(ndb) != NDBT_OK)
1287  return -1;
1288  return 0;
1289 }
1290 
1291 static int copy_events(Ndb *ndb)
1292 {
1293  DBUG_ENTER("copy_events");
1294  int r= 0;
1295  NdbDictionary::Dictionary * dict = ndb->getDictionary();
1296  int n_inserts= 0;
1297  int n_updates= 0;
1298  int n_deletes= 0;
1299  while (1)
1300  {
1301  int res= ndb->pollEvents(1000); // wait for event or 1000 ms
1302  DBUG_PRINT("info", ("pollEvents res=%d", res));
1303  if (res <= 0)
1304  {
1305  break;
1306  }
1307  NdbEventOperation *pOp;
1308  while ((pOp= ndb->nextEvent()))
1309  {
1310  char buf[1024];
1311  sprintf(buf, "%s_SHADOW", pOp->getEvent()->getTable()->getName());
1312  const NdbDictionary::Table *table= dict->getTable(buf);
1313 
1314  if (table == 0)
1315  {
1316  g_err << "unable to find table " << buf << endl;
1317  DBUG_RETURN(-1);
1318  }
1319 
1320  if (pOp->isOverrun())
1321  {
1322  g_err << "buffer overrun\n";
1323  DBUG_RETURN(-1);
1324  }
1325  r++;
1326 
1327  if (!pOp->isConsistent()) {
1328  g_err << "A node failure has occured and events might be missing\n";
1329  DBUG_RETURN(-1);
1330  }
1331 
1332  int noRetries= 0;
1333  do
1334  {
1335  NdbTransaction *trans= ndb->startTransaction();
1336  if (trans == 0)
1337  {
1338  g_err << "startTransaction failed "
1339  << ndb->getNdbError().code << " "
1340  << ndb->getNdbError().message << endl;
1341  DBUG_RETURN(-1);
1342  }
1343 
1344  NdbOperation *op= trans->getNdbOperation(table);
1345  if (op == 0)
1346  {
1347  g_err << "getNdbOperation failed "
1348  << trans->getNdbError().code << " "
1349  << trans->getNdbError().message << endl;
1350  DBUG_RETURN(-1);
1351  }
1352 
1353  switch (pOp->getEventType()) {
1355  if (op->insertTuple())
1356  {
1357  g_err << "insertTuple "
1358  << op->getNdbError().code << " "
1359  << op->getNdbError().message << endl;
1360  DBUG_RETURN(-1);
1361  }
1362  if (noRetries == 0)
1363  {
1364  n_inserts++;
1365  }
1366  break;
1368  if (op->deleteTuple())
1369  {
1370  g_err << "deleteTuple "
1371  << op->getNdbError().code << " "
1372  << op->getNdbError().message << endl;
1373  DBUG_RETURN(-1);
1374  }
1375  if (noRetries == 0)
1376  {
1377  n_deletes++;
1378  }
1379  break;
1381  if (op->updateTuple())
1382  {
1383  g_err << "updateTuple "
1384  << op->getNdbError().code << " "
1385  << op->getNdbError().message << endl;
1386  DBUG_RETURN(-1);
1387  }
1388  if (noRetries == 0)
1389  {
1390  n_updates++;
1391  }
1392  break;
1393  default:
1394  abort();
1395  }
1396 
1397  {
1398  for (const NdbRecAttr *pk= pOp->getFirstPkAttr();
1399  pk;
1400  pk= pk->next())
1401  {
1402  if (pk->isNULL())
1403  {
1404  g_err << "internal error: primary key isNull()="
1405  << pk->isNULL() << endl;
1406  DBUG_RETURN(NDBT_FAILED);
1407  }
1408  if (op->equal(pk->getColumn()->getColumnNo(),pk->aRef()))
1409  {
1410  g_err << "equal " << pk->getColumn()->getColumnNo() << " "
1411  << op->getNdbError().code << " "
1412  << op->getNdbError().message << endl;
1413  DBUG_RETURN(NDBT_FAILED);
1414  }
1415  }
1416  }
1417 
1418  switch (pOp->getEventType()) {
1420  {
1421  for (const NdbRecAttr *data= pOp->getFirstDataAttr();
1422  data;
1423  data= data->next())
1424  {
1425  if (data->isNULL() < 0 ||
1426  op->setValue(data->getColumn()->getColumnNo(),
1427  data->isNULL() ? 0:data->aRef()))
1428  {
1429  g_err << "setValue(insert) " << data->getColumn()->getColumnNo()
1430  << " " << op->getNdbError().code
1431  << " " << op->getNdbError().message << endl;
1432  DBUG_RETURN(-1);
1433  }
1434  }
1435  break;
1436  }
1438  break;
1440  {
1441  for (const NdbRecAttr *data= pOp->getFirstDataAttr();
1442  data;
1443  data= data->next())
1444  {
1445  if (data->isNULL() >= 0 &&
1446  op->setValue(data->getColumn()->getColumnNo(),
1447  data->isNULL() ? 0:data->aRef()))
1448  {
1449  g_err << "setValue(update) " << data->getColumn()->getColumnNo()
1450  << " " << op->getNdbError().code
1451  << " " << op->getNdbError().message << endl;
1452  DBUG_RETURN(NDBT_FAILED);
1453  }
1454  }
1455  break;
1456  }
1457  default:
1459  abort();
1460  }
1461  if (trans->execute(Commit) == 0)
1462  {
1463  trans->close();
1464  // everything ok
1465  break;
1466  }
1467  if (noRetries++ == 10 ||
1469  {
1470  g_err << "execute " << r << " failed "
1471  << trans->getNdbError().code << " "
1472  << trans->getNdbError().message << endl;
1473  trans->close();
1474  DBUG_RETURN(-1);
1475  }
1476  trans->close();
1477  NdbSleep_MilliSleep(100); // sleep before retying
1478  } while(1);
1479  } // for
1480  } // while(1)
1481  g_info << "n_updates: " << n_updates << " "
1482  << "n_inserts: " << n_inserts << " "
1483  << "n_deletes: " << n_deletes << endl;
1484  DBUG_RETURN(r);
1485 }
1486 
1487 static int verify_copy(Ndb *ndb,
1490 {
1491  for (unsigned i= 0; i < tabs1.size(); i++)
1492  if (tabs1[i])
1493  {
1494  HugoTransactions hugoTrans(*tabs1[i]);
1495  if (hugoTrans.compare(ndb, tabs2[i]->getName(), 0))
1496  return -1;
1497  }
1498  return 0;
1499 }
1500 
1501 static int createEventOperations(Ndb * ndb)
1502 {
1503  DBUG_ENTER("createEventOperations");
1504  int i;
1505 
1506  // creat all event ops
1507  for (i= 0; pTabs[i]; i++)
1508  {
1509  char buf[1024];
1510  sprintf(buf, "%s_EVENT", pTabs[i]->getName());
1511  NdbEventOperation *pOp= ndb->createEventOperation(buf);
1512  if ( pOp == NULL )
1513  {
1514  DBUG_RETURN(NDBT_FAILED);
1515  }
1516 
1517  int n_columns= pTabs[i]->getNoOfColumns();
1518  for (int j = 0; j < n_columns; j++)
1519  {
1520  pOp->getValue(pTabs[i]->getColumn(j)->getName());
1521  pOp->getPreValue(pTabs[i]->getColumn(j)->getName());
1522  }
1523 
1524  if ( pOp->execute() )
1525  {
1526  DBUG_RETURN(NDBT_FAILED);
1527  }
1528  }
1529 
1530  DBUG_RETURN(NDBT_OK);
1531 }
1532 
1533 #if 0
1534 static int createAllEventOperations(NDBT_Context* ctx, NDBT_Step* step)
1535 {
1536  DBUG_ENTER("createAllEventOperations");
1537  Ndb * ndb= GETNDB(step);
1538  int r= createEventOperations(ndb);
1539  if (r != NDBT_OK)
1540  {
1541  DBUG_RETURN(NDBT_FAILED);
1542  }
1543  DBUG_RETURN(NDBT_OK);
1544 }
1545 #endif
1546 
1547 static int dropEventOperations(Ndb * ndb)
1548 {
1549  DBUG_ENTER("dropEventOperations");
1550 
1551  NdbEventOperation *pOp;
1552  while ( (pOp= ndb->getEventOperation()) )
1553  {
1554  if (ndb->dropEventOperation(pOp))
1555  {
1556  DBUG_RETURN(NDBT_FAILED);
1557  }
1558  }
1559 
1560  DBUG_RETURN(NDBT_OK);
1561 }
1562 
1563 #if 0
1564 static int dropAllEventOperations(NDBT_Context* ctx, NDBT_Step* step)
1565 {
1566  DBUG_ENTER("dropAllEventOperations");
1567  Ndb * ndb= GETNDB(step);
1568  int r= dropEventOperations(ndb);
1569  if (r != NDBT_OK)
1570  {
1571  DBUG_RETURN(NDBT_FAILED);
1572  }
1573  DBUG_RETURN(NDBT_OK);
1574 }
1575 #endif
1576 
1577 static int runMulti(NDBT_Context* ctx, NDBT_Step* step)
1578 {
1579  DBUG_ENTER("runMulti");
1580 
1581  Ndb * ndb= GETNDB(step);
1582 
1583  int no_error= 1;
1584  int i;
1585 
1586  if (createEventOperations(ndb))
1587  {
1588  DBUG_RETURN(NDBT_FAILED);
1589  }
1590 
1591  // create a hugo operation per table
1592  Vector<HugoOperations *> hugo_ops;
1593  for (i= 0; no_error && pTabs[i]; i++)
1594  {
1595  hugo_ops.push_back(new HugoOperations(*pTabs[i]));
1596  }
1597 
1598  int n_records= 3;
1599  // insert n_records records per table
1600  do {
1601  if (start_transaction(ndb, hugo_ops))
1602  {
1603  no_error= 0;
1604  DBUG_RETURN(NDBT_FAILED);
1605  }
1606  for (i= 0; no_error && pTabs[i]; i++)
1607  {
1608  hugo_ops[i]->pkInsertRecord(ndb, 0, n_records);
1609  }
1610  if (execute_commit(ndb, hugo_ops))
1611  {
1612  no_error= 0;
1613  DBUG_RETURN(NDBT_FAILED);
1614  }
1615  if(close_transaction(ndb, hugo_ops))
1616  {
1617  no_error= 0;
1618  DBUG_RETURN(NDBT_FAILED);
1619  }
1620  } while(0);
1621 
1622  // copy events and verify
1623  do {
1624  if (copy_events(ndb) < 0)
1625  {
1626  no_error= 0;
1627  DBUG_RETURN(NDBT_FAILED);
1628  }
1629  if (verify_copy(ndb, pTabs, pShadowTabs))
1630  {
1631  no_error= 0;
1632  DBUG_RETURN(NDBT_FAILED);
1633  }
1634  } while (0);
1635 
1636  // update n_records-1 records in first table
1637  do {
1638  if (start_transaction(ndb, hugo_ops))
1639  {
1640  no_error= 0;
1641  DBUG_RETURN(NDBT_FAILED);
1642  }
1643 
1644  hugo_ops[0]->pkUpdateRecord(ndb, n_records-1);
1645 
1646  if (execute_commit(ndb, hugo_ops))
1647  {
1648  no_error= 0;
1649  DBUG_RETURN(NDBT_FAILED);
1650  }
1651  if(close_transaction(ndb, hugo_ops))
1652  {
1653  no_error= 0;
1654  DBUG_RETURN(NDBT_FAILED);
1655  }
1656  } while(0);
1657 
1658  // copy events and verify
1659  do {
1660  if (copy_events(ndb) < 0)
1661  {
1662  no_error= 0;
1663  DBUG_RETURN(NDBT_FAILED);
1664  }
1665  if (verify_copy(ndb, pTabs, pShadowTabs))
1666  {
1667  no_error= 0;
1668  DBUG_RETURN(NDBT_FAILED);
1669  }
1670  } while (0);
1671 
1672  if (dropEventOperations(ndb))
1673  {
1674  DBUG_RETURN(NDBT_FAILED);
1675  }
1676 
1677  if (no_error)
1678  DBUG_RETURN(NDBT_OK);
1679  DBUG_RETURN(NDBT_FAILED);
1680 }
1681 
1682 static int runMulti_NR(NDBT_Context* ctx, NDBT_Step* step)
1683 {
1684  DBUG_ENTER("runMulti");
1685 
1686  int records = ctx->getNumRecords();
1687  int loops = ctx->getNumLoops();
1688  Ndb * ndb= GETNDB(step);
1689 
1690  int i;
1691 
1692  if (createEventOperations(ndb))
1693  {
1694  DBUG_RETURN(NDBT_FAILED);
1695  }
1696 
1697  for (i= 0; pTabs[i]; i++)
1698  {
1699  HugoTransactions hugo(*pTabs[i]);
1700  if (hugo.loadTable(ndb, records, 1, true, 1))
1701  {
1702  DBUG_RETURN(NDBT_FAILED);
1703  }
1704  // copy events and verify
1705  if (copy_events(ndb) < 0)
1706  {
1707  DBUG_RETURN(NDBT_FAILED);
1708  }
1709  }
1710 
1711  if (verify_copy(ndb, pTabs, pShadowTabs))
1712  {
1713  DBUG_RETURN(NDBT_FAILED);
1714  }
1715 
1716  {
1717  NdbRestarts restarts;
1718  for (int j= 0; j < loops; j++)
1719  {
1720  // restart a node
1721  int timeout = 240;
1722  if (restarts.executeRestart(ctx, "RestartRandomNodeAbort", timeout))
1723  {
1724  DBUG_RETURN(NDBT_FAILED);
1725  }
1726 
1727  sleep(5);
1728  // update all tables
1729  for (i= 0; pTabs[i]; i++)
1730  {
1731  HugoTransactions hugo(*pTabs[i]);
1732  if (hugo.pkUpdateRecords(ndb, records, 1, 1))
1733  {
1734  DBUG_RETURN(NDBT_FAILED);
1735  }
1736  if (copy_events(ndb) < 0)
1737  {
1738  DBUG_RETURN(NDBT_FAILED);
1739  }
1740  }
1741 
1742  // copy events and verify
1743  if (verify_copy(ndb, pTabs, pShadowTabs))
1744  {
1745  DBUG_RETURN(NDBT_FAILED);
1746  }
1747  }
1748  }
1749 
1750  if (dropEventOperations(ndb))
1751  {
1752  DBUG_RETURN(NDBT_FAILED);
1753  }
1754 
1755  DBUG_RETURN(NDBT_OK);
1756 }
1757 
1758 typedef Bitmask<(MAX_NDB_NODES + 31) / 32> NdbNodeBitmask;
1759 
1760 static
1761 int
1762 restartNodes(NdbNodeBitmask mask)
1763 {
1764  int cnt = 0;
1765  int nodes[MAX_NDB_NODES];
1766  NdbRestarter res;
1767  for (Uint32 i = 0; i<MAX_NDB_NODES; i++)
1768  {
1769  if (mask.get(i))
1770  {
1771  nodes[cnt++] = i;
1772  res.restartOneDbNode(i, false, true, true);
1776  }
1777  }
1778 
1779  if (res.waitNodesNoStart(nodes, cnt) != 0)
1780  return NDBT_FAILED;
1781 
1782  res.startNodes(nodes, cnt);
1783 
1784  return res.waitClusterStarted();
1785 }
1786 
1787 static int restartAllNodes()
1788 {
1789  NdbRestarter restarter;
1790  NdbNodeBitmask ng;
1791  NdbNodeBitmask nodes0;
1792  NdbNodeBitmask nodes1;
1793 
1798  for (Uint32 i = 0; i<(Uint32)restarter.getNumDbNodes(); i++)
1799  {
1800  int nodeId = restarter.getDbNodeId(i);
1801  if (ng.get(restarter.getNodeGroup(nodeId)) == false)
1802  {
1803  nodes0.set(nodeId);
1804  ng.set(restarter.getNodeGroup(nodeId));
1805  }
1806  else
1807  {
1808  nodes1.set(nodeId);
1809  }
1810  }
1811 
1812  int res;
1813  if ((res = restartNodes(nodes0)) != NDBT_OK)
1814  {
1815  return res;
1816  }
1817 
1818 
1819  res = restartNodes(nodes1);
1820  return res;
1821 }
1822 
1823 static int runCreateDropNR(NDBT_Context* ctx, NDBT_Step* step)
1824 {
1825  DBUG_ENTER("runCreateDropNR");
1826  Ndb * ndb= GETNDB(step);
1827  int result = NDBT_OK;
1828  NdbRestarter restarter;
1829  int loops = ctx->getNumLoops();
1830 
1831  if (restarter.getNumDbNodes() < 2)
1832  {
1833  ctx->stopTest();
1834  return NDBT_OK;
1835  }
1836  NdbDictionary::Table copy(* ctx->getTab());
1837  do
1838  {
1839  const NdbDictionary::Table* pTab =
1840  ndb->getDictionary()->getTable(copy.getName());
1841  result = NDBT_FAILED;
1842  if (createEvent(ndb, *pTab, ctx))
1843  {
1844  g_err << "createEvent failed" << endl;
1845  break;
1846  }
1847  NdbEventOperation *pOp= createEventOperation(ndb, *pTab);
1848  if (pOp == 0)
1849  {
1850  g_err << "Failed to createEventOperation" << endl;
1851  break;
1852  }
1853  if (dropEvent(ndb, *pTab))
1854  {
1855  g_err << "Failed to dropEvent()" << endl;
1856  break;
1857  }
1858  ndbout << "Restarting with dropped events with subscribers" << endl;
1859  if (restartAllNodes())
1860  break;
1861  if (ndb->getDictionary()->dropTable(pTab->getName()) != 0){
1862  g_err << "Failed to drop " << pTab->getName() <<" in db" << endl;
1863  break;
1864  }
1865  ndbout << "Restarting with dropped events and dropped "
1866  << "table with subscribers" << endl;
1867  if (restartAllNodes())
1868  break;
1869  if (ndb->dropEventOperation(pOp))
1870  {
1871  g_err << "Failed dropEventOperation" << endl;
1872  break;
1873  }
1874  //tmp.setNodeGroupIds(0, 0);
1875  if (ndb->getDictionary()->createTable(copy) != 0){
1876  g_err << "createTable failed: "
1877  << ndb->getDictionary()->getNdbError() << endl;
1878  break;
1879  }
1880  result = NDBT_OK;
1881  } while (--loops > 0);
1882 
1883  DBUG_RETURN(result);
1884 }
1885 
1886 static
1887 int
1888 runSubscribeUnsubscribe(NDBT_Context* ctx, NDBT_Step* step)
1889 {
1890  char buf[1024];
1891  const NdbDictionary::Table & tab = * ctx->getTab();
1892  sprintf(buf, "%s_EVENT", tab.getName());
1893  Ndb* ndb = GETNDB(step);
1894  int loops = 5 * ctx->getNumLoops();
1895  int untilStopped = ctx->getProperty("SubscribeUntilStopped", (Uint32)0);
1896 
1897  while ((untilStopped || --loops) && !ctx->isTestStopped())
1898  {
1899  NdbEventOperation *pOp= ndb->createEventOperation(buf);
1900  if (pOp == 0)
1901  {
1902  g_err << "createEventOperation: "
1903  << ndb->getNdbError().code << " "
1904  << ndb->getNdbError().message << endl;
1905  return NDBT_FAILED;
1906  }
1907 
1908  int n_columns= tab.getNoOfColumns();
1909  for (int j = 0; j < n_columns; j++)
1910  {
1911  pOp->getValue(tab.getColumn(j)->getName());
1912  pOp->getPreValue(tab.getColumn(j)->getName());
1913  }
1914  if ( pOp->execute() )
1915  {
1916  g_err << "pOp->execute(): "
1917  << pOp->getNdbError().code << " "
1918  << pOp->getNdbError().message << endl;
1919 
1920  ndb->dropEventOperation(pOp);
1921 
1922  return NDBT_FAILED;
1923  }
1924 
1925  // consume events to make sure dropped events are deleted
1926  if (ndb->pollEvents(0))
1927  {
1928  while (ndb->nextEvent())
1929  ;
1930  }
1931 
1932  if (ndb->dropEventOperation(pOp))
1933  {
1934  g_err << "pOp->execute(): "
1935  << ndb->getNdbError().code << " "
1936  << ndb->getNdbError().message << endl;
1937  return NDBT_FAILED;
1938  }
1939  }
1940 
1941  return NDBT_OK;
1942 }
1943 
1944 int
1945 runLoadTable(NDBT_Context* ctx, NDBT_Step* step)
1946 {
1947  int records = ctx->getNumRecords();
1948  HugoTransactions hugoTrans(*ctx->getTab());
1949  if (hugoTrans.loadTable(GETNDB(step), records) != 0){
1950  return NDBT_FAILED;
1951  }
1952  return NDBT_OK;
1953 }
1954 
1955 int
1956 runScanUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
1957  //int records = ctx->getNumRecords();
1958  int parallelism = ctx->getProperty("Parallelism", (Uint32)0);
1959  int abort = ctx->getProperty("AbortProb", (Uint32)0);
1960  HugoTransactions hugoTrans(*ctx->getTab());
1961  while (ctx->isTestStopped() == false)
1962  {
1963  if (hugoTrans.scanUpdateRecords(GETNDB(step), 0, abort,
1964  parallelism) == NDBT_FAILED){
1965  return NDBT_FAILED;
1966  }
1967  }
1968  return NDBT_OK;
1969 }
1970 
1971 int
1972 runInsertDeleteUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
1973 {
1974  //int result = NDBT_OK;
1975  int records = ctx->getNumRecords();
1976  HugoTransactions hugoTrans(*ctx->getTab());
1977  UtilTransactions utilTrans(*ctx->getTab());
1978  while (ctx->isTestStopped() == false)
1979  {
1980  if (hugoTrans.loadTable(GETNDB(step), records, 1) != 0){
1981  return NDBT_FAILED;
1982  }
1983  if (utilTrans.clearTable(GETNDB(step), records) != 0){
1984  return NDBT_FAILED;
1985  }
1986  }
1987 
1988  return NDBT_OK;
1989 }
1990 
1991 int
1992 runBug31701(NDBT_Context* ctx, NDBT_Step* step)
1993 {
1994  //int result = NDBT_OK;
1995 
1996  NdbRestarter restarter;
1997 
1998  if (restarter.getNumDbNodes() < 2){
1999  ctx->stopTest();
2000  return NDBT_OK;
2001  }
2002  // This should really wait for applier to start...10s is likely enough
2003  NdbSleep_SecSleep(10);
2004 
2005  int nodeId = restarter.getDbNodeId(rand() % restarter.getNumDbNodes());
2006 
2007  int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
2008  if (restarter.dumpStateOneNode(nodeId, val2, 2))
2009  return NDBT_FAILED;
2010 
2011  restarter.insertErrorInNode(nodeId, 13033);
2012  if (restarter.waitNodesNoStart(&nodeId, 1))
2013  return NDBT_FAILED;
2014 
2015  if (restarter.startNodes(&nodeId, 1))
2016  return NDBT_FAILED;
2017 
2018  if (restarter.waitClusterStarted())
2019  return NDBT_FAILED;
2020 
2021 
2022  int records = ctx->getNumRecords();
2023  HugoTransactions hugoTrans(*ctx->getTab());
2024 
2025  if(ctx->getPropertyWait("LastGCI_hi", ~(Uint32)0))
2026  {
2027  g_err << "FAIL " << __LINE__ << endl;
2028  return NDBT_FAILED;
2029  }
2030 
2031  hugoTrans.clearTable(GETNDB(step), 0);
2032 
2033  if (hugoTrans.loadTable(GETNDB(step), 3*records, 1, true, 1) != 0){
2034  g_err << "FAIL " << __LINE__ << endl;
2035  return NDBT_FAILED;
2036  }
2037 
2038  if (hugoTrans.pkDelRecords(GETNDB(step), 3*records, 1, true, 1) != 0){
2039  g_err << "FAIL " << __LINE__ << endl;
2040  return NDBT_FAILED;
2041  }
2042  if (hugoTrans.loadTable(GETNDB(step), records, 1, true, 1) != 0){
2043  g_err << "FAIL " << __LINE__ << endl;
2044  return NDBT_FAILED;
2045  }
2046  if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, 1) != 0){
2047  g_err << "FAIL " << __LINE__ << endl;
2048  return NDBT_FAILED;
2049  }
2050  if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, 1) != 0){
2051  g_err << "FAIL " << __LINE__ << endl;
2052  return NDBT_FAILED;
2053  }
2054  if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, 1) != 0){
2055  g_err << "FAIL " << __LINE__ << endl;
2056  return NDBT_FAILED;
2057  }
2058 
2059  ctx->setProperty("LastGCI_lo", Uint32(hugoTrans.m_latest_gci));
2060  ctx->setProperty("LastGCI_hi", Uint32(hugoTrans.m_latest_gci >> 32));
2061  if(ctx->getPropertyWait("LastGCI_hi", ~(Uint32)0))
2062  {
2063  g_err << "FAIL " << __LINE__ << endl;
2064  return NDBT_FAILED;
2065  }
2066 
2067  ctx->stopTest();
2068  return NDBT_OK;
2069 }
2070 
2071 int
2072 errorInjectBufferOverflow(NDBT_Context* ctx, NDBT_Step* step)
2073 {
2074  Ndb * ndb= GETNDB(step);
2075  NdbRestarter restarter;
2076  const NdbDictionary::Table* pTab = ctx->getTab();
2077  int result= NDBT_OK;
2078  int res;
2079  bool found_gap = false;
2080  NdbEventOperation *pOp= createEventOperation(ndb, *pTab);
2081  Uint64 gci;
2082 
2083  if (pOp == 0)
2084  {
2085  g_err << "Failed to createEventOperation" << endl;
2086  return NDBT_FAILED;
2087  }
2088 
2089  if (restarter.insertErrorInAllNodes(13036) != 0)
2090  {
2091  result = NDBT_FAILED;
2092  goto cleanup;
2093  }
2094 
2095  res = ndb->pollEvents(5000);
2096 
2097  if (ndb->getNdbError().code != 0)
2098  {
2099  g_err << "pollEvents failed: \n";
2100  g_err << ndb->getNdbError().code << " "
2101  << ndb->getNdbError().message << endl;
2102  result = (ndb->getNdbError().code == 4720)?NDBT_OK:NDBT_FAILED;
2103  goto cleanup;
2104  }
2105  if (res >= 0) {
2106  NdbEventOperation *tmp;
2107  while (!found_gap && (tmp= ndb->nextEvent()))
2108  {
2109  if (!ndb->isConsistent(gci))
2110  found_gap = true;
2111  }
2112  }
2113  if (!ndb->isConsistent(gci))
2114  found_gap = true;
2115  if (!found_gap)
2116  {
2117  g_err << "buffer overflow not detected\n";
2118  result = NDBT_FAILED;
2119  goto cleanup;
2120  }
2121 
2122 cleanup:
2123 
2124  if (ndb->dropEventOperation(pOp) != 0) {
2125  g_err << "dropping event operation failed\n";
2126  result = NDBT_FAILED;
2127  }
2128 
2129  return result;
2130 }
2131 
2132 int
2133 errorInjectStalling(NDBT_Context* ctx, NDBT_Step* step)
2134 {
2135  Ndb * ndb= GETNDB(step);
2136  NdbRestarter restarter;
2137  const NdbDictionary::Table* pTab = ctx->getTab();
2138  NdbEventOperation *pOp= createEventOperation(ndb, *pTab);
2139  int result = NDBT_OK;
2140  int res;
2141  bool connected = true;
2142 
2143  if (pOp == 0)
2144  {
2145  g_err << "Failed to createEventOperation" << endl;
2146  return NDBT_FAILED;
2147  }
2148 
2149  if (restarter.insertErrorInAllNodes(13037) != 0)
2150  {
2151  result = NDBT_FAILED;
2152  goto cleanup;
2153  }
2154 
2155  res = ndb->pollEvents(5000) > 0;
2156 
2157  if (ndb->getNdbError().code != 0)
2158  {
2159  g_err << "pollEvents failed: \n";
2160  g_err << ndb->getNdbError().code << " "
2161  << ndb->getNdbError().message << endl;
2162  result = NDBT_FAILED;
2163  goto cleanup;
2164  }
2165 
2166  if (res > 0) {
2167  NdbEventOperation *tmp;
2168  int count = 0;
2169  while (connected && (tmp= ndb->nextEvent()))
2170  {
2171  if (tmp != pOp)
2172  {
2173  printf("Found stray NdbEventOperation\n");
2174  result = NDBT_FAILED;
2175  goto cleanup;
2176  }
2177  switch (tmp->getEventType()) {
2179  connected = false;
2180  break;
2181  default:
2182  count++;
2183  break;
2184  }
2185  }
2186  if (connected)
2187  {
2188  g_err << "failed to detect cluster disconnect\n";
2189  result = NDBT_FAILED;
2190  goto cleanup;
2191  }
2192  }
2193 
2194 cleanup:
2195 
2196  if (ndb->dropEventOperation(pOp) != 0) {
2197  g_err << "dropping event operation failed\n";
2198  result = NDBT_FAILED;
2199  }
2200 
2201  // Reconnect by trying to start a transaction
2202  uint retries = 100;
2203  while (!connected && retries--)
2204  {
2205  HugoTransactions hugoTrans(* ctx->getTab());
2206  if (hugoTrans.loadTable(ndb, 100) == 0)
2207  {
2208  connected = true;
2209  result = NDBT_OK;
2210  }
2211  else
2212  {
2213  NdbSleep_MilliSleep(300);
2214  result = NDBT_FAILED;
2215  }
2216  }
2217 
2218  if (!connected)
2219  g_err << "Failed to reconnect\n";
2220 
2221  // Restart cluster with abort
2222  if (restarter.restartAll(false, false, true) != 0){
2223  ctx->stopTest();
2224  return NDBT_FAILED;
2225  }
2226 
2227  // Stop the other thread
2228  ctx->stopTest();
2229 
2230  if (restarter.waitClusterStarted(300) != 0){
2231  return NDBT_FAILED;
2232  }
2233 
2234  if (ndb->waitUntilReady() != 0){
2235  return NDBT_FAILED;
2236  }
2237 
2238  return result;
2239 }
2240 int
2241 runBug33793(NDBT_Context* ctx, NDBT_Step* step)
2242 {
2243  //int result = NDBT_OK;
2244  int loops = ctx->getNumLoops();
2245 
2246  NdbRestarter restarter;
2247 
2248  if (restarter.getNumDbNodes() < 2){
2249  ctx->stopTest();
2250  return NDBT_OK;
2251  }
2252  // This should really wait for applier to start...10s is likely enough
2253  NdbSleep_SecSleep(10);
2254 
2255  while (loops-- && ctx->isTestStopped() == false)
2256  {
2257  int nodeId = restarter.getDbNodeId(rand() % restarter.getNumDbNodes());
2258  int nodecount = 0;
2259  int nodes[255];
2260  printf("nodeid: %u : victims: ", nodeId);
2261  for (int i = 0; i<restarter.getNumDbNodes(); i++)
2262  {
2263  int id = restarter.getDbNodeId(i);
2264  if (id == nodeId)
2265  continue;
2266 
2267  if (restarter.getNodeGroup(id) == restarter.getNodeGroup(nodeId))
2268  {
2269  nodes[nodecount++] = id;
2270  printf("%u ", id);
2271  int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
2272  if (restarter.dumpStateOneNode(id, val2, 2))
2273  return NDBT_FAILED;
2274  }
2275  }
2276  printf("\n"); fflush(stdout);
2277 
2278  restarter.insertErrorInNode(nodeId, 13034);
2279  if (restarter.waitNodesNoStart(nodes, nodecount))
2280  return NDBT_FAILED;
2281 
2282  if (restarter.startNodes(nodes, nodecount))
2283  return NDBT_FAILED;
2284 
2285  if (restarter.waitClusterStarted())
2286  return NDBT_FAILED;
2287  }
2288 
2289  ctx->stopTest();
2290  return NDBT_OK;
2291 }
2292 
2293 static
2294 int
2295 cc(Ndb_cluster_connection** ctx, Ndb** ndb)
2296 {
2298  int ret;
2299  if ((ret = xncc->connect(30, 1, 0)) != 0)
2300  {
2301  delete xncc;
2302  return NDBT_FAILED;
2303  }
2304 
2305  if ((ret = xncc->wait_until_ready(30, 10)) != 0)
2306  {
2307  delete xncc;
2308  return NDBT_FAILED;
2309  }
2310 
2311  Ndb* xndb = new Ndb(xncc, "TEST_DB");
2312  if (xndb->init() != 0)
2313  {
2314  delete xndb;
2315  delete xncc;
2316  return NDBT_FAILED;
2317  }
2318 
2319  if (xndb->waitUntilReady(30) != 0)
2320  {
2321  delete xndb;
2322  delete xncc;
2323  return NDBT_FAILED;
2324  }
2325 
2326  * ctx = xncc;
2327  * ndb = xndb;
2328  return 0;
2329 }
2330 
2331 static
2333 op(Ndb* xndb, const NdbDictionary::Table * table)
2334 {
2335  char buf[1024];
2336  sprintf(buf, "%s_EVENT", table->getName());
2337  NdbEventOperation *pOp;
2338  pOp = xndb->createEventOperation(buf);
2339  if ( pOp == NULL )
2340  {
2341  g_err << "Event operation creation failed on %s" << buf << endl;
2342  return 0;
2343  }
2344 
2345  int n_columns= table->getNoOfColumns();
2346  NdbRecAttr* recAttr[1024];
2347  NdbRecAttr* recAttrPre[1024];
2348  for (int i = 0; i < n_columns; i++) {
2349  recAttr[i] = pOp->getValue(table->getColumn(i)->getName());
2350  recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
2351  }
2352 
2353  return pOp;
2354 }
2355 
2356 int
2357 runBug34853(NDBT_Context* ctx, NDBT_Step* step)
2358 {
2359  //int result = NDBT_OK;
2360  //int loops = ctx->getNumLoops();
2361  //int records = ctx->getNumRecords();
2362  //Ndb* pNdb = GETNDB(step);
2363  NdbRestarter res;
2364 
2365  if (res.getNumDbNodes() < 2)
2366  {
2367  return NDBT_OK;
2368  }
2369 
2370  Ndb_cluster_connection* xncc;
2371  Ndb* xndb;
2372 
2373  if (cc(&xncc, &xndb))
2374  {
2375  return NDBT_FAILED;
2376  }
2377 
2378  NdbEventOperation* pOp = op(xndb, ctx->getTab());
2379  if (pOp == 0)
2380  {
2381  delete xndb;
2382  delete xncc;
2383  return NDBT_FAILED;
2384  }
2385 
2386  int api = xncc->node_id();
2387  int nodeId = res.getDbNodeId(rand() % res.getNumDbNodes());
2388  ndbout_c("stopping %u", nodeId);
2389  res.restartOneDbNode(nodeId, false, true, true);
2393 
2394  ndbout_c("waiting for %u", nodeId);
2395  res.waitNodesNoStart(&nodeId, 1);
2396 
2397  int dump[2];
2398  dump[0] = 9004;
2399  dump[1] = api;
2400  res.dumpStateOneNode(nodeId, dump, 2);
2401  res.startNodes(&nodeId, 1);
2402  ndbout_c("waiting cluster");
2403  res.waitClusterStarted();
2404 
2405  if (pOp->execute())
2406  { // This starts changes to "start flowing"
2407  g_err << "execute operation execution failed: \n";
2408  g_err << pOp->getNdbError().code << " "
2409  << pOp->getNdbError().message << endl;
2410  delete xndb;
2411  delete xncc;
2412  return NDBT_FAILED;
2413  }
2414 
2415  xndb->dropEventOperation(pOp);
2416 
2417  ndbout_c("stopping %u", nodeId);
2418  res.restartOneDbNode(nodeId, false, true, true);
2422 
2423  ndbout_c("waiting for %u", nodeId);
2424  res.waitNodesNoStart(&nodeId, 1);
2425 
2426  dump[0] = 71;
2427  dump[1] = 7;
2428  res.dumpStateOneNode(nodeId, dump, 2);
2429  res.startNodes(&nodeId, 1);
2430  ndbout_c("waiting node sp 7");
2431  res.waitNodesStartPhase(&nodeId, 1, 6);
2432 
2433  delete xndb;
2434  delete xncc;
2435 
2436  NdbSleep_SecSleep(5); // 3 seconds to open connections. i.e 5 > 3
2437 
2438  dump[0] = 71;
2439  res.dumpStateOneNode(nodeId, dump, 1);
2440 
2441  res.waitClusterStarted();
2442 
2443  if (cc(&xncc, &xndb))
2444  {
2445  return NDBT_FAILED;
2446  }
2447 
2448  pOp = op(xndb, ctx->getTab());
2449  if (pOp == 0)
2450  {
2451  delete xndb;
2452  delete xncc;
2453  return NDBT_FAILED;
2454  }
2455 
2456  if (pOp->execute())
2457  { // This starts changes to "start flowing"
2458  g_err << "execute operation execution failed: \n";
2459  g_err << pOp->getNdbError().code << " "
2460  << pOp->getNdbError().message << endl;
2461  delete xndb;
2462  delete xncc;
2463  return NDBT_FAILED;
2464  }
2465 
2466  xndb->dropEventOperation(pOp);
2467  delete xndb;
2468  delete xncc;
2469  return NDBT_OK;
2470 }
2471 
2474 int
2475 runNFSubscribe(NDBT_Context* ctx, NDBT_Step* step)
2476 {
2477  NdbRestarter restarter;
2478 
2479  if (restarter.getNumDbNodes() < 2)
2480  {
2481  ctx->stopTest();
2482  return NDBT_OK;
2483  }
2484 
2485  int codes[] = {
2486  6023, (int)NdbRestarter::NS_NON_MASTER,
2487  13013, (int)NdbRestarter::NS_RANDOM,
2488  13019, (int)NdbRestarter::NS_RANDOM,
2489  13020, (int)NdbRestarter::NS_RANDOM,
2490  13041, (int)NdbRestarter::NS_RANDOM,
2491  0
2492  };
2493 
2494  int nr_codes[] = {
2495  13039,
2496  13040,
2497  13042,
2498  0
2499  };
2500 
2501  int loops = ctx->getNumLoops();
2502  while (loops-- && !ctx->isTestStopped())
2503  {
2504  int i = 0;
2505  while (codes[i] != 0)
2506  {
2507  int code = codes[i++];
2508  int nodeId = restarter.getNode((NdbRestarter::NodeSelector)codes[i++]);
2509  int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
2510  if (restarter.dumpStateOneNode(nodeId, val2, 2))
2511  return NDBT_FAILED;
2512 
2513  ndbout_c("Node %u error: %u", nodeId, code);
2514  if (restarter.insertErrorInNode(nodeId, code))
2515  return NDBT_FAILED;
2516 
2517  if (restarter.waitNodesNoStart(&nodeId, 1))
2518  return NDBT_FAILED;
2519 
2520  if (restarter.startNodes(&nodeId, 1))
2521  return NDBT_FAILED;
2522 
2523  if (restarter.waitClusterStarted())
2524  return NDBT_FAILED;
2525  }
2526 
2527  int nodeId = restarter.getDbNodeId(rand() % restarter.getNumDbNodes());
2528  if (restarter.restartOneDbNode(nodeId, false, true, true) != 0)
2529  return NDBT_FAILED;
2530 
2531  if (restarter.waitNodesNoStart(&nodeId, 1))
2532  return NDBT_FAILED;
2533 
2534  i = 0;
2535  while (nr_codes[i] != 0)
2536  {
2537  int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
2538  if (restarter.dumpStateOneNode(nodeId, val2, 2))
2539  return NDBT_FAILED;
2540 
2541  ndbout_c("Node %u error: %u", nodeId, nr_codes[i]);
2542  if (restarter.insertErrorInNode(nodeId, nr_codes[i]))
2543  return NDBT_FAILED;
2544 
2545  if (restarter.startNodes(&nodeId, 1))
2546  return NDBT_FAILED;
2547 
2548  NdbSleep_SecSleep(3);
2549 
2550  if (restarter.waitNodesNoStart(&nodeId, 1))
2551  return NDBT_FAILED;
2552 
2553  i++;
2554  }
2555 
2556  ndbout_c("Done..now starting %u", nodeId);
2557  if (restarter.startNodes(&nodeId, 1))
2558  return NDBT_FAILED;
2559 
2560  if (restarter.waitClusterStarted())
2561  return NDBT_FAILED;
2562  }
2563 
2564  ctx->stopTest();
2565  return NDBT_OK;
2566 }
2567 
2568 int
2569 runBug35208_createTable(NDBT_Context* ctx, NDBT_Step* step)
2570 {
2571  NdbDictionary::Table tab = *ctx->getTab();
2572 
2573  while (tab.getNoOfColumns() < 100)
2574  {
2575  BaseString name;
2577  name.assfmt("COL_%d", tab.getNoOfColumns());
2578  col.setName(name.c_str());
2580  col.setLength(1);
2581  col.setNullable(false);
2582  col.setPrimaryKey(false);
2583  tab.addColumn(col);
2584  }
2585 
2586  NdbDictionary::Dictionary* dict = GETNDB(step)->getDictionary();
2587  dict->dropTable(tab.getName());
2588  dict->createTable(tab);
2589 
2590  const NdbDictionary::Table* pTab = dict->getTable(tab.getName());
2591  ctx->setTab(pTab);
2592 
2593  return NDBT_OK;
2594 }
2595 
2596 #define UPDATE_COL 66
2597 
2598 int
2599 runBug35208(NDBT_Context* ctx, NDBT_Step* step)
2600 {
2601  Ndb* ndb= GETNDB(step);
2602  const NdbDictionary::Table * table= ctx->getTab();
2603 
2604  char buf[1024];
2605  sprintf(buf, "%s_EVENT", table->getName());
2606  NdbEventOperation *pOp = ndb->createEventOperation(buf);
2607  if ( pOp == NULL ) {
2608  g_err << "Event operation creation failed on %s" << buf << endl;
2609  return NDBT_FAILED;
2610  }
2611 
2612  int result = NDBT_OK;
2613  HugoTransactions hugoTrans(* table);
2614 
2615  char col[100];
2616  BaseString::snprintf(col, sizeof(col), "COL_%u", UPDATE_COL);
2617 
2618  int i;
2619  int n_columns= table->getNoOfColumns();
2620  NdbRecAttr* recAttr[1024];
2621  NdbRecAttr* recAttrPre[1024];
2622  for (i = 0; i < n_columns; i++) {
2623  recAttr[i] = pOp->getValue(table->getColumn(i)->getName());
2624  recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
2625  }
2626 
2627  if (pOp->execute())
2628  { // This starts changes to "start flowing"
2629  g_err << "execute operation execution failed: \n";
2630  g_err << pOp->getNdbError().code << " "
2631  << pOp->getNdbError().message << endl;
2632  goto err;
2633  }
2634 
2635  hugoTrans.loadTable(GETNDB(step), ctx->getNumRecords());
2636 
2637  for (int i = 0; i<ctx->getNumLoops(); i++)
2638  {
2639  ndbout_c("testing %u updates", (i + 1));
2640  NdbTransaction* pTrans = ndb->startTransaction();
2641  for (int m = 0; m<(i+1); m++)
2642  {
2643  for (int r = 0; r<ctx->getNumRecords(); r++)
2644  {
2645  NdbOperation* pOp = pTrans->getNdbOperation(table->getName());
2646  pOp->updateTuple();
2647  HugoOperations hop(* table);
2648  hop.equalForRow(pOp, r);
2649  pOp->setValue(col, rand());
2650  }
2651  if (pTrans->execute(NoCommit) != 0)
2652  {
2653  ndbout << pTrans->getNdbError() << endl;
2654  goto err;
2655  }
2656  }
2657  if (pTrans->execute(Commit) != 0)
2658  {
2659  ndbout << pTrans->getNdbError() << endl;
2660  goto err;
2661  }
2662 
2663  Uint64 gci;
2664  pTrans->getGCI(&gci);
2665  ndbout_c("set(LastGCI_hi): %u/%u",
2666  Uint32(gci >> 32),
2667  Uint32(gci));
2668  ctx->setProperty("LastGCI_lo", Uint32(gci));
2669  ctx->setProperty("LastGCI_hi", Uint32(gci >> 32));
2670  if(ctx->getPropertyWait("LastGCI_hi", ~(Uint32)0))
2671  {
2672  g_err << "FAIL " << __LINE__ << endl;
2673  goto err;
2674  }
2675 
2676  Uint32 bug = 0;
2677  Uint32 cnt = 0;
2678  Uint64 curr_gci = 0;
2679  while(curr_gci <= gci)
2680  {
2681  ndb->pollEvents(100, &curr_gci);
2682  NdbEventOperation* tmp = 0;
2683  while ((tmp= ndb->nextEvent()) != 0)
2684  {
2686  {
2687  cnt++;
2688  bool first = true;
2689  for (int c = 0; c<table->getNoOfColumns(); c++)
2690  {
2691  if (recAttr[c]->isNULL() >= 0)
2692  {
2696  if (c != UPDATE_COL &&
2697  table->getColumn(c)->getPrimaryKey() == false)
2698  {
2699  bug++;
2700  if (first)
2701  {
2702  first = false;
2703  printf("Detect (incorrect) update value for: ");
2704  }
2705  printf("%u ", c);
2706  result = NDBT_FAILED;
2707  }
2708  }
2709  }
2710  if (!first)
2711  printf("\n");
2712  }
2713  }
2714  }
2715  ndbout_c("found %u updates bugs: %u", cnt, bug);
2716  }
2717 
2718  ndb->dropEventOperation(pOp);
2719  ctx->stopTest();
2720 
2721  return result;
2722 
2723 err:
2724  ndb->dropEventOperation(pOp);
2725 
2726  return NDBT_FAILED;
2727 }
2728 
2729 
2730 
2733 int
2734 runBug37279(NDBT_Context* ctx, NDBT_Step* step)
2735 {
2736  NdbRestarter res;
2737  if (res.getNumDbNodes() < 2)
2738  {
2739  ctx->stopTest();
2740  return NDBT_OK;
2741  }
2742 
2743  if (runCreateEvent(ctx, step))
2744  {
2745  return NDBT_FAILED;
2746  }
2747 
2748  Ndb* pNdb = GETNDB(step);
2749  NdbDictionary::Dictionary* dict = pNdb->getDictionary();
2750 
2751  const NdbDictionary::Table* tab = dict->getTable(ctx->getTab()->getName());
2752  //const NdbDictionary::Table* org = tab;
2753  NdbEventOperation* pOp0 = createEventOperation(pNdb, *tab);
2754 
2755  if (pOp0 == 0)
2756  {
2757  return NDBT_FAILED;
2758  }
2759 
2760  {
2761  Ndb* ndb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
2762  if (ndb->init() != 0)
2763  {
2764  delete ndb;
2765  ndbout_c("here: %u", __LINE__);
2766  return NDBT_FAILED;
2767  }
2768 
2769  if (ndb->waitUntilReady(30) != 0)
2770  {
2771  delete ndb;
2772  ndbout_c("here: %u", __LINE__);
2773  return NDBT_FAILED;
2774  }
2775 
2776  ndb->getDictionary()->dropTable(tab->getName());
2777  delete ndb;
2778  }
2779 
2780  int nodeId = res.getDbNodeId(rand() % res.getNumDbNodes());
2781  ndbout_c("stopping %u", nodeId);
2782  res.restartOneDbNode(nodeId, false, false, true);
2786  if (res.waitClusterStarted())
2787  {
2788  return NDBT_FAILED;
2789  }
2790 
2791  pNdb->dropEventOperation(pOp0);
2792  runDropEvent(ctx, step);
2793 
2794  return NDBT_OK;
2795 }
2796 
2797 int
2798 runBug37338(NDBT_Context* ctx, NDBT_Step* step)
2799 {
2800  NdbRestarter res;
2801  if (res.getNumDbNodes() < 2)
2802  {
2803  ctx->stopTest();
2804  return NDBT_OK;
2805  }
2806 
2807  int nodeId = res.getDbNodeId(rand() % res.getNumDbNodes());
2808 
2809  Ndb* pNdb = GETNDB(step);
2810  NdbDictionary::Dictionary* dict = pNdb->getDictionary();
2811  const NdbDictionary::Table* tab = dict->getTable(ctx->getTab()->getName());
2812 
2813  const char * name = "BugXXX";
2814  NdbDictionary::Table copy = * tab;
2815  copy.setName(name);
2816  dict->dropTable(name);
2817 
2818  for (int i = 0; i<ctx->getNumLoops(); i++)
2819  {
2820  Ndb* ndb0;
2821  Ndb_cluster_connection *con0;
2822  NdbEventOperation* pOp0;
2823  NdbDictionary::Dictionary * dict0;
2824 
2825  cc(&con0, &ndb0);
2826  dict0 = ndb0->getDictionary();
2827  if (dict0->createTable(copy) != 0)
2828  {
2829  ndbout << dict0->getNdbError() << endl;
2830  return NDBT_FAILED;
2831  }
2832 
2833  const NdbDictionary::Table * copyptr = dict0->getTable(name);
2834  if (copyptr == 0)
2835  {
2836  return NDBT_FAILED;
2837  }
2838  createEvent(ndb0, *copyptr, ctx);
2839  pOp0 = createEventOperation(ndb0, *copyptr);
2840  dict0 = ndb0->getDictionary();dict->dropTable(name);
2841 
2842  res.restartOneDbNode(nodeId, false, true, true);
2846 
2847  res.waitNodesNoStart(&nodeId, 1);
2848  res.startNodes(&nodeId, 1);
2849  if (res.waitClusterStarted())
2850  {
2851  return NDBT_FAILED;
2852  }
2853 
2854  ndb0->dropEventOperation(pOp0);
2855 
2856  delete ndb0;
2857  delete con0;
2858  }
2859 
2860  return NDBT_OK;
2861 }
2862 
2863 int
2864 runBug37442(NDBT_Context* ctx, NDBT_Step* step)
2865 {
2866  NdbRestarter res;
2867  if (res.getNumDbNodes() < 2)
2868  {
2869  ctx->stopTest();
2870  return NDBT_OK;
2871  }
2872 
2873  int nodeId = res.getDbNodeId(rand() % res.getNumDbNodes());
2874 
2875  Ndb* pNdb = GETNDB(step);
2876  NdbDictionary::Dictionary* dict = pNdb->getDictionary();
2877  const NdbDictionary::Table* tab = dict->getTable(ctx->getTab()->getName());
2878 
2879  if (runCreateEvent(ctx, step))
2880  {
2881  return NDBT_FAILED;
2882  }
2883 
2884  for (int i = 0; i<ctx->getNumLoops(); i++)
2885  {
2886  NdbEventOperation * pOp = createEventOperation(GETNDB(step), *tab);
2887 
2888  res.restartOneDbNode(nodeId, false, true, true);
2892 
2893  res.waitNodesNoStart(&nodeId, 1);
2894 
2895  GETNDB(step)->dropEventOperation(pOp);
2896 
2897  res.startNodes(&nodeId, 1);
2898  if (res.waitClusterStarted())
2899  {
2900  return NDBT_FAILED;
2901  }
2902  }
2903 
2904  runDropEvent(ctx, step);
2905 
2906  return NDBT_OK;
2907 }
2908 
2909 const NdbDictionary::Table* createBoringTable(const char* name, Ndb* pNdb)
2910 {
2912 
2913  tab.setName(name);
2914 
2916  pk.setName("Key");
2918  pk.setLength(1);
2919  pk.setNullable(false);
2920  pk.setPrimaryKey(true);
2921  tab.addColumn(pk);
2922 
2923  NdbDictionary::Column attr;
2924  attr.setName("Attr");
2926  attr.setLength(1);
2927  attr.setNullable(true);
2928  attr.setPrimaryKey(false);
2929  tab.addColumn(attr);
2930 
2931  pNdb->getDictionary()->dropTable(tab.getName());
2932  if(pNdb->getDictionary()->createTable(tab) == 0)
2933  {
2934  ndbout << (NDBT_Table&)tab << endl;
2935  return pNdb->getDictionary()->getTable(tab.getName());
2936  }
2937 
2938  ndbout << "Table create failed, err : " <<
2939  pNdb->getDictionary()->getNdbError().code << endl;
2940 
2941  return NULL;
2942 }
2943 
2944 /* Types of operation which can be tagged via 'setAnyValue */
2945 enum OpTypes {Insert, Update, Write, Delete, EndOfOpTypes};
2946 
2953 int
2954 executeOps(Ndb* pNdb,
2955  const NdbDictionary::Table* tab,
2956  OpTypes op,
2957  Uint32 rowCount,
2958  Uint32 keyOffset,
2959  Uint32 anyValueOffset,
2961 {
2962  NdbTransaction* trans= pNdb->startTransaction();
2963  const NdbRecord* record= tab->getDefaultRecord();
2964 
2965  char RowBuf[16];
2966  Uint32* keyPtr= (Uint32*) NdbDictionary::getValuePtr(record,
2967  RowBuf,
2968  0);
2969  Uint32* attrPtr= (Uint32*) NdbDictionary::getValuePtr(record,
2970  RowBuf,
2971  1);
2972 
2973  for (Uint32 i=keyOffset; i < (keyOffset + rowCount); i++)
2974  {
2975  memcpy(keyPtr, &i, sizeof(i));
2976  memcpy(attrPtr, &i, sizeof(i));
2977  opts.optionsPresent |= NdbOperation::OperationOptions::OO_ANYVALUE;
2978  opts.anyValue= anyValueOffset + i;
2979  bool allowInterpreted=
2980  (op == Update) ||
2981  (op == Delete);
2982 
2983  if (!allowInterpreted)
2984  opts.optionsPresent &=
2985  ~ (Uint64) NdbOperation::OperationOptions::OO_INTERPRETED;
2986 
2987  switch (op) {
2988  case Insert :
2989  if (trans->insertTuple(record,
2990  RowBuf,
2991  NULL,
2992  &opts,
2993  sizeof(opts)) == NULL)
2994  {
2995  g_err << "Can't create operation : " <<
2996  trans->getNdbError().code << endl;
2997  return NDBT_FAILED;
2998  }
2999  break;
3000  case Update :
3001  if (trans->updateTuple(record,
3002  RowBuf,
3003  record,
3004  RowBuf,
3005  NULL,
3006  &opts,
3007  sizeof(opts)) == NULL)
3008  {
3009  g_err << "Can't create operation : " <<
3010  trans->getNdbError().code << endl;
3011  return NDBT_FAILED;
3012  }
3013  break;
3014  case Write :
3015  if (trans->writeTuple(record,
3016  RowBuf,
3017  record,
3018  RowBuf,
3019  NULL,
3020  &opts,
3021  sizeof(opts)) == NULL)
3022  {
3023  g_err << "Can't create operation : " <<
3024  trans->getNdbError().code << endl;
3025  return NDBT_FAILED;
3026  }
3027  break;
3028  case Delete :
3029  if (trans->deleteTuple(record,
3030  RowBuf,
3031  record,
3032  NULL,
3033  NULL,
3034  &opts,
3035  sizeof(opts)) == NULL)
3036  {
3037  g_err << "Can't create operation : " <<
3038  trans->getNdbError().code << endl;
3039  return NDBT_FAILED;
3040  }
3041  break;
3042  default:
3043  g_err << "Bad operation type : " << op << endl;
3044  return NDBT_FAILED;
3045  }
3046  }
3047 
3048  trans->execute(Commit);
3049 
3050  if (trans->getNdbError().code != 0)
3051  {
3052  g_err << "Error executing operations :" <<
3053  trans->getNdbError().code << endl;
3054  return NDBT_FAILED;
3055  }
3056 
3057  trans->close();
3058 
3059  return NDBT_OK;
3060 }
3061 
3062 int
3063 checkAnyValueInEvent(Ndb* pNdb,
3064  NdbRecAttr* preKey,
3065  NdbRecAttr* postKey,
3066  NdbRecAttr* preAttr,
3067  NdbRecAttr* postAttr,
3068  Uint32 num,
3069  Uint32 anyValueOffset,
3070  bool checkPre)
3071 {
3072  Uint32 received= 0;
3073 
3074  while (received < num)
3075  {
3076  int pollRc;
3077 
3078  if ((pollRc= pNdb->pollEvents(10000)) < 0)
3079  {
3080  g_err << "Error while polling for events : " <<
3081  pNdb->getNdbError().code;
3082  return NDBT_FAILED;
3083  }
3084 
3085  if (pollRc == 0)
3086  {
3087  printf("No event, waiting...\n");
3088  continue;
3089  }
3090 
3092  while((event= pNdb->nextEvent()) != NULL)
3093  {
3094 // printf("Event is %p of type %u\n",
3095 // event, event->getEventType());
3096 // printf("Got event, prekey is %u predata is %u \n",
3097 // preKey->u_32_value(),
3098 // preAttr->u_32_value());
3099 // printf(" postkey is %u postdata is %u anyvalue is %u\n",
3100 // postKey->u_32_value(),
3101 // postAttr->u_32_value(),
3102 // event->getAnyValue());
3103 
3104  received ++;
3105  Uint32 keyVal= (checkPre?
3106  preKey->u_32_value() :
3107  postKey->u_32_value());
3108 
3109  if (event->getAnyValue() !=
3110  (anyValueOffset + keyVal))
3111  {
3112  g_err << "Error : Got event, key is " <<
3113  keyVal << " anyValue is " <<
3114  event->getAnyValue() <<
3115  " expected " << (anyValueOffset + keyVal)
3116  << endl;
3117  return NDBT_FAILED;
3118  }
3119  }
3120  }
3121 
3122  return NDBT_OK;
3123 }
3124 
3125 
3126 
3127 int
3128 runBug37672(NDBT_Context* ctx, NDBT_Step* step)
3129 {
3130  /* InterpretedDelete and setAnyValue failed */
3131  /* Let's create a boring, known table for this since
3132  * we don't yet have Hugo tools for NdbRecord
3133  */
3134  BaseString name;
3135  name.assfmt("TAB_TESTEVENT%d", rand() & 65535);
3136  Ndb* pNdb= GETNDB(step);
3137 
3138  const NdbDictionary::Table* tab= createBoringTable(name.c_str(), pNdb);
3139 
3140  if (tab == NULL)
3141  return NDBT_FAILED;
3142 
3143  /* Create an event to listen to events on the table */
3144  char eventName[1024];
3145  sprintf(eventName,"%s_EVENT", tab->getName());
3146 
3147  if (createEvent(pNdb, *tab, false, true) != 0)
3148  return NDBT_FAILED;
3149 
3150  /* Now create the event operation to retrieve the events */
3151  NdbEventOperation* eventOp;
3152  eventOp= pNdb->createEventOperation(eventName);
3153 
3154  if (eventOp == NULL)
3155  {
3156  g_err << "Failed to create event operation :" <<
3157  pNdb->getNdbError().code << endl;
3158  return NDBT_FAILED;
3159  }
3160 
3161  NdbRecAttr* eventKeyData= eventOp->getValue("Key");
3162  NdbRecAttr* eventOldKeyData= eventOp->getPreValue("Key");
3163  NdbRecAttr* eventAttrData= eventOp->getValue("Attr");
3164  NdbRecAttr* eventOldAttrData= eventOp->getPreValue("Attr");
3165 
3166  if ((eventKeyData == NULL) || (eventAttrData == NULL))
3167  {
3168  g_err << "Failed to get NdbRecAttrs for events" << endl;
3169  return NDBT_FAILED;
3170  };
3171 
3172  if (eventOp->execute() != 0)
3173  {
3174  g_err << "Failed to execute event operation :" <<
3175  eventOp->getNdbError().code << endl;
3176  return NDBT_FAILED;
3177  }
3178 
3179  /* Perform some operations on the table, and check
3180  * that we get the correct AnyValues propagated
3181  * through
3182  */
3184  opts.optionsPresent= 0;
3185 
3186  NdbInterpretedCode nonsenseProgram;
3187 
3188  nonsenseProgram.load_const_u32(0, 0);
3189  nonsenseProgram.interpret_exit_ok();
3190 
3191  nonsenseProgram.finalise();
3192 
3193  const Uint32 rowCount= 1500;
3194  Uint32 keyOffset= 0;
3195  Uint32 anyValueOffset= 100;
3196 
3197  printf ("Testing AnyValue with no interpreted program\n");
3198  for (int variants= 0; variants < 2; variants ++)
3199  {
3200  for (int op= Insert; op < EndOfOpTypes; op++)
3201  {
3202  printf(" Testing opType %d (ko=%d, ao=%d)...",
3203  op, keyOffset, anyValueOffset);
3204 
3205  if (executeOps(pNdb,
3206  tab,
3207  (OpTypes)op,
3208  rowCount,
3209  keyOffset,
3210  anyValueOffset,
3211  opts))
3212  return NDBT_FAILED;
3213 
3214  if (checkAnyValueInEvent(pNdb,
3215  eventOldKeyData, eventKeyData,
3216  eventOldAttrData, eventAttrData,
3217  rowCount,
3218  anyValueOffset,
3219  false // always use postKey data
3220  ) != NDBT_OK)
3221  return NDBT_FAILED;
3222  printf("ok\n");
3223  };
3224 
3225  printf("Testing AnyValue with interpreted program\n");
3226  opts.optionsPresent|= NdbOperation::OperationOptions::OO_INTERPRETED;
3227  opts.interpretedCode= &nonsenseProgram;
3228  }
3229 
3230  if (dropEventOperations(pNdb) != 0)
3231  {
3232  g_err << "Dropping event operations failed : " <<
3233  pNdb->getNdbError().code << endl;
3234  return NDBT_FAILED;
3235  }
3236 
3237  if (dropEvent(pNdb, tab->getName()) != 0)
3238  {
3239  g_err << "Dropping event failed : " <<
3240  pNdb->getDictionary()->getNdbError().code << endl;
3241  return NDBT_FAILED;
3242  }
3243 
3244  pNdb->getDictionary()->dropTable(tab->getName());
3245 
3246  return NDBT_OK;
3247 }
3248 
3249 
3250 int
3251 runBug30780(NDBT_Context* ctx, NDBT_Step* step)
3252 {
3253  //int result = NDBT_OK;
3254 
3255  NdbRestarter res;
3256 
3257  if (res.getNumDbNodes() < 2)
3258  {
3259  ctx->stopTest();
3260  return NDBT_OK;
3261  }
3262 
3263  const int cases = 4;
3264  int loops = ctx->getNumLoops();
3265  if (loops <= cases)
3266  loops = cases + 1;
3267  for (int i = 0; i<loops; i++)
3268  {
3269  int master = res.getMasterNodeId();
3270  int next = res.getNextMasterNodeId(master);
3271 
3272  res.insertErrorInNode(next, 8064);
3273  int val1[] = { 7213, 0 };
3274  int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
3275  if (res.dumpStateOneNode(master, val2, 2))
3276  return NDBT_FAILED;
3277 
3278  int c = i % cases;
3279  {
3280  char buf[100];
3281  const char * off = NdbEnv_GetEnv("NDB_ERR", buf, sizeof(buf));
3282  if (off)
3283  {
3284  c = atoi(off);
3285  }
3286  }
3287  switch(c){
3288  case 0:
3289  ndbout_c("stopping %u", master);
3290  res.restartOneDbNode(master, false, true, true);
3294  break;
3295  case 1:
3296  ndbout_c("stopping %u, err 7213", master);
3297  val1[0] = 7213;
3298  val1[1] = master;
3299  res.dumpStateOneNode(next, val1, 2);
3300  break;
3301  case 2:
3302  ndbout_c("stopping %u, err 7214", master);
3303  val1[0] = 7214;
3304  val1[1] = master;
3305  res.dumpStateOneNode(next, val1, 2);
3306  break;
3307  case 3:
3308  ndbout_c("stopping %u, err 7007", master);
3309  res.insertErrorInNode(master, 7007);
3310  break;
3311  }
3312  ndbout_c("waiting for %u", master);
3313  res.waitNodesNoStart(&master, 1);
3314  ndbout_c("starting %u", master);
3315  res.startNodes(&master, 1);
3316  ndbout_c("waiting for cluster started");
3317  if (res.waitClusterStarted())
3318  {
3319  return NDBT_FAILED;
3320  }
3321  }
3322 
3323  ctx->stopTest();
3324  return NDBT_OK;
3325 }
3326 
3327 int
3328 runBug44915(NDBT_Context* ctx, NDBT_Step* step)
3329 {
3330  int result = NDBT_OK;
3331 
3332  NdbRestarter res;
3333  int error[] = { 13031, 13044, 13045, 0 };
3334  for (int i = 0; error[i] && result == NDBT_OK; i++)
3335  {
3336  ndbout_c("error: %d", error[i]);
3337  res.insertErrorInNode(res.getDbNodeId(rand() % res.getNumDbNodes()),
3338  error[i]);
3339 
3340  result = runCreateEvent(ctx, step); // should fail due to error insert
3341  result = runCreateEvent(ctx, step); // should pass
3342  result = runDropEvent(ctx, step);
3343  }
3344  return result;
3345 }
3346 
3347 int
3348 runBug56579(NDBT_Context* ctx, NDBT_Step* step)
3349 {
3350  int result = NDBT_OK;
3351 
3352  NdbRestarter res;
3353  Ndb* pNdb = GETNDB(step);
3354 
3355  int error_all[] = { 13046, 0 };
3356  for (int i = 0; error_all[i] && result == NDBT_OK; i++)
3357  {
3358  ndbout_c("error: %d", error_all[i]);
3359  res.insertErrorInAllNodes(error_all[i]);
3360 
3361  if (createEventOperation(pNdb, *ctx->getTab()) != 0)
3362  {
3363  return NDBT_FAILED;
3364  }
3365  }
3366 
3367  return result;
3368 }
3369 
3370 int
3371 runBug57886_create_drop(NDBT_Context* ctx, NDBT_Step* step)
3372 {
3373  int loops = ctx->getNumLoops();
3374  Ndb* pNdb = GETNDB(step);
3375 
3376  NdbDictionary::Dictionary *pDict = pNdb->getDictionary();
3377  NdbDictionary::Table tab = * ctx->getTab();
3378 
3379  sleep(5);
3380 
3381  while (loops --)
3382  {
3383  if (pDict->dropTable(tab.getName()) != 0)
3384  {
3385  return NDBT_FAILED;
3386  }
3387 
3388  if (pDict->createTable(tab) != 0)
3389  {
3390  return NDBT_FAILED;
3391  }
3392 
3393  sleep(1);
3394  }
3395 
3396  ctx->stopTest();
3397  return NDBT_OK;
3398 }
3399 
3400 int
3401 runBug57886_subscribe_unsunscribe(NDBT_Context* ctx, NDBT_Step* step)
3402 {
3403  Ndb* pNdb;
3405 
3406  NdbDictionary::Table tab = * ctx->getTab();
3407 
3408  if (cc(&pCC, &pNdb))
3409  {
3410  // too few api slots...
3411  return NDBT_OK;
3412  }
3413 
3414  while (!ctx->isTestStopped())
3415  {
3416  createEvent(pNdb, tab, false, false);
3417 
3418  NdbEventOperation* op = createEventOperation(pNdb, tab, 0);
3419  if (op)
3420  {
3421  pNdb->dropEventOperation(op);
3422  }
3423  dropEvent(pNdb, tab);
3424  }
3425 
3426  delete pNdb;
3427  delete pCC;
3428  return NDBT_OK;
3429 }
3430 
3431 NDBT_TESTSUITE(test_event);
3432 TESTCASE("BasicEventOperation",
3433  "Verify that we can listen to Events"
3434  "NOTE! No errors are allowed!" )
3435 {
3436 #if 0
3437  TABLE("T1");
3438  TABLE("T3");
3439  TABLE("T5");
3440  TABLE("T6");
3441  TABLE("T8");
3442 #endif
3443  INITIALIZER(runCreateEvent);
3444  STEP(runEventOperation);
3445  STEP(runEventLoad);
3446  FINALIZER(runDropEvent);
3447 }
3448 TESTCASE("CreateDropEventOperation",
3449  "Verify that we can Create and Drop many times"
3450  "NOTE! No errors are allowed!" ){
3451  INITIALIZER(runCreateEvent);
3452  STEP(runCreateDropEventOperation);
3453  FINALIZER(runDropEvent);
3454 }
3455 TESTCASE("ParallellEventOperation",
3456  "Verify that we can listen to Events in parallell"
3457  "NOTE! No errors are allowed!" ){
3458  INITIALIZER(runCreateEvent);
3459  STEP(runEventOperation);
3460  STEP(runEventOperation);
3461  STEP(runEventLoad);
3462  FINALIZER(runDropEvent);
3463 }
3464 TESTCASE("EventOperationApplier",
3465  "Verify that if we apply the data we get from event "
3466  "operation is the same as the original table"
3467  "NOTE! No errors are allowed!" ){
3468  INITIALIZER(runCreateEvent);
3469  INITIALIZER(runCreateShadowTable);
3470  STEP(runEventApplier);
3471  STEP(runEventMixedLoad);
3472  FINALIZER(runDropEvent);
3473  FINALIZER(runVerify);
3474  FINALIZER(runDropShadowTable);
3475 }
3476 TESTCASE("EventOperationApplier_NR",
3477  "Verify that if we apply the data we get from event "
3478  "operation is the same as the original table"
3479  "NOTE! No errors are allowed!" ){
3480  INITIALIZER(runCreateEvent);
3481  INITIALIZER(runCreateShadowTable);
3482  STEP(runEventApplier);
3483  STEP(runEventMixedLoad);
3484  STEP(runRestarter);
3485  FINALIZER(runDropEvent);
3486  FINALIZER(runVerify);
3487  FINALIZER(runDropShadowTable);
3488 }
3489 TESTCASE("EventOperationApplier_NS",
3490  "Verify that if we apply the data we get from event "
3491  "operation is the same as the original table"
3492  "NOTE! No errors are allowed!" ){
3493  TC_PROPERTY("Graceful", 1);
3494  INITIALIZER(runCreateEvent);
3495  INITIALIZER(runCreateShadowTable);
3496  STEP(runEventApplier);
3497  STEP(runEventMixedLoad);
3498  STEP(runRestarter);
3499  FINALIZER(runDropEvent);
3500  FINALIZER(runVerify);
3501  FINALIZER(runDropShadowTable);
3502 }
3503 TESTCASE("MergeEventOperationApplier",
3504  "Verify that if we apply the data we get from merged event "
3505  "operation is the same as the original table"
3506  "NOTE! No errors are allowed!" ){
3507  TC_PROPERTY("MergeEvents", 1);
3508  INITIALIZER(runCreateEvent);
3509  INITIALIZER(runCreateShadowTable);
3510  STEP(runEventApplier);
3511  STEP(runEventMixedLoad);
3512  FINALIZER(runDropEvent);
3513  FINALIZER(runVerify);
3514  FINALIZER(runDropShadowTable);
3515 }
3516 TESTCASE("MergeEventOperationApplier_NR",
3517  "Verify that if we apply the data we get from merged event "
3518  "operation is the same as the original table"
3519  "NOTE! No errors are allowed!" ){
3520  TC_PROPERTY("MergeEvents", 1);
3521  INITIALIZER(runCreateEvent);
3522  INITIALIZER(runCreateShadowTable);
3523  STEP(runEventApplier);
3524  STEP(runEventMixedLoad);
3525  STEP(runRestarter);
3526  FINALIZER(runDropEvent);
3527  FINALIZER(runVerify);
3528  FINALIZER(runDropShadowTable);
3529 }
3530 TESTCASE("Multi",
3531  "Verify that we can work with all tables in parallell"
3532  "NOTE! HugoOperations::startTransaction, pTrans != NULL errors, "
3533  "are allowed!" ){
3534  ALL_TABLES();
3535  INITIALIZER(getAllTables);
3536  INITIALIZER(createAllEvents);
3537  INITIALIZER(createAllShadows);
3538  STEP(runMulti);
3539  FINALIZER(dropAllShadows);
3540  FINALIZER(dropAllEvents);
3541 }
3542 TESTCASE("Multi_NR",
3543  "Verify that we can work with all tables in parallell"
3544  "NOTE! HugoOperations::startTransaction, pTrans != NULL errors, "
3545  "are allowed!" ){
3546  ALL_TABLES();
3547  INITIALIZER(getAllTables);
3548  INITIALIZER(createAllEvents);
3549  INITIALIZER(createAllShadows);
3550  STEP(runMulti_NR);
3551  FINALIZER(dropAllShadows);
3552  FINALIZER(dropAllEvents);
3553 }
3554 TESTCASE("CreateDropNR",
3555  "Verify that we can Create and Drop in any order"
3556  "NOTE! No errors are allowed!" ){
3557  FINALIZER(runCreateDropNR);
3558 }
3559 TESTCASE("SubscribeUnsubscribe",
3560  "A bunch of threads doing subscribe/unsubscribe in loop"
3561  "NOTE! No errors are allowed!" ){
3562  INITIALIZER(runCreateEvent);
3563  STEPS(runSubscribeUnsubscribe, 16);
3564  FINALIZER(runDropEvent);
3565 }
3566 TESTCASE("Bug27169", ""){
3567  INITIALIZER(runCreateEvent);
3568  STEP(runEventListenerUntilStopped);
3569  STEP(runInsertDeleteUntilStopped);
3570  STEP(runScanUpdateUntilStopped);
3571  STEP(runRestarterLoop);
3572  FINALIZER(runDropEvent);
3573 }
3574 TESTCASE("Bug31701", ""){
3575  INITIALIZER(runCreateEvent);
3576  INITIALIZER(runCreateShadowTable);
3577  STEP(runEventApplier);
3578  STEP(runBug31701);
3579  FINALIZER(runDropEvent);
3580  FINALIZER(runDropShadowTable);
3581 }
3582 TESTCASE("SubscribeNR", ""){
3583  TC_PROPERTY("ReportSubscribe", 1);
3584  TC_PROPERTY("SubscribeUntilStopped", 1);
3585  INITIALIZER(runCreateEvent);
3586  STEPS(runSubscribeUnsubscribe, 5);
3587  STEP(runNFSubscribe);
3588  FINALIZER(runDropEvent);
3589 }
3590 TESTCASE("EventBufferOverflow",
3591  "Simulating EventBuffer overflow while node restart"
3592  "NOTE! No errors are allowed!" ){
3593  INITIALIZER(runCreateEvent);
3594  STEP(errorInjectBufferOverflow);
3595  FINALIZER(runDropEvent);
3596 }
3597 TESTCASE("StallingSubscriber",
3598  "Simulating slow subscriber that will become disconnected"
3599  "NOTE! No errors are allowed!" ){
3600  INITIALIZER(runCreateEvent);
3601  STEP(errorInjectStalling);
3602 }
3603 TESTCASE("Bug33793", ""){
3604  INITIALIZER(runCreateEvent);
3605  STEP(runEventListenerUntilStopped);
3606  STEP(runBug33793);
3607  FINALIZER(runDropEvent);
3608 }
3609 TESTCASE("Bug34853", ""){
3610  INITIALIZER(runCreateEvent);
3611  INITIALIZER(runBug34853);
3612  FINALIZER(runDropEvent);
3613 }
3614 TESTCASE("Bug35208", ""){
3615  INITIALIZER(runBug35208_createTable);
3616  INITIALIZER(runCreateEvent);
3617  INITIALIZER(runCreateShadowTable);
3618  STEP(runBug35208);
3619  STEP(runEventApplier);
3620  FINALIZER(runDropEvent);
3621  FINALIZER(runVerify);
3622  FINALIZER(runDropShadowTable);
3623 }
3624 TESTCASE("Bug37279", "")
3625 {
3626  INITIALIZER(runBug37279);
3627 }
3628 TESTCASE("Bug37338", "")
3629 {
3630  INITIALIZER(runBug37338);
3631 }
3632 TESTCASE("Bug37442", "")
3633 {
3634  INITIALIZER(runBug37442);
3635 }
3636 TESTCASE("Bug37672", "NdbRecord option OO_ANYVALUE causes interpreted delete to abort.")
3637 {
3638  INITIALIZER(runBug37672);
3639 }
3640 TESTCASE("Bug30780", "")
3641 {
3642  INITIALIZER(runCreateEvent);
3643  INITIALIZER(runLoadTable);
3644  STEP(runEventConsumer);
3645  STEPS(runScanUpdateUntilStopped, 3);
3646  STEP(runBug30780);
3647  FINALIZER(runDropEvent);
3648 }
3649 TESTCASE("Bug44915", "")
3650 {
3651  INITIALIZER(runBug44915);
3652 }
3653 TESTCASE("Bug56579", "")
3654 {
3655  INITIALIZER(runCreateEvent);
3656  STEP(runBug56579);
3657  FINALIZER(runDropEvent);
3658 }
3659 TESTCASE("Bug57886", "")
3660 {
3661  STEP(runBug57886_create_drop);
3662  STEPS(runBug57886_subscribe_unsunscribe, 5);
3663 }
3664 NDBT_TESTSUITE_END(test_event);
3665 
3666 int main(int argc, const char** argv){
3667  ndb_init();
3668  NDBT_TESTSUITE_INSTANCE(test_event);
3669  test_event.setCreateAllTables(true);
3670  return test_event.execute(argc, argv);
3671 }
3672 
3673 template class Vector<HugoOperations *>;
3674 template class Vector<NdbEventOperation *>;
3675 template class Vector<NdbRecAttr*>;
3676 template class Vector<Vector<NdbRecAttr*> >;