NdbPortLibTest.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.  *  NdbPortLibTest.cpp
  15.  *  Test the functionality of portlib
  16.  *  TODO - Add tests for NdbMem
  17.  */
  18. #include <ndb_global.h>
  19. #include "NdbOut.hpp"
  20. #include "NdbThread.h"
  21. #include "NdbMutex.h"
  22. #include "NdbCondition.h"
  23. #include "NdbSleep.h"
  24. #include "NdbTick.h"
  25. #include "NdbEnv.h"
  26. #include "NdbHost.h"
  27. #include "NdbMain.h"
  28. int TestHasFailed;
  29. int verbose = 0;
  30. static void fail(const char* test, const char* cause)
  31. {
  32.   TestHasFailed = 1;
  33.   ndbout << test << " failed, " << cause << endl;
  34. }
  35. // test 1 variables and funcs
  36. extern "C"  void* thread1func(void* arg)
  37. {
  38.   int arg1;
  39.   int returnvalue = 8;
  40.   arg1 = *(int*)arg;
  41.   ndbout << "thread1: thread1func called with arg = " << arg1 << endl;
  42.   //  delay(1000);
  43.   if (arg1 != 7)
  44.     fail("TEST1", "Wrong arg");
  45.   return returnvalue;
  46. }
  47. // test 2 variables and funcs
  48. NdbMutex* test2mutex;
  49. extern "C" void* test2func(void* arg)
  50. {
  51.   int arg1;
  52.   arg1 = *(int*)arg;
  53.   ndbout << "thread" << arg1 << " started in test2func" << endl;
  54.   if (NdbMutex_Lock(test2mutex) != 0)
  55.     fail("TEST2", "Failed to lock mutex");
  56.   ndbout << "thread" << arg1 << ", test2func " << endl;
  57.   if (NdbMutex_Unlock(test2mutex) != 0)
  58.     fail("TEST2", "Failed to unlock mutex");
  59.   int returnvalue = arg1;
  60.   return returnvalue;
  61. }
  62. // test 3 and 7 variables and funcs
  63. NdbMutex* testmutex;
  64. NdbCondition* testcond;
  65. int testthreadsdone;
  66. extern "C" void* testfunc(void* arg)
  67. {
  68.   int tmpVar;
  69.   int threadno;
  70.   int result;
  71.   threadno = *(int*)arg;
  72.   ndbout << "Thread" << threadno << " started in testfunc" << endl;
  73.   do 
  74.     {
  75.       if ((threadno % 2) == 0)
  76. result = NdbSleep_SecSleep(1);
  77.       else
  78. result = NdbSleep_MilliSleep(100);
  79.       if (result != 0)
  80. fail("TEST3", "Wrong result from sleep function");
  81.       if (NdbMutex_Lock(testmutex) != 0)
  82. fail("TEST3", "Wrong result from NdbMutex_Lock function");
  83.   
  84.       ndbout << "thread" << threadno << ", testfunc " << endl;
  85.       testthreadsdone++;
  86.       tmpVar = testthreadsdone;
  87.       if (NdbCondition_Signal(testcond) != 0)
  88. fail("TEST3", "Wrong result from NdbCondition_Signal function");
  89.   
  90.       if (NdbMutex_Unlock(testmutex) != 0)
  91. fail("TEST3", "Wrong result from NdbMutex_Unlock function");
  92.     }
  93.   while(tmpVar<100);
  94.   
  95.   return 0;
  96. }
  97. extern "C" void* testTryLockfunc(void* arg)
  98. {
  99.   int tmpVar = 0;
  100.   int threadno;
  101.   int result;
  102.   threadno = *(int*)arg;
  103.   ndbout << "Thread" << threadno << " started" << endl;
  104.   do 
  105.     {
  106.       if ((threadno % 2) == 0)
  107. result = NdbSleep_SecSleep(1);
  108.       else
  109. result = NdbSleep_MilliSleep(100);
  110.       if (result != 0)
  111. fail("TEST3", "Wrong result from sleep function");
  112.       if (NdbMutex_Trylock(testmutex) == 0){
  113.  
  114. ndbout << "thread" << threadno << ", testTryLockfunc locked" << endl;
  115.    testthreadsdone++;
  116. tmpVar = testthreadsdone;
  117. if (NdbCondition_Signal(testcond) != 0)
  118.   fail("TEST3", "Wrong result from NdbCondition_Signal function");
  119.   
  120. if (NdbMutex_Unlock(testmutex) != 0)
  121.   fail("TEST3", "Wrong result from NdbMutex_Unlock function");
  122.       }
  123.     }
  124.   while(tmpVar<100);
  125.   
  126.   return 0;
  127. }
  128. void testMicros(int count);
  129. Uint64 time_diff(Uint64 s1, Uint64 s2, Uint32 m1, Uint32 m2);
  130. NDB_COMMAND(PortLibTest, "portlibtest", "portlibtest", "Test the portable function layer", 4096){
  131.   ndbout << "= TESTING ARGUMENT PASSING ============" << endl;
  132.   ndbout << "ARGC: " << argc << endl;
  133.   for(int i = 1; i < argc; i++){
  134.     ndbout << " ARGV"<<i<<": " << (char*)argv[i] << endl;
  135.   }
  136.   ndbout << endl << endl;
  137.   
  138.   struct NdbThread* thread1var;
  139.   void *status = 0;
  140.   int arg = 7;
  141.   TestHasFailed = 0;
  142.   // create one thread and wait for it to return
  143.   ndbout << "= TEST1 ===============================" << endl;
  144.   thread1var = NdbThread_Create(thread1func, // Function 
  145. (void**)&arg,// Arg
  146. 2048,        // Stacksize
  147. (char*)"thread1",  // Thread name
  148. NDB_THREAD_PRIO_MEAN); // Thread priority
  149.   
  150.   if(NdbThread_WaitFor(thread1var, &status) != 0)
  151.     fail("TEST1", "NdbThread_WaitFor failed");
  152.   // NOTE! thread return value is not yet used in Ndb and thus not tested(does not work)
  153.   //ndbout << "thread1 returned, status = " << status << endl;
  154.   //if (status != 8) 
  155.   // fail("TEST1", "Wrong status");
  156.   ndbout << "TEST1 completed" << endl;
  157.   NdbThread_Destroy(&thread1var);
  158.   // Create 10 threads that will wait for a mutex before printing it's message to screen
  159.   ndbout << "= TEST2 ===============================" << endl;
  160. #define T2_THREADS 10
  161.   NdbThread* threads[T2_THREADS];
  162.   int   args[T2_THREADS];
  163.   void *status2 = 0;
  164.   test2mutex = NdbMutex_Create();
  165.   NdbMutex_Lock(test2mutex);
  166.   for (int i = 0; i < T2_THREADS; i++)
  167.     {
  168.       args[i] = i;
  169.     threads[i] = NdbThread_Create(test2func, // Function 
  170.   (void**)&args[i],// Arg
  171.   2048,        // Stacksize
  172.   (char*)"test2thread",  // Thread name
  173.   NDB_THREAD_PRIO_MEAN); // Thread priority
  174.     if (threads[i] == NULL)
  175.       fail("TEST2", "NdbThread_Create failed");
  176.     }
  177.   ndbout << "All threads created" << endl;
  178.   NdbMutex_Unlock(test2mutex);
  179.   for (int i = 0; i < T2_THREADS; i++)
  180.   {
  181.     if (NdbThread_WaitFor(threads[i], &status2))
  182.       fail("TEST2", "NdbThread_WaitFor failed");      
  183.     NdbThread_Destroy(&threads[i]);
  184.     // Don't test return values
  185.     //    ndbout << "thread" << i << " returned, status = " << status2 << endl;
  186.     //    if (status2 != i)
  187.     //      fail("TEST2", "Wrong status");
  188.   }
  189.   if (NdbMutex_Lock(test2mutex) != 0)
  190.     fail("TEST2", "NdbMutex_Lock failed");
  191.   if (NdbMutex_Unlock(test2mutex) != 0)
  192.     fail("TEST2", "NdbMutex_Unlock failed");
  193.   if (NdbMutex_Destroy(test2mutex) != 0)
  194.     fail("TEST2", "NdbMutex_Destroy failed");
  195.   ndbout << "TEST2 completed" << endl;
  196.   ndbout << "= TEST3 ===============================" << endl;
  197.   // Create 10 threads that will by synchronised by a condition
  198.   // When they are awakened and have the mutex they will increment a global variable
  199. #define T3_THREADS 10
  200.   NdbThread* t3threads[T3_THREADS];
  201.   int   t3args[T3_THREADS];
  202.   void *status3 = 0;
  203.   testmutex = NdbMutex_Create();
  204.   testcond = NdbCondition_Create();
  205.   testthreadsdone = 0;
  206.   
  207.   for (int i = 0; i < T3_THREADS; i++)
  208.     {
  209.       t3args[i] = i;
  210.       t3threads[i] = NdbThread_Create(testfunc, // Function 
  211.       (void**)&t3args[i],// Arg
  212.       2048,        // Stacksize
  213.       (char*)"test3thread",  // Thread name
  214.       NDB_THREAD_PRIO_MEAN); // Thread priority
  215.     }
  216.   ndbout << "All threads created" << endl;
  217.   if (NdbMutex_Lock(testmutex) != 0)
  218.     fail("TEST3", "NdbMutex_Lock failed");
  219.   
  220.   while (testthreadsdone < T3_THREADS*10)
  221.     {
  222.       if(NdbCondition_Wait(testcond, testmutex) != 0)
  223. fail("TEST3", "NdbCondition_Wait failed");
  224.       ndbout << "Condition signaled, there are " << testthreadsdone << " completed threads" << endl;
  225.     }
  226.   if (NdbMutex_Unlock(testmutex) != 0)
  227.     fail("TEST3", "NdbMutex_Unlock failed");
  228.   for (int i = 0; i < T3_THREADS; i++)
  229.   {
  230.     if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
  231.       fail("TEST3", "NdbThread_WaitFor failed");
  232.     NdbThread_Destroy(&t3threads[i]);
  233.     //ndbout << "thread" << i << " returned, status = " << status3 << endl;
  234.     //if (status3 != i)
  235.     //  fail("TEST3", "Wrong status");
  236.   }
  237.   NdbMutex_Destroy(testmutex);
  238.   NdbCondition_Destroy(testcond);
  239.   ndbout << "TEST3 completed" << endl;
  240.   ndbout << "= TEST4 ===============================" << endl;
  241.   // Check tick functions
  242.   //#if 0
  243.   int sleeptimes[] = {78, 12, 199, 567, 899};
  244.   for (int i = 0; i < 5; i++)
  245.   {
  246.   ndbout << "*------------------------------- Measure" << i << endl;
  247.   NDB_TICKS millisec_now; 
  248.   NDB_TICKS millisec_now2;
  249.   millisec_now = NdbTick_CurrentMillisecond();
  250.   NdbSleep_MilliSleep(sleeptimes[i]);
  251.   millisec_now2 = NdbTick_CurrentMillisecond();
  252.   ndbout << "  Time before sleep = " << millisec_now << endl;
  253.   ndbout << "  Time after sleep =  " << millisec_now2 << endl;
  254.   ndbout << "  Tried to sleep "<<sleeptimes[i]<<" milliseconds." << endl;
  255.   ndbout << "  Sleep time was " << millisec_now2 -millisec_now <<" milliseconds." << endl;
  256.   }
  257.   ndbout << "TEST4 completed" << endl;
  258.   ndbout << "= TEST5 ===============================" << endl;
  259.   // Check NdbOut
  260.   ndbout << "Testing hex and dec functions of NdbOut" << endl;
  261.   for (int i = 0; i<= 0xFF; i++)
  262.     {
  263.       ndbout << i << "=" <<hex << i << "="<<dec << i << ", ";
  264.     }
  265.   ndbout << endl<< "Testing that hex is reset to dec by endl" << endl;
  266.   ndbout << hex << 67 << endl;
  267.   ndbout << 67 << endl;
  268.   
  269.   ndbout << "TEST5 completed" << endl;
  270.   ndbout << "= TEST6 ===============================" << endl;
  271.   const char* theEnvHostNamePtr;
  272.   char buf[255];
  273.   char theHostHostName[256];
  274.   theEnvHostNamePtr = NdbEnv_GetEnv("HOSTNAME", buf, 255);
  275.   if(theEnvHostNamePtr == NULL)
  276.     fail("TEST6", "Could not get HOSTNAME from env");
  277.   else{
  278.     ndbout << "HOSTNAME from GetEnv" <<  theEnvHostNamePtr << endl;
  279.  
  280.     NdbHost_GetHostName(theHostHostName);
  281.   
  282.     ndbout << "HOSTNAME from GetHostName" <<theHostHostName << endl;
  283.     if (strcmp(theEnvHostNamePtr, theHostHostName) != 0)
  284.       fail("TEST6", "NdbHost_GetHostName or NdbEnv_GetEnv failed");
  285.   }
  286.   ndbout << "= TEST7 ===============================" << endl;
  287.   testmutex = NdbMutex_Create();
  288.   testcond = NdbCondition_Create();
  289.   testthreadsdone = 0;
  290.   
  291.   for (int i = 0; i < T3_THREADS; i++)
  292.     {
  293.       t3args[i] = i;
  294.       t3threads[i] = NdbThread_Create(testfunc, // Function 
  295.       (void**)&t3args[i],// Arg
  296.       2048,        // Stacksize
  297.       (char*)"test7thread",  // Thread name
  298.       NDB_THREAD_PRIO_MEAN); // Thread priority
  299.     }
  300.   ndbout << "All threads created" << endl;
  301.   if (NdbMutex_Lock(testmutex) != 0)
  302.     fail("TEST7", "NdbMutex_Lock failed");
  303.   while (testthreadsdone < T3_THREADS*10)
  304.     {
  305.       // just testing the functionality without timing out, therefor 20 sec.
  306.       if(NdbCondition_WaitTimeout(testcond, testmutex, 20000) != 0)
  307. fail("TEST7", "NdbCondition_WaitTimeout failed");
  308.       ndbout << "Condition signaled, there are " << testthreadsdone << " completed threads" << endl;
  309.     }
  310.   if (NdbMutex_Unlock(testmutex) != 0)
  311.     fail("TEST7", "NdbMutex_Unlock failed");
  312.   for (int i = 0; i < T3_THREADS; i++)
  313.   {
  314.     if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
  315.       fail("TEST7", "NdbThread_WaitFor failed");
  316.     NdbThread_Destroy(&t3threads[i]);
  317.   }
  318.   NdbMutex_Destroy(testmutex);
  319.   NdbCondition_Destroy(testcond);
  320.   ndbout << "TEST7 completed" << endl;
  321.   ndbout << "= TEST8 ===============================" << endl;
  322.   ndbout << "         NdbCondition_WaitTimeout" << endl;
  323.   testmutex = NdbMutex_Create();
  324.   testcond = NdbCondition_Create();
  325.   for (int i = 0; i < 5; i++)
  326.   {
  327.     ndbout << "*------------------------------- Measure" << i << endl;
  328.   NDB_TICKS millisec_now; 
  329.   NDB_TICKS millisec_now2;
  330.   millisec_now = NdbTick_CurrentMillisecond();
  331.   if (NdbCondition_WaitTimeout(testcond, testmutex, sleeptimes[i]) != 0)
  332.     fail("TEST8", "NdbCondition_WaitTimeout failed");
  333.   millisec_now2 = NdbTick_CurrentMillisecond();
  334.   ndbout << "  Time before WaitTimeout = " << millisec_now << endl;
  335.   ndbout << "  Time after WaitTimeout =  " << millisec_now2 << endl;
  336.   ndbout << "  Tried to wait "<<sleeptimes[i]<<" milliseconds." << endl;
  337.   ndbout << "  Wait time was " << millisec_now2 -millisec_now <<" milliseconds." << endl;
  338.   }
  339.   ndbout << "TEST8 completed" << endl;
  340.  
  341.   ndbout << "= TEST9 ===============================" << endl;
  342.   ndbout << "         NdbTick_CurrentXXXXXsecond compare" << endl;
  343.   for (int i = 0; i < 5; i++)
  344.   {
  345.     ndbout << "*------------------------------- Measure" << i << endl;
  346.   NDB_TICKS millisec_now; 
  347.   NDB_TICKS millisec_now2;
  348.   Uint32 usec_now, usec_now2;
  349.   Uint64 msec_now, msec_now2;
  350.   millisec_now = NdbTick_CurrentMillisecond();
  351.   NdbTick_CurrentMicrosecond( &msec_now, &usec_now);
  352.   NdbSleep_MilliSleep(sleeptimes[i]);
  353.   millisec_now2 = NdbTick_CurrentMillisecond();
  354.   NdbTick_CurrentMicrosecond( &msec_now2, &usec_now2);
  355.   Uint64 usecdiff = time_diff(msec_now,msec_now2,usec_now,usec_now2);
  356.   NDB_TICKS msecdiff = millisec_now2 -millisec_now;
  357.   ndbout << "     Slept "<<sleeptimes[i]<<" milliseconds." << endl;
  358.   ndbout << "  Measured " << msecdiff <<" milliseconds with milli function ." << endl;
  359.   ndbout << "  Measured " << usecdiff/1000 << "," << usecdiff%1000<<" milliseconds with micro function ." << endl;
  360.   }
  361.   ndbout << "TEST9 completed" << endl;
  362.   const int iter = 20;
  363.   ndbout << "Testing microsecond timer - " << iter << " iterations" << endl;
  364.   testMicros(iter);
  365.   ndbout << "Testing microsecond timer - COMPLETED" << endl;
  366. #if defined NDB_OSE || defined NDB_SOFTOSE
  367.   ndbout << "system_tick() = " << system_tick() << " us per tick" << endl;
  368. #endif
  369.   ndbout << "= TEST10 ===============================" << endl;
  370.   testmutex = NdbMutex_Create();
  371.   testcond = NdbCondition_Create();
  372.   testthreadsdone = 0;
  373.   
  374.   for (int i = 0; i < T3_THREADS; i++)
  375.     {
  376.       t3args[i] = i;
  377.       t3threads[i] = NdbThread_Create(testTryLockfunc, // Function 
  378.       (void**)&t3args[i],// Arg
  379.       2048,        // Stacksize
  380.       (char*)"test10thread",  // Thread name
  381.       NDB_THREAD_PRIO_MEAN); // Thread priority
  382.     }
  383.   ndbout << "All threads created" << endl;
  384.   if (NdbMutex_Lock(testmutex) != 0)
  385.     fail("TEST10", "NdbMutex_Lock failed");
  386.   while (testthreadsdone < T3_THREADS*10)
  387.     {
  388.       if(NdbCondition_Wait(testcond, testmutex) != 0)
  389. fail("TEST10", "NdbCondition_WaitTimeout failed");
  390.       ndbout << "Condition signaled, there are " << testthreadsdone << " completed threads" << endl;
  391.     }
  392.   if (NdbMutex_Unlock(testmutex) != 0)
  393.     fail("TEST10", "NdbMutex_Unlock failed");
  394.   for (int i = 0; i < T3_THREADS; i++)
  395.   {
  396.     if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
  397.       fail("TEST10", "NdbThread_WaitFor failed");
  398.     NdbThread_Destroy(&t3threads[i]);
  399.   }
  400.   NdbMutex_Destroy(testmutex);
  401.   NdbCondition_Destroy(testcond);
  402.   ndbout << "TEST10 completed" << endl;
  403.   // Check total status of test
  404.   if (TestHasFailed == 1)
  405.     ndbout << endl << "TEST FAILED!" << endl;
  406.   else
  407.     ndbout << endl << "TEST PASSED!" << endl;
  408.   return TestHasFailed;
  409. };
  410. Uint64 time_diff(Uint64 s1, Uint64 s2, Uint32 m1, Uint32 m2){
  411.   Uint64 diff = 0;
  412.   diff += (s2 - s1) * 1000000;
  413.   if(m2 >= m1)
  414.     diff += (m2 - m1);
  415.   else {
  416.     diff += m2;
  417.     diff -= m1;
  418.   }
  419.   //  if(0)
  420.   // ndbout("(s1,m1) = (%d, %d) (s2,m2) = (%d, %d) -> diff = %dn",
  421.   //   (Uint32)s1,m1,(Uint32)s2,m2, (Uint32)diff);
  422.   
  423.   return diff;
  424. };
  425. void 
  426. testMicros(int count){
  427.   Uint32 avg = 0;
  428.   Uint32 sum2 = 0;
  429.   for(int i = 0; i<count; i++){
  430.     Uint64 s1, s2;
  431.     Uint32 m1, m2;
  432.     if(NdbTick_CurrentMicrosecond(&s1, &m1) != 0){
  433.       ndbout << "Failed to get current micro" << endl;
  434.       TestHasFailed = 1; 
  435.       return;
  436.     }
  437.     Uint32 r = (rand() % 1000) + 1;
  438.     NdbSleep_MilliSleep(r);
  439.     if(NdbTick_CurrentMicrosecond(&s2, &m2) != 0){
  440.       ndbout << "Failed to get current micro" << endl;
  441.       TestHasFailed = 1; 
  442.       return;
  443.     }
  444.     Uint64 m = time_diff(s1,s2,m1,m2);
  445.     if(verbose)
  446.       ndbout << "Slept for " << r << " ms" 
  447.      << " - Measured  " << m << " us" << endl;
  448.     
  449.     if(m > (r*1000)){
  450.       avg += (m - (r*1000));
  451.       sum2 += (m - (r*1000)) * (m - (r*1000));
  452.     } else {
  453.       avg += ((r*1000) - m);
  454.       sum2 += ((r*1000) - m) * ((r*1000) - m);
  455.     }
  456. #if 0
  457.     m /= 1000;
  458.     if(m > r && ((m - r) > 10)){
  459.       ndbout << "Difference to big: " << (m - r) << " - Test failed" << endl;
  460.       TestHasFailed = 1;
  461.     }
  462.     if(m < r && ((r - m) > 10)){
  463.       ndbout << "Difference to big: " << (r - m) << " - Test failed" << endl;
  464.       TestHasFailed = 1;
  465.     }
  466. #endif
  467.   }
  468.   Uint32 dev = (avg * avg - sum2) / count; dev /= count;
  469.   avg /= count;
  470.   Uint32 t = 0;
  471.   while((t*t)<dev) t++;
  472.   ndbout << "NOTE - measure are compared to NdbSleep_MilliSleep(...)" << endl;
  473.   ndbout << "Average error = " << avg << " us" << endl;
  474.   ndbout << "Stddev  error = " << t << " us" << endl;
  475. }