32 #include <ndb_global.h>
37 #include <NdbTest.hpp>
38 #include <NdbSchemaCon.hpp>
40 static int const MaxAttr = 64;
41 static int const MaxOper = 1000;
42 static int const MaxSize = 10000;
43 static int const MaxOff = 64;
44 static int const MaxData = MaxSize + MaxOff + 100;
47 static int attrcnt = 25;
48 static int existok = 0;
49 static bool kontinue =
false;
50 static int loopcnt = 1;
51 static int opercnt = 100;
52 static int randomizer = 171317;
53 static int sizelim = 500;
54 static int xverbose = 0;
56 static void printusage() {
58 <<
"usage: testDataBuffers options [default/max]"
60 <<
"NOTE: too large combinations result in NDB error"
62 <<
"-a N number of attributes (including the key) [25/64]"
64 <<
"-e no error if table exists (assumed to have same structure)"
66 <<
"-k on error continue with next test case"
68 <<
"-l N number of loops to run, 0 means infinite [1]"
70 <<
"-o N number of operations (rows in each table) [100/1000]"
72 <<
"-r N source of randomness (big number (prime)) [171317]"
74 <<
"-s N array size limit (rounded up in some tests) [500/10000]"
76 <<
"-x extremely verbose"
78 <<
"Tables: TB00 .. TB15"
91 ndberror(
char const*
fmt, ...)
96 BaseString::vsnprintf(buf,
sizeof(buf), fmt, ap);
98 ndbout << buf <<
" --" << endl;
104 ndbout <<
"top: " << top->getNdbError() << endl;
113 chkerror(
char const* fmt, ...)
118 BaseString::vsnprintf(buf,
sizeof(buf), fmt, ap);
120 ndbout <<
"*** check failed: " << buf <<
" ***" << endl;
126 static bool isAligned(UintPtr x)
128 return ((x & 3) == 0);
130 static bool isAligned(
char* p)
132 return isAligned(UintPtr(p));
134 static unsigned toAligned(
unsigned x)
136 while (! isAligned(x))
140 static char* toAligned(
char* p)
142 while (! isAligned(p))
148 static int byteVal(
int k,
int i,
int j)
150 return '0' + (k + i + j) % 10;
155 static char tab[20] =
"";
173 static bool alignAddr;
174 static bool alignSize;
176 static bool noRandom;
177 static int testbits = 4;
214 ndbout <<
"--- case " << flag <<
" ---" << endl;
215 sprintf(tab,
"TB%02d", flag);
217 alignAddr = ! (flag & 1);
218 ndbout << (alignAddr ?
"align addresses" :
"mis-align addresses") << endl;
219 alignSize = ! (flag & 2);
220 ndbout << (alignSize ?
"align data sizes" :
"mis-align data sizes") << endl;
221 useBuf = ! (flag & 4);
222 ndbout << (useBuf ?
"use our buffers" :
"use ndbapi buffers") << endl;
223 noRandom = ! (flag & 8);
224 ndbout << (noRandom ?
"simple sizes" :
"randomize sizes") << endl;
226 int smax = 0, stot = 0,
i;
228 ndbout <<
"- define table " << tab << endl;
229 for (i = 0; i < attrcnt; i++) {
231 memset(&c, 0,
sizeof(c));
232 sprintf(c.aAttrName,
"C%d", i);
234 c.aAttrType = UnSigned;
237 c.aTupleKey = TupleKey;
242 c.aArraySize = makeSize(i);
243 if (smax < c.aArraySize)
245 stot += c.aArraySize;
249 ndbout <<
"-- column " << i <<
" size=" << c.aArraySize << endl;
251 c.buf = toAligned(c.data);
252 c.bufsiz =
sizeof(c.data) - (c.buf - c.data);
254 ndbout <<
"tab=" << tab <<
" cols=" << attrcnt
255 <<
" size max=" << smax <<
" tot=" << stot << endl;
257 if ((tcon = NdbSchemaCon::startSchemaTrans(ndb)) == 0)
258 return ndberror(
"startSchemaTransaction");
260 return ndberror(
"getNdbSchemaOp");
262 return ndberror(
"createTable");
263 for (i = 0; i < attrcnt; i++) {
274 return ndberror(
"createAttribute col=%d", i);
278 return ndberror(
"execute");
279 ndbout <<
"using " << tab << endl;
281 ndbout <<
"created " << tab << endl;
287 ndbout <<
"- delete" << endl;
289 for (key = 0; key < opercnt; key++) {
291 return ndberror(
"startTransaction key=%d", key);
293 return ndberror(
"getNdbOperation key=%d", key);
295 return ndberror(
"deleteTuple key=%d", key);
296 for (i = 0; i < attrcnt; i++) {
299 if (op->
equal(c.aAttrName, (
char*)&key,
sizeof(key)) < 0)
300 return ndberror(
"equal key=%d", key);
304 if (con->
execute(Commit) < 0) {
306 return ndberror(
"execute key=%d", key);
314 ndbout <<
"deleted " << delcnt << endl;
317 ndbout <<
"- insert" << endl;
318 for (key = 0; key < opercnt; key++) {
319 int off = makeOff(key);
321 return ndberror(
"startTransaction key=%d", key);
323 return ndberror(
"getNdbOperation key=%d", key);
325 return ndberror(
"insertTuple key=%d", key);
326 for (i = 0; i < attrcnt; i++) {
329 if (op->
equal(c.aAttrName, (
char*)&key,
sizeof(key)) < 0)
330 return ndberror(
"equal key=%d", key);
332 memset(c.buf,
'A', c.bufsiz);
333 for (
int j = 0; j < c.aArraySize; j++)
334 c.buf[j + off] = byteVal(key, i, j);
335 if (op->
setValue(c.aAttrName, c.buf + off, c.aArraySize) < 0)
336 return ndberror(
"setValue key=%d col=%d", key, i);
340 return ndberror(
"execute key=%d", key);
345 ndbout <<
"inserted " << key << endl;
348 ndbout <<
"- select" << endl;
349 for (key = 0; key < opercnt; key++) {
350 int off = makeOff(key);
352 ndbout <<
"-- key " << key <<
" off=" << off << endl;
354 return ndberror(
"startTransaction key=%d", key);
356 return ndberror(
"getNdbOperation key=%d", key);
358 return ndberror(
"readTuple key=%d", key);
359 for (i = 0; i < attrcnt; i++) {
362 if (op->
equal(c.aAttrName, (
char*)&key,
sizeof(key)) < 0)
363 return ndberror(
"equal key=%d", key);
368 sprintf(tmp,
"0x%p", c.buf + off);
370 strcpy(tmp,
"ndbapi");
371 ndbout <<
"--- column " << i <<
" addr=" << tmp << endl;
373 memset(c.buf,
'B', c.bufsiz);
375 if (op->
getValue(c.aAttrName, c.buf + off) < 0)
376 return ndberror(
"getValue key=%d col=%d", key, i);
378 if ((c.aRa = op->
getValue(c.aAttrName)) == 0)
379 return ndberror(
"getValue key=%d col=%d", key, i);
384 return ndberror(
"execute key=%d", key);
385 for (i = 0; i < attrcnt; i++) {
390 for (j = 0; j < off; j++) {
391 if (c.buf[j] !=
'B') {
392 return chkerror(
"mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x",
393 key, i, j,
'B', c.buf[j]);
396 for (j = 0; j < c.aArraySize; j++) {
397 if (c.buf[j + off] != byteVal(key, i, j)) {
398 return chkerror(
"mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
399 key, i, j, byteVal(key, i, j), c.buf[j]);
402 for (j = c.aArraySize + off; j < c.bufsiz; j++) {
403 if (c.buf[j] !=
'B') {
404 return chkerror(
"mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x",
405 key, i, j,
'B', c.buf[j]);
409 char* buf = c.aRa->aRef();
411 return ndberror(
"null aRef key=%d col%d", key, i);
412 for (
int j = 0; j < c.aArraySize; j++) {
413 if (buf[j] != byteVal(key, i, j)) {
414 return chkerror(
"mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
415 key, i, j, byteVal(key, i, j), buf[j]);
424 ndbout <<
"selected " << key << endl;
427 ndbout <<
"- scan" << endl;
433 for (k = 0; k < opercnt; k++)
435 for (key = 0; key < opercnt; key++) {
436 int off = makeOff(key);
441 ndbout <<
"-- key " << key <<
" off=" << off << endl;
444 return ndberror(
"startTransaction key=%d", key);
446 return ndberror(
"getNdbOperation key=%d", key);
448 return ndberror(
"openScanRead key=%d", key);
451 Uint32 colNum= table->
getColumn(c.aAttrName)->getAttrId();
452 if (code->load_const_u32(1, key) < 0)
453 return ndberror(
"load_const_u32");
454 if (code->read_attr(2, colNum) < 0)
455 return ndberror(
"read_attr");
456 if (code->branch_eq(1, 2, 0) < 0)
457 return ndberror(
"branch_eq");
458 if (code->interpret_exit_nok() < 0)
459 return ndberror(
"interpret_exit_nok");
460 if (code->def_label(0) < 0)
461 return ndberror(
"def_label");
462 if (code->interpret_exit_ok() < 0)
463 return ndberror(
"interpret_exit_ok");
465 return ndberror(
"finalise");
467 return ndberror(
"setInterpretedCode");
469 for (i = 0; i < attrcnt; i++) {
472 if (op->
getValue(c.aAttrName, (
char*)&newkey) < 0)
473 return ndberror(
"getValue key=%d col=%d", key, i);
478 sprintf(tmp,
"0x%p", c.buf + off);
480 strcpy(tmp,
"ndbapi");
481 ndbout <<
"--- column " << i <<
" addr=" << tmp << endl;
483 memset(c.buf,
'C', c.bufsiz);
485 if (op->
getValue(c.aAttrName, c.buf + off) < 0)
486 return ndberror(
"getValue key=%d col=%d", key, i);
488 if ((c.aRa = op->
getValue(c.aAttrName)) == 0)
489 return ndberror(
"getValue key=%d col=%d", key, i);
493 if (con->
execute(NoCommit) < 0)
494 return ndberror(
"executeScan key=%d", key);
498 return ndberror(
"unexpected key=%d newkey=%d", key, newkey);
499 for (i = 1; i < attrcnt; i++) {
503 for (j = 0; j < off; j++) {
504 if (c.buf[j] !=
'C') {
505 return chkerror(
"mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x",
506 key, i, j,
'C', c.buf[j]);
509 for (j = 0; j < c.aArraySize; j++) {
510 if (c.buf[j + off] != byteVal(key, i, j)) {
511 return chkerror(
"mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
512 key, i, j, byteVal(key, i, j), c.buf[j]);
515 for (j = c.aArraySize + off; j < c.bufsiz; j++) {
516 if (c.buf[j] !=
'C') {
517 return chkerror(
"mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x",
518 key, i, j,
'C', c.buf[j]);
522 char* buf = c.aRa->aRef();
524 return ndberror(
"null aRef key=%d col%d", key, i);
525 for (
int j = 0; j < c.aArraySize; j++) {
526 if (buf[j] != byteVal(key, i, j)) {
527 return chkerror(
"mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
528 key, i, j, byteVal(key, i, j), buf[j]);
536 return ndberror(
"nextScanResult key=%d", key);
538 return ndberror(
"scan key=%d found %d", key, cnt);
544 for (k = 0; k < opercnt; k++)
546 return ndberror(
"key %d not found", k);
547 ndbout <<
"scanned " << key << endl;
549 ndbout <<
"done" << endl;
553 NDB_COMMAND(testDataBuffers,
"testDataBuffers",
"testDataBuffers",
"testDataBuffers", 65535)
557 while (++argv, --argc > 0) {
558 char const* p = argv[0];
559 if (*p++ !=
'-' || strlen(p) != 1)
563 if (++argv, --argc > 0) {
564 attrcnt = atoi(argv[0]);
565 if (1 <= attrcnt && attrcnt <= MaxAttr)
576 if (++argv, --argc > 0) {
577 loopcnt = atoi(argv[0]);
583 if (++argv, --argc > 0) {
584 opercnt = atoi(argv[0]);
585 if (0 <= opercnt && opercnt <= MaxOper)
590 if (++argv, --argc > 0) {
591 randomizer = atoi(argv[0]);
597 if (++argv, --argc > 0) {
598 sizelim = atoi(argv[0]);
599 if (1 <= sizelim && sizelim <= MaxSize)
609 return NDBT_ProgramExit(NDBT_WRONGARGS);
618 return NDBT_ProgramExit(NDBT_FAILED);
621 ndb =
new Ndb(&con,
"TEST_DB");
622 if (ndb->
init() != 0)
630 ndberror(
"waitUntilReady");
635 for (i = 1; 0 == loopcnt || i <= loopcnt; i++) {
636 ndbout <<
"=== loop " << i <<
" ===" << endl;
637 for (
int flag = 0; flag < (1<<testbits); flag++) {
650 return NDBT_ProgramExit(ok ? NDBT_OK : NDBT_FAILED);