1 /* Copyright (c) 2003-2006, 2008 MySQL AB
2    Use is subject to license terms
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 Street, Fifth Floor, Boston, MA  02110-1301, USA */
16 
17 #include <NDBT.hpp>
18 #include <NDBT_Test.hpp>
19 #include <HugoTransactions.hpp>
20 #include <UtilTransactions.hpp>
21 #include <NdbRestarter.hpp>
22 #include <NdbRestarts.hpp>
23 #include <Vector.hpp>
24 #include <random.h>
25 #include <NdbTick.h>
26 
27 
28 #define CHECK(b) if (!(b)) { \
29   ndbout << "ERR: "<< step->getName() \
30          << " failed on line " << __LINE__ << endl; \
31   result = NDBT_FAILED; \
32   continue; }
33 
runClearTable(NDBT_Context * ctx,NDBT_Step * step)34 int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
35   int records = ctx->getNumRecords();
36   int batchSize = ctx->getProperty("BatchSize", 1);
37 
38   HugoTransactions hugoTrans(*ctx->getTab());
39   if (hugoTrans.pkDelRecords(GETNDB(step),  records, batchSize) != 0){
40     return NDBT_FAILED;
41   }
42   return NDBT_OK;
43 }
44 
runLoadTable(NDBT_Context * ctx,NDBT_Step * step)45 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
46 
47   int records = ctx->getNumRecords();
48   HugoTransactions hugoTrans(*ctx->getTab());
49   if (hugoTrans.loadTable(GETNDB(step), records) != 0){
50     return NDBT_FAILED;
51   }
52   return NDBT_OK;
53 }
54 
runTestIncValue64(NDBT_Context * ctx,NDBT_Step * step)55 int runTestIncValue64(NDBT_Context* ctx, NDBT_Step* step){
56   int records = ctx->getNumRecords();
57   //  NDBT_Table* pTab = ctx->getTab();
58   //Ndb* pNdb = GETNDB(step);
59 
60   HugoTransactions hugoTrans(*ctx->getTab());
61   if (hugoTrans.pkInterpretedUpdateRecords(GETNDB(step),
62 					   records) != 0){
63     return NDBT_FAILED;
64   }
65 
66   // Verify the update
67   if (hugoTrans.pkReadRecords(GETNDB(step),
68 			      records) != 0){
69     return NDBT_FAILED;
70   }
71 
72   return NDBT_OK;
73 
74 }
75 
runTestIncValue32(NDBT_Context * ctx,NDBT_Step * step)76 int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){
77   int result = NDBT_OK;
78   const NdbDictionary::Table * pTab = ctx->getTab();
79   Ndb* pNdb = GETNDB(step);
80 
81   if (strcmp(pTab->getName(), "T1") != 0) {
82     g_err << "runTestBug19537: skip, table != T1" << endl;
83     return NDBT_OK;
84   }
85 
86 
87   NdbConnection* pTrans = pNdb->startTransaction();
88   if (pTrans == NULL){
89     ERR(pNdb->getNdbError());
90     return NDBT_FAILED;
91   }
92 
93   NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
94   if (pOp == NULL) {
95     ERR(pTrans->getNdbError());
96     pNdb->closeTransaction(pTrans);
97     return NDBT_FAILED;
98   }
99 
100   int check = pOp->interpretedUpdateTuple();
101   if( check == -1 ) {
102     ERR(pTrans->getNdbError());
103     pNdb->closeTransaction(pTrans);
104     return NDBT_FAILED;
105   }
106 
107 
108   // Primary keys
109   Uint32 pkVal = 1;
110   check = pOp->equal("KOL1", pkVal );
111   if( check == -1 ) {
112     ERR(pTrans->getNdbError());
113     pNdb->closeTransaction(pTrans);
114     return NDBT_FAILED;
115   }
116 
117   // Attributes
118 
119   // Update column
120   Uint32 valToIncWith = 1;
121   check = pOp->incValue("KOL2", valToIncWith);
122   if( check == -1 ) {
123     ERR(pTrans->getNdbError());
124     pNdb->closeTransaction(pTrans);
125     return NDBT_FAILED;
126   }
127 
128   NdbRecAttr* valueRec = pOp->getValue("KOL2");
129   if( valueRec == NULL ) {
130     ERR(pTrans->getNdbError());
131     pNdb->closeTransaction(pTrans);
132     return NDBT_FAILED;
133   }
134 
135   check = pTrans->execute(Commit);
136   if( check == -1 ) {
137     ERR(pTrans->getNdbError());
138     pNdb->closeTransaction(pTrans);
139     return NDBT_FAILED;
140   }
141 
142   Uint32 value = valueRec->u_32_value();
143 
144   pNdb->closeTransaction(pTrans);
145 
146 
147   return NDBT_OK;
148 }
149 
runTestBug19537(NDBT_Context * ctx,NDBT_Step * step)150 int runTestBug19537(NDBT_Context* ctx, NDBT_Step* step){
151   int result = NDBT_OK;
152   const NdbDictionary::Table * pTab = ctx->getTab();
153   Ndb* pNdb = GETNDB(step);
154 
155   if (strcmp(pTab->getName(), "T1") != 0) {
156     g_err << "runTestBug19537: skip, table != T1" << endl;
157     return NDBT_OK;
158   }
159 
160 
161   NdbConnection* pTrans = pNdb->startTransaction();
162   if (pTrans == NULL){
163     ERR(pNdb->getNdbError());
164     return NDBT_FAILED;
165   }
166 
167   NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
168   if (pOp == NULL) {
169     ERR(pTrans->getNdbError());
170     pNdb->closeTransaction(pTrans);
171     return NDBT_FAILED;
172   }
173 
174   if (pOp->interpretedUpdateTuple() == -1) {
175     ERR(pOp->getNdbError());
176     pNdb->closeTransaction(pTrans);
177     return NDBT_FAILED;
178   }
179 
180 
181   // Primary keys
182   const Uint32 pkVal = 1;
183   if (pOp->equal("KOL1", pkVal) == -1) {
184     ERR(pTrans->getNdbError());
185     pNdb->closeTransaction(pTrans);
186     return NDBT_FAILED;
187   }
188 
189   // Load 64-bit constant into register 1 and
190   // write from register 1 to 32-bit column KOL2
191   const Uint64 reg_val = 0x0102030405060708ULL;
192 
193   const Uint32* reg_ptr32 = (const Uint32*)&reg_val;
194   if (reg_ptr32[0] == 0x05060708 && reg_ptr32[1] == 0x01020304) {
195     g_err << "runTestBug19537: platform is LITTLE endian" << endl;
196   } else if (reg_ptr32[0] == 0x01020304 && reg_ptr32[1] == 0x05060708) {
197     g_err << "runTestBug19537: platform is BIG endian" << endl;
198   } else {
199     g_err << "runTestBug19537: impossible platform"
200           << hex << " [0]=" << reg_ptr32[0] << " [1]=" <<reg_ptr32[1] << endl;
201     pNdb->closeTransaction(pTrans);
202     return NDBT_FAILED;
203   }
204 
205   if (pOp->load_const_u64(1, reg_val) == -1 ||
206       pOp->write_attr("KOL2", 1) == -1) {
207     ERR(pOp->getNdbError());
208     pNdb->closeTransaction(pTrans);
209     return NDBT_FAILED;
210   }
211 
212   if (pTrans->execute(Commit) == -1) {
213     ERR(pTrans->getNdbError());
214     pNdb->closeTransaction(pTrans);
215     return NDBT_FAILED;
216   }
217 
218   // Read value via a new transaction
219 
220   pTrans = pNdb->startTransaction();
221   if (pTrans == NULL){
222     ERR(pNdb->getNdbError());
223     return NDBT_FAILED;
224   }
225 
226   pOp = pTrans->getNdbOperation(pTab->getName());
227   if (pOp == NULL) {
228     ERR(pTrans->getNdbError());
229     pNdb->closeTransaction(pTrans);
230     return NDBT_FAILED;
231   }
232 
233   Uint32 kol2 = 0x09090909;
234   if (pOp->readTuple() == -1 ||
235       pOp->equal("KOL1", pkVal) == -1 ||
236       pOp->getValue("KOL2", (char*)&kol2) == 0) {
237     ERR(pOp->getNdbError());
238     pNdb->closeTransaction(pTrans);
239     return NDBT_FAILED;
240   }
241 
242   if (pTrans->execute(Commit) == -1) {
243     ERR(pTrans->getNdbError());
244     pNdb->closeTransaction(pTrans);
245     return NDBT_FAILED;
246   }
247 
248   // Expected conversion as in C - truncate to lower (logical) word
249 
250   if (kol2 == 0x01020304) {
251     g_err << "runTestBug19537: the bug manifests itself !" << endl;
252     pNdb->closeTransaction(pTrans);
253     return NDBT_FAILED;
254   }
255 
256   if (kol2 != 0x05060708) {
257     g_err << "runTestBug19537: impossible KOL2 " << hex << kol2 << endl;
258     pNdb->closeTransaction(pTrans);
259     return NDBT_FAILED;
260   }
261 
262   pNdb->closeTransaction(pTrans);
263   return NDBT_OK;
264 }
265 
266 
runTestBug34107(NDBT_Context * ctx,NDBT_Step * step)267 int runTestBug34107(NDBT_Context* ctx, NDBT_Step* step){
268   int result = NDBT_OK;
269   const NdbDictionary::Table * pTab = ctx->getTab();
270   Ndb* pNdb = GETNDB(step);
271 
272   int i;
273   for (i = 0; i <= 1; i++) {
274     g_info << "bug34107:" << (i == 0 ? " small" : " too big") << endl;
275 
276     NdbConnection* pTrans = pNdb->startTransaction();
277     if (pTrans == NULL){
278       ERR(pNdb->getNdbError());
279       return NDBT_FAILED;
280     }
281 
282     NdbScanOperation* pOp = pTrans->getNdbScanOperation(pTab->getName());
283     if (pOp == NULL) {
284       ERR(pTrans->getNdbError());
285       pNdb->closeTransaction(pTrans);
286       return NDBT_FAILED;
287     }
288 
289     if (pOp->readTuples() == -1) {
290       ERR(pOp->getNdbError());
291       pNdb->closeTransaction(pTrans);
292       return NDBT_FAILED;
293     }
294 
295     int n = i == 0 ? 10000 : 30000;
296     int k;
297 
298     for (k = 0; k < n; k++) {
299 
300       // inserts 1 word ATTRINFO
301 
302       if (pOp->interpret_exit_ok() == -1) {
303         ERR(pOp->getNdbError());
304         pNdb->closeTransaction(pTrans);
305         return NDBT_FAILED;
306       }
307     }
308 
309     if (pTrans->execute(NoCommit) == -1) {
310       ERR(pTrans->getNdbError());
311       pNdb->closeTransaction(pTrans);
312       return NDBT_FAILED;
313     }
314 
315     int ret;
316     while ((ret = pOp->nextResult()) == 0)
317       ;
318     g_info << "ret=" << ret << " err=" << pOp->getNdbError().code << endl;
319 
320     if (i == 0 && ret != 1) {
321       ERR(pTrans->getNdbError());
322       pNdb->closeTransaction(pTrans);
323       return NDBT_FAILED;
324     }
325 
326     if (i == 1 && ret != -1) {
327       g_err << "unexpected big filter success" << endl;
328       pNdb->closeTransaction(pTrans);
329       return NDBT_FAILED;
330     }
331     if (i == 1 && pOp->getNdbError().code != 874) {
332       g_err << "unexpected big filter error code, wanted 874" << endl;
333       ERR(pTrans->getNdbError());
334       pNdb->closeTransaction(pTrans);
335       return NDBT_FAILED;
336     }
337 
338     pNdb->closeTransaction(pTrans);
339   }
340 
341   return NDBT_OK;
342 }
343 
344 
345 NDBT_TESTSUITE(testInterpreter);
346 TESTCASE("IncValue32",
347 	 "Test incValue for 32 bit integer\n"){
348   INITIALIZER(runLoadTable);
349   INITIALIZER(runTestIncValue32);
350   FINALIZER(runClearTable);
351 }
352 TESTCASE("IncValue64",
353 	 "Test incValue for 64 bit integer\n"){
354   INITIALIZER(runLoadTable);
355   INITIALIZER(runTestIncValue64);
356   FINALIZER(runClearTable);
357 }
358 TESTCASE("Bug19537",
359          "Test big-endian write_attr of 32 bit integer\n"){
360   INITIALIZER(runLoadTable);
361   INITIALIZER(runTestBug19537);
362   FINALIZER(runClearTable);
363 }
364 TESTCASE("Bug34107",
365          "Test too big scan filter (error 874)\n"){
366   INITIALIZER(runLoadTable);
367   INITIALIZER(runTestBug34107);
368   FINALIZER(runClearTable);
369 }
370 #if 0
371 TESTCASE("MaxTransactions",
372 	 "Start transactions until no more can be created\n"){
373   INITIALIZER(runTestMaxTransaction);
374 }
375 TESTCASE("MaxOperations",
376 	"Get operations until no more can be created\n"){
377   INITIALIZER(runLoadTable);
378   INITIALIZER(runTestMaxOperations);
379   FINALIZER(runClearTable);
380 }
381 TESTCASE("MaxGetValue",
382 	"Call getValue loads of time\n"){
383   INITIALIZER(runLoadTable);
384   INITIALIZER(runTestGetValue);
385   FINALIZER(runClearTable);
386 }
387 TESTCASE("MaxEqual",
388 	"Call equal loads of time\n"){
389   INITIALIZER(runTestEqual);
390 }
391 TESTCASE("DeleteNdb",
392 	"Make sure that a deleted Ndb object is properly deleted\n"
393 	"and removed from transporter\n"){
394   INITIALIZER(runLoadTable);
395   INITIALIZER(runTestDeleteNdb);
396   FINALIZER(runClearTable);
397 }
398 TESTCASE("WaitUntilReady",
399 	"Make sure you get an error message when calling waitUntilReady\n"
400 	"without an init'ed Ndb\n"){
401   INITIALIZER(runTestWaitUntilReady);
402 }
403 TESTCASE("GetOperationNoTab",
404 	"Call getNdbOperation on a table that does not exist\n"){
405   INITIALIZER(runGetNdbOperationNoTab);
406 }
407 TESTCASE("MissingOperation",
408 	"Missing operation request(insertTuple) should give an error code\n"){
409   INITIALIZER(runMissingOperation);
410 }
411 TESTCASE("GetValueInUpdate",
412 	"Test that it's not possible to perform getValue in an update\n"){
413   INITIALIZER(runLoadTable);
414   INITIALIZER(runGetValueInUpdate);
415   FINALIZER(runClearTable);
416 }
417 TESTCASE("UpdateWithoutKeys",
418 	"Test that it's not possible to perform update without setting\n"
419 	 "PKs"){
420   INITIALIZER(runLoadTable);
421   INITIALIZER(runUpdateWithoutKeys);
422   FINALIZER(runClearTable);
423 }
424 TESTCASE("UpdateWithoutValues",
425 	"Test that it's not possible to perform update without setValues\n"){
426   INITIALIZER(runLoadTable);
427   INITIALIZER(runUpdateWithoutValues);
428   FINALIZER(runClearTable);
429 }
430 TESTCASE("NdbErrorOperation",
431 	 "Test that NdbErrorOperation is properly set"){
432   INITIALIZER(runCheckGetNdbErrorOperation);
433 }
434 #endif
435 NDBT_TESTSUITE_END(testInterpreter);
436 
main(int argc,const char ** argv)437 int main(int argc, const char** argv){
438   ndb_init();
439   //  TABLE("T1");
440   return testInterpreter.execute(argc, argv);
441 }
442 
443 
444