testDataBuffers.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:16k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /*
  14.  * testDataBuffers
  15.  *
  16.  * Test getValue() of byte arrays:
  17.  * - using application buffers of different alignments and sizes
  18.  * - using NdbApi allocated small (<32) and big (>=32) buffers
  19.  *
  20.  * Verifies fixes to tickets 189 and 206.
  21.  *
  22.  * Options: see printusage() below.
  23.  *
  24.  * Creates tables TB00 to TB15
  25.  */
  26. #include <ndb_global.h>
  27. #include <NdbMain.h>
  28. #include <NdbOut.hpp>
  29. #include <NdbApi.hpp>
  30. #include <NdbTest.hpp>
  31. #include <NdbSchemaCon.hpp>
  32. // limits
  33. static int const MaxAttr = 64;
  34. static int const MaxOper = 1000;
  35. static int const MaxSize = 10000;
  36. static int const MaxOff = 64; // max offset to add to data buffer
  37. static int const MaxData = MaxSize + MaxOff + 100;
  38. // options
  39. static int attrcnt = 25;
  40. static int existok = 0;
  41. static bool kontinue = false;
  42. static int loopcnt = 1;
  43. static int opercnt = 100; // also does this many scans
  44. static int randomizer = 171317;
  45. static int sizelim = 500;
  46. static int xverbose = 0;
  47. static void printusage() {
  48.     ndbout
  49. << "usage: testDataBuffers options [default/max]"
  50. << endl
  51. << "NOTE: too large combinations result in NDB error"
  52. << endl
  53. << "-a N  number of attributes (including the key) [25/64]"
  54. << endl
  55. << "-e    no error if table exists (assumed to have same structure)"
  56. << endl
  57. << "-k    on error continue with next test case"
  58. << endl
  59. << "-l N  number of loops to run, 0 means infinite [1]"
  60. << endl
  61. << "-o N  number of operations (rows in each table) [100/1000]"
  62. << endl
  63. << "-r N  source of randomness (big number (prime)) [171317]"
  64. << endl
  65. << "-s N  array size limit (rounded up in some tests) [500/10000]"
  66. << endl
  67. << "-x    extremely verbose"
  68. << endl
  69. << "Tables: TB00 .. TB15"
  70. << endl
  71. ;
  72. }
  73. static Ndb* ndb = 0;
  74. static NdbSchemaCon* tcon = 0;
  75. static NdbSchemaOp* top = 0;
  76. static NdbConnection* con = 0;
  77. static NdbOperation* op = 0;
  78. static NdbScanOperation* sop = 0;
  79. static NdbResultSet* rs = 0;
  80. static int
  81. ndberror(char const* fmt, ...)
  82. {
  83.     va_list ap;
  84.     char buf[200];
  85.     va_start(ap, fmt);
  86.     BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
  87.     va_end(ap);
  88.     ndbout << buf << " --" << endl;
  89.     if (ndb)
  90.       ndbout << "ndb : " << ndb->getNdbError() << endl;
  91.     if (tcon)
  92. ndbout << "tcon: " << tcon->getNdbError() << endl;
  93.     if (top)
  94. ndbout << "top: " << top->getNdbError() << endl;
  95.     if (con)
  96. ndbout << "con : " << con->getNdbError() << endl;
  97.     if (op)
  98. ndbout << "op  : " << op->getNdbError() << endl;
  99.     return -1;
  100. }
  101. static int
  102. chkerror(char const* fmt, ...)
  103. {
  104.     va_list ap;
  105.     char buf[200];
  106.     va_start(ap, fmt);
  107.     BaseString::vsnprintf(buf, sizeof(buf), fmt, ap);
  108.     va_end(ap);
  109.     ndbout << "*** check failed: " << buf << " ***" << endl;
  110.     return -1;
  111. }
  112. // alignment of addresses and data sizes
  113. static bool isAligned(UintPtr x)
  114. {
  115.     return ((x & 3) == 0);
  116. }
  117. static bool isAligned(char* p)
  118. {
  119.     return isAligned(UintPtr(p));
  120. }
  121. static unsigned toAligned(UintPtr x)
  122. {
  123.     while (! isAligned(x))
  124. x++;
  125.     return x;
  126. }
  127. static char* toAligned(char* p)
  128. {
  129.     while (! isAligned(p))
  130. p++;
  131.     return p;
  132. }
  133. // byte value for key k column i byte j
  134. static int byteVal(int k, int i, int j)
  135. {
  136.     return '0' + (k + i + j)  % 10;
  137. }
  138. // tables
  139. static char tab[20] = "";
  140. static struct col {
  141.     char aAttrName[20];
  142.     AttrType aAttrType;
  143.     int aAttrSize;
  144.     int aArraySize;
  145.     KeyType aTupleKey;
  146.     bool nullable;
  147.     NdbRecAttr* aRa;
  148.     char* buf;
  149.     int bufsiz;
  150.     char data[MaxData];
  151. } ccol[MaxAttr];
  152. static int key = 0;
  153. // independent test bits
  154. static bool alignAddr; // align our buffer addresses to 4x
  155. static bool alignSize; // align data sizes to 4x
  156. static bool useBuf; // use our buffers for output
  157. static bool noRandom; // do not randomize sizes and offsets
  158. static int testbits = 4;
  159. static int
  160. makeSize(int i)
  161. {
  162.     int n;
  163.     if (noRandom)
  164. n = i;
  165.     else
  166. n = i * randomizer;
  167.     n %= sizelim;
  168.     if (n <= 0)
  169. n = 1;
  170.     if (alignSize)
  171. n = toAligned(n);
  172.     return n;
  173. }
  174. static int
  175. makeOff(int k)
  176. {
  177.     int n;
  178.     if (alignAddr)
  179. n = 0;
  180.     else if (noRandom)
  181. n = k;
  182.     else
  183. n = k * randomizer;
  184.     n %= MaxOff;
  185.     if (n < 0)
  186. n = -n;
  187.     return n;
  188. }
  189. static int
  190. testcase(int flag)
  191. {
  192.     ndbout << "--- case " << flag << " ---" << endl;
  193.     sprintf(tab, "TB%02d", flag);
  194.     alignAddr = ! (flag & 1);
  195.     ndbout << (alignAddr ? "align addresses" : "mis-align addresses") << endl;
  196.     alignSize = ! (flag & 2);
  197.     ndbout << (alignSize ? "align data sizes" : "mis-align data sizes") << endl;
  198.     useBuf = ! (flag & 4);
  199.     ndbout << (useBuf ? "use our buffers" : "use ndbapi buffers") << endl;
  200.     noRandom = ! (flag & 8);
  201.     ndbout << (noRandom ? "simple sizes" : "randomize sizes") << endl;
  202.     int smax = 0, stot = 0, i;
  203.     if (xverbose)
  204.       ndbout << "- define table " << tab << endl;
  205.     for (i = 0; i < attrcnt; i++) {
  206. col& c = ccol[i];
  207. memset(&c, 0, sizeof(c));
  208. sprintf(c.aAttrName, "C%d", i);
  209. if (i == 0) {
  210.     c.aAttrType = UnSigned;
  211.     c.aAttrSize = 32;
  212.     c.aArraySize = 1;
  213.     c.aTupleKey = TupleKey;
  214.     c.nullable = false;
  215. } else {
  216.     c.aAttrType = String;
  217.     c.aAttrSize = 8;
  218.     c.aArraySize = makeSize(i);
  219.     if (smax < c.aArraySize)
  220. smax = c.aArraySize;
  221.     stot += c.aArraySize;
  222.     c.aTupleKey = NoKey;
  223.     c.nullable = true;
  224.     if (xverbose)
  225.       ndbout << "-- column " << i << " size=" << c.aArraySize << endl;
  226. }
  227. c.buf = toAligned(c.data);
  228. c.bufsiz = sizeof(c.data) - (c.buf - c.data);
  229.     }
  230.     ndbout << "tab=" << tab << " cols=" << attrcnt
  231. << " size max=" << smax << " tot=" << stot << endl;
  232.     ndb = new Ndb("TEST_DB");
  233.     if (ndb->init() != 0)
  234. return ndberror("init");
  235.     if (ndb->waitUntilReady(30) < 0)
  236. return ndberror("waitUntilReady");
  237.     if ((tcon = NdbSchemaCon::startSchemaTrans(ndb)) == 0)
  238. return ndberror("startSchemaTransaction");
  239.     if ((top = tcon->getNdbSchemaOp()) == 0)
  240. return ndberror("getNdbSchemaOp");
  241.     if (top->createTable(tab) < 0)
  242. return ndberror("createTable");
  243.     for (i = 0; i < attrcnt; i++) {
  244. col& c = ccol[i];
  245. if (top->createAttribute(
  246.     c.aAttrName,
  247.     c.aTupleKey,
  248.     c.aAttrSize,
  249.     c.aArraySize,
  250.     c.aAttrType,
  251.     MMBased,
  252.     c.nullable
  253. ) < 0)
  254.     return ndberror("createAttribute col=%d", i);
  255.     }
  256.     if (tcon->execute() < 0) {
  257. if (! (tcon->getNdbError().code == 721 && existok))
  258.     return ndberror("execute");
  259. ndbout << "using " << tab << endl;
  260.     } else {
  261. ndbout << "created " << tab << endl;
  262.     }
  263.     top = 0;
  264.     tcon = 0;
  265.     if (xverbose)
  266.       ndbout << "- delete" << endl;
  267.     int delcnt = 0;
  268.     for (key = 0; key < opercnt; key++) {
  269. if ((con = ndb->startTransaction()) == 0)
  270.     return ndberror("startTransaction key=%d", key);
  271. if ((op = con->getNdbOperation(tab)) == 0)
  272.     return ndberror("getNdbOperation key=%d", key);
  273. if (op->deleteTuple() < 0)
  274.     return ndberror("deleteTuple key=%d", key);
  275. for (i = 0; i < attrcnt; i++) {
  276.     col& c = ccol[i];
  277.     if (i == 0) {
  278. if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0)
  279.     return ndberror("equal key=%d", key);
  280.     } else {
  281.     }
  282. }
  283. if (con->execute(Commit) < 0) {
  284.   if (con->getNdbError().code != 626)
  285.     return ndberror("execute key=%d", key);
  286. } else {
  287.     delcnt++;
  288. }
  289. ndb->closeTransaction(con);
  290.     }
  291.     con = 0;
  292.     op = 0;
  293.     ndbout << "deleted " << delcnt << endl;
  294.     if (xverbose)
  295.       ndbout << "- insert" << endl;
  296.     for (key = 0; key < opercnt; key++) {
  297. int off = makeOff(key);
  298. if ((con = ndb->startTransaction()) == 0)
  299.     return ndberror("startTransaction key=%d", key);
  300. if ((op = con->getNdbOperation(tab)) == 0)
  301.     return ndberror("getNdbOperation key=%d", key);
  302. if (op->insertTuple() < 0)
  303.     return ndberror("insertTuple key=%d", key);
  304. for (i = 0; i < attrcnt; i++) {
  305.     col& c = ccol[i];
  306.     if (i == 0) {
  307. if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0)
  308.     return ndberror("equal key=%d", key);
  309.     } else {
  310. memset(c.buf, 'A', c.bufsiz);
  311. for (int j = 0; j < c.aArraySize; j++)
  312.     c.buf[j + off] = byteVal(key, i, j);
  313. if (op->setValue(c.aAttrName, c.buf + off, c.aArraySize) < 0)
  314.     return ndberror("setValue key=%d col=%d", key, i);
  315.     }
  316. }
  317. if (con->execute(Commit) < 0)
  318.     return ndberror("execute key=%d", key);
  319. ndb->closeTransaction(con);
  320.     }
  321.     con = 0;
  322.     op = 0;
  323.     ndbout << "inserted " << key << endl;
  324.     if (xverbose)
  325.       ndbout << "- select" << endl;
  326.     for (key = 0; key < opercnt; key++) {
  327. int off = makeOff(key);
  328. if (xverbose)
  329.   ndbout << "-- key " << key << " off=" << off << endl;
  330. if ((con = ndb->startTransaction()) == 0)
  331.     return ndberror("startTransaction key=%d", key);
  332. if ((op = con->getNdbOperation(tab)) == 0)
  333.     return ndberror("getNdbOperation key=%d", key);
  334. if (op->readTuple() < 0)
  335.     return ndberror("readTuple key=%d", key);
  336. for (i = 0; i < attrcnt; i++) {
  337.     col& c = ccol[i];
  338.     if (i == 0) {
  339. if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0)
  340.     return ndberror("equal key=%d", key);
  341.     } else {
  342. if (xverbose) {
  343.   char tmp[20];
  344.   if (useBuf)
  345.     sprintf(tmp, "0x%p", c.buf + off);
  346.   else
  347.     strcpy(tmp, "ndbapi");
  348.   ndbout << "--- column " << i << " addr=" << tmp << endl;
  349. }
  350. memset(c.buf, 'B', c.bufsiz);
  351. if (useBuf) {
  352.     if (op->getValue(c.aAttrName, c.buf + off) < 0)
  353. return ndberror("getValue key=%d col=%d", key, i);
  354. } else {
  355.     if ((c.aRa = op->getValue(c.aAttrName)) == 0)
  356. return ndberror("getValue key=%d col=%d", key, i);
  357. }
  358.     }
  359. }
  360. if (con->execute(Commit) != 0)
  361.     return ndberror("execute key=%d", key);
  362. for (i = 0; i < attrcnt; i++) {
  363.     col& c = ccol[i];
  364.     if (i == 0) {
  365.     } else if (useBuf) {
  366.                 int j;
  367. for (j = 0; j < off; j++) {
  368.     if (c.buf[j] != 'B') {
  369. return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x",
  370.     key, i, j, 'B', c.buf[j]);
  371.     }
  372. }
  373. for (j = 0; j < c.aArraySize; j++) {
  374.     if (c.buf[j + off] != byteVal(key, i, j)) {
  375. return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
  376.     key, i, j, byteVal(key, i, j), c.buf[j]);
  377.     }
  378. }
  379. for (j = c.aArraySize + off; j < c.bufsiz; j++) {
  380.     if (c.buf[j] != 'B') {
  381. return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x",
  382.     key, i, j, 'B', c.buf[j]);
  383.     }
  384. }
  385.     } else {
  386. char* buf = c.aRa->aRef();
  387. if (buf == 0)
  388.     return ndberror("null aRef key=%d col%d", key, i);
  389. for (int j = 0; j < c.aArraySize; j++) {
  390.     if (buf[j] != byteVal(key, i, j)) {
  391. return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
  392.     key, i, j, byteVal(key, i, j), buf[j]);
  393.     }
  394. }
  395.     }
  396. }
  397. ndb->closeTransaction(con);
  398.     }
  399.     con = 0;
  400.     op = 0;
  401.     ndbout << "selected " << key << endl;
  402.     if (xverbose)
  403.       ndbout << "- scan" << endl;
  404.     char found[MaxOper];
  405.     int k;
  406.     for (k = 0; k < opercnt; k++)
  407. found[k] = 0;
  408.     for (key = 0; key < opercnt; key++) {
  409. int off = makeOff(key);
  410. if (xverbose)
  411.   ndbout << "-- key " << key << " off=" << off << endl;
  412. int newkey = 0;
  413. if ((con = ndb->startTransaction()) == 0)
  414.     return ndberror("startTransaction key=%d", key);
  415. if ((op = sop = con->getNdbScanOperation(tab)) == 0)
  416.     return ndberror("getNdbOperation key=%d", key);
  417. if ((rs = sop->readTuples(1)) == 0)
  418.     return ndberror("openScanRead key=%d", key);
  419. {
  420.     col& c = ccol[0];
  421.     if (op->load_const_u32(1, key) < 0)
  422. return ndberror("load_const_u32");
  423.     if (op->read_attr(c.aAttrName, 2) < 0)
  424. return ndberror("read_attr");
  425.     if (op->branch_eq(1, 2, 0) < 0)
  426. return ndberror("branch_eq");
  427.     if (op->interpret_exit_nok() < 0)
  428. return ndberror("interpret_exit_nok");
  429.     if (op->def_label(0) < 0)
  430. return ndberror("def_label");
  431.     if (op->interpret_exit_ok() < 0)
  432. return ndberror("interpret_exit_ok");
  433. }
  434. for (i = 0; i < attrcnt; i++) {
  435.     col& c = ccol[i];
  436.     if (i == 0) {
  437. if (op->getValue(c.aAttrName, (char*)&newkey) < 0)
  438.     return ndberror("getValue key=%d col=%d", key, i);
  439.     } else {
  440. if (xverbose) {
  441.   char tmp[20];
  442.   if (useBuf)
  443.     sprintf(tmp, "0x%p", c.buf + off);
  444.   else
  445.     strcpy(tmp, "ndbapi");
  446.   ndbout << "--- column " << i << " addr=" << tmp << endl;
  447. }
  448. memset(c.buf, 'C', c.bufsiz);
  449. if (useBuf) {
  450.     if (op->getValue(c.aAttrName, c.buf + off) < 0)
  451. return ndberror("getValue key=%d col=%d", key, i);
  452. } else {
  453.     if ((c.aRa = op->getValue(c.aAttrName)) == 0)
  454. return ndberror("getValue key=%d col=%d", key, i);
  455. }
  456.     }
  457. }
  458. if (con->execute(NoCommit) < 0)
  459.     return ndberror("executeScan key=%d", key);
  460. int ret, cnt = 0;
  461. while ((ret = rs->nextResult()) == 0) {
  462.     if (key != newkey)
  463. return ndberror("unexpected key=%d newkey=%d", key, newkey);
  464.     for (i = 1; i < attrcnt; i++) {
  465. col& c = ccol[i];
  466. if (useBuf) {
  467.                     int j;
  468.     for (j = 0; j < off; j++) {
  469. if (c.buf[j] != 'C') {
  470.     return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x",
  471. key, i, j, 'C', c.buf[j]);
  472. }
  473.     }
  474.     for (j = 0; j < c.aArraySize; j++) {
  475. if (c.buf[j + off] != byteVal(key, i, j)) {
  476.     return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
  477. key, i, j, byteVal(key, i, j), c.buf[j]);
  478. }
  479.     }
  480.     for (j = c.aArraySize + off; j < c.bufsiz; j++) {
  481. if (c.buf[j] != 'C') {
  482.     return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x",
  483. key, i, j, 'C', c.buf[j]);
  484. }
  485.     }
  486. } else {
  487.     char* buf = c.aRa->aRef();
  488.     if (buf == 0)
  489. return ndberror("null aRef key=%d col%d", key, i);
  490.     for (int j = 0; j < c.aArraySize; j++) {
  491. if (buf[j] != byteVal(key, i, j)) {
  492.     return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
  493. key, i, j, byteVal(key, i, j), buf[j]);
  494. }
  495.     }
  496. }
  497.     }
  498.     cnt++;
  499. }
  500. if (ret < 0)
  501.     return ndberror("nextScanResult key=%d", key);
  502. if (cnt != 1)
  503.     return ndberror("scan key=%d found %d", key, cnt);
  504. found[key] = 1;
  505. ndb->closeTransaction(con);
  506.     }
  507.     con = 0;
  508.     op = 0;
  509.     for (k = 0; k < opercnt; k++)
  510. if (! found[k])
  511.     return ndberror("key %d not found", k);
  512.     ndbout << "scanned " << key << endl;
  513.     ndb = 0;
  514.     ndbout << "done" << endl;
  515.     return 0;
  516. }
  517. NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuffers", 65535)
  518. {
  519.     int i;
  520.     ndb_init();
  521.     while (++argv, --argc > 0) {
  522. char const* p = argv[0];
  523. if (*p++ != '-' || strlen(p) != 1)
  524.     goto wrongargs;
  525. switch (*p) {
  526. case 'a':
  527.     if (++argv, --argc > 0) {
  528. attrcnt = atoi(argv[0]);
  529. if (1 <= attrcnt && attrcnt <= MaxAttr)
  530.     break;
  531.     }
  532.     goto wrongargs;
  533. case 'e':
  534.     existok = 1;
  535.     break;
  536. case 'k':
  537.     kontinue = true;
  538.     break;
  539. case 'l':
  540.     if (++argv, --argc > 0) {
  541. loopcnt = atoi(argv[0]);
  542. if (0 <= loopcnt)
  543.     break;
  544.     }
  545.     goto wrongargs;
  546. case 'o':
  547.     if (++argv, --argc > 0) {
  548. opercnt = atoi(argv[0]);
  549. if (0 <= opercnt && opercnt <= MaxOper)
  550.     break;
  551.     }
  552.     goto wrongargs;
  553. case 'r':
  554.     if (++argv, --argc > 0) {
  555. randomizer = atoi(argv[0]);
  556. if (1 <= randomizer)
  557.     break;
  558.     }
  559.     goto wrongargs;
  560. case 's':
  561.     if (++argv, --argc > 0) {
  562. sizelim = atoi(argv[0]);
  563. if (1 <= sizelim && sizelim <= MaxSize)
  564.     break;
  565.     }
  566.     goto wrongargs;
  567. case 'x':
  568.     xverbose = 1;
  569.     break;
  570. default:
  571. wrongargs:
  572.     printusage();
  573.     return NDBT_ProgramExit(NDBT_WRONGARGS);
  574. }
  575.     }
  576.     unsigned ok = true;
  577.     for (i = 1; 0 == loopcnt || i <= loopcnt; i++) {
  578. ndbout << "=== loop " << i << " ===" << endl;
  579. for (int flag = 0; flag < (1<<testbits); flag++) {
  580.     if (testcase(flag) < 0) {
  581. ok = false;
  582. if (! kontinue)
  583.     goto out;
  584.     }
  585. }
  586.     }
  587. out:
  588.     return NDBT_ProgramExit(ok ? NDBT_OK : NDBT_FAILED);
  589. }
  590. // vim: set sw=4: