(file) Return to ut.cpp CVS log (file) (dir) Up to [OMI] / omi / ut

  1 mike  1.1 /*
  2           **==============================================================================
  3           **
  4           ** Open Management Infrastructure (OMI)
  5           **
  6           ** Copyright (c) Microsoft Corporation
  7           ** 
  8           ** Licensed under the Apache License, Version 2.0 (the "License"); you may not 
  9           ** use this file except in compliance with the License. You may obtain a copy 
 10           ** of the License at 
 11           **
 12           **     http://www.apache.org/licenses/LICENSE-2.0 
 13           **
 14           ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15           ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED 
 16           ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 
 17           ** MERCHANTABLITY OR NON-INFRINGEMENT. 
 18           **
 19           ** See the Apache 2 License for the specific language governing permissions 
 20           ** and limitations under the License.
 21           **
 22 mike  1.1 **==============================================================================
 23           */
 24           
 25           // StorageServiceTest.cpp : Defines the entry point for the console application.
 26           //
 27           
 28           #include "ut.h"
 29           #include <vector>
 30           #include <map>
 31           #include <iostream>
 32           #include <fstream>
 33           #include <sstream>
 34           
 35           #if defined(CONFIG_OS_WINDOWS)
 36           # include <time.h>
 37           #else
 38           # include <unistd.h>
 39           # include <sys/time.h>
 40           # include <sys/types.h>
 41           #endif
 42           
 43 mike  1.1 using namespace std;
 44           
 45           namespace ut {
 46               typedef unsigned long long uint64;
 47           
 48               static vector< MODULE_TEST_CALLBACK > *s_fn;
 49               static int  s_tests = 0;
 50               static bool s_lastTestFailed = false;
 51               static vector< UnittestException > s_errors;
 52               static vector< string > s_warnings;
 53               static string s_TestsToRun;
 54               static unsigned int s_NumToRunEachTest = 1; // execute each test this number of times
 55               static bool s_printTestName = false;
 56               static const char*  s_argv0;
 57               static string s_xml_file;
 58               static uint64 s_test_start_time;
 59               static std::map<std::string, string> s_attributes;
 60           
 61               /* helper functions */
 62               static uint64 TimeNow()
 63               {
 64 mike  1.1     #if defined(CONFIG_OS_WINDOWS)
 65                   FILETIME ft;
 66                   ULARGE_INTEGER tmp;
 67           
 68                   GetSystemTimeAsFileTime(&ft);
 69                   tmp.u.LowPart = ft.dwLowDateTime;
 70                   tmp.u.HighPart = ft.dwHighDateTime;
 71                   tmp.QuadPart -= 0X19DB1DED53E8000;
 72                   return (tmp.QuadPart / (UINT64)10);
 73               #else
 74                   struct timeval tv;
 75                   struct timezone tz;
 76                   memset(&tv, 0, sizeof(tv));
 77                   memset(&tz, 0, sizeof(tz));
 78           
 79                   if (gettimeofday(&tv, &tz) != 0)
 80                       return 0;
 81           
 82                   return ((uint64)tv.tv_sec * (uint64)1000000 + (uint64)tv.tv_usec);
 83               #endif
 84               }
 85 mike  1.1 
 86               void registerCallback(MODULE_TEST_CALLBACK pfn)
 87               {
 88                   if ( !s_fn )
 89                       s_fn = new vector< MODULE_TEST_CALLBACK >;
 90           
 91                   s_fn->push_back( pfn );
 92               }
 93           
 94               unsigned int testStarted(const char* name)
 95               {
 96                   if ( !s_TestsToRun.empty() &&
 97                       s_TestsToRun.find(string(",") + name + ",") == s_TestsToRun.npos )
 98                       return 0;
 99           
100                   if (s_printTestName)
101                       cout << endl << name;
102           
103                   s_tests++;
104                   s_test_start_time = TimeNow();
105           
106 mike  1.1         return s_NumToRunEachTest;
107               }
108           
109               void testCompleted(const char* /*name*/)
110               {
111                   cout << (s_lastTestFailed ? "X" : "*");
112           
113                   if (s_tests % 80 == 0)
114                       cout << endl;
115           
116                   if (s_printTestName)
117                   {
118                       uint64 elapsed = TimeNow() - s_test_start_time;
119                       printf(" \t%d.%03d ms", 
120                           (int)(elapsed / 1000 ), //ms
121                           (int)(elapsed % 1000) ); // us
122           
123                   }
124                   s_lastTestFailed = false;
125               }
126           
127 mike  1.1     void testFailed(const UnittestException& ex)
128               {
129                   s_lastTestFailed = true;
130                   s_errors.push_back(ex);
131               }
132           
133               void testWarning(const char* text)
134               {
135                   s_warnings.push_back(text);
136               }
137           
138               bool testGetAttr(const std::string& name, std::string& value)
139               {
140                   map<string, string>::const_iterator it = s_attributes.find(name);
141           
142                   if (it == s_attributes.end())
143                       return false;
144           
145                   value = it->second;
146                   return true;
147               }
148 mike  1.1 
149           };
150           
151           using namespace ut;
152           
153           static void Usage()
154           {
155               printf("\
156           unit-test program; usage:\n\
157           \t%s [options] [tests-to-run]\n\
158           \t\tSupported options are:\n\
159           \t\t-h             - help screen\n\
160           \t\t-n <number>    - execute each test given number of times\n\
161           \t\t-p             - print out test name\n\
162           \t\t-xml <file>    - create xml results file\n\
163           \t\t-a <name>[=value] - set attribute for unittest\n\
164           \t\t<tests-to-run> - coma separated list of tests to run\n",
165               s_argv0);
166           }
167           
168           static void CheckArguments(int argc, char* argv[])
169 mike  1.1 {
170               for (int i = 0; i < argc; )
171               {
172                   /* Check for -I option */
173                   if (strcmp(argv[i], "-n") == 0)
174                   {
175                       /* Check for mandatory option argument */
176                       if (i + 1 == argc)
177                       {
178                           fprintf(stderr, "Missing option argument for -n");
179                           Usage();
180                           exit(1);
181                       }
182           
183                       /* Append path to array */
184                       s_NumToRunEachTest = atol(argv[i+1]);
185           
186                       /* Remove option and its argument from argv */
187                       memmove(&argv[i], &argv[i+2], sizeof(char*) * (argc-i-2));
188                       argc -= 2;
189                   }
190 mike  1.1         else if (strcmp(argv[i], "-xml") == 0)
191                   {
192                       /* Check for mandatory option argument */
193                       if (i + 1 == argc)
194                       {
195                           fprintf(stderr, "Missing option argument for -xml");
196                           Usage();
197                           exit(1);
198                       }
199           
200                       /* Append path to array */
201                       s_xml_file = argv[i+1];
202           
203                       /* Remove option and its argument from argv */
204                       memmove(&argv[i], &argv[i+2], sizeof(char*) * (argc-i-2));
205                       argc -= 2;
206                   }
207                   else if (strcmp(argv[i], "-p") == 0)
208                   {
209                       s_printTestName = true;
210           
211 mike  1.1             /* Remove option and its argument from argv */
212                       memmove(&argv[i], &argv[i+1], sizeof(char*) * (argc-i-1));
213                       argc--;
214                   }
215                   else if (strcmp(argv[i], "-a") == 0)
216                   {
217                       /* Check for mandatory option argument */
218                       if (i + 1 == argc)
219                       {
220                           fprintf(stderr, "Missing option argument for -a");
221                           Usage();
222                           exit(1);
223                       }
224           
225                       /* Append path to array */
226                       {
227                           const char* name = argv[i+1];
228                           const char* value = strchr(name, '=');
229           
230                           string strName, strValue;
231           
232 mike  1.1                 if (value)
233                           {
234                               strName = string(name, value);
235                               strValue = value+1;
236                           }
237                           else
238                           {
239                               strName = name;
240                           }
241                           //s_attributes[ strName ] = strValue;
242                           s_attributes.insert(pair<string, string>(strName, strValue));
243           
244                       }
245           
246                       /* Remove option and its argument from argv */
247                       memmove(&argv[i], &argv[i+2], sizeof(char*) * (argc-i-2));
248                       argc -= 2;
249                   }
250                   else if (strcmp(argv[i], "-h") == 0)
251                   {
252                       Usage();
253 mike  1.1             exit(0);
254                   }
255                   else if (argv[i][0] == '-')
256                   {
257                       fprintf(stderr, "unknown option: %s", argv[i]);
258                       Usage();
259                       exit(1);
260                   }
261                   else
262                       i++;
263               }
264           
265               if ( argc > 1 )
266               {
267                   s_TestsToRun = string(",") + argv[1] + ",";
268               }
269           
270           }
271           
272           static void produceXmlOutput()
273           {
274 mike  1.1     // create xml from results
275           //<?xml version="1.0" encoding='ISO-8859-1' standalone='yes' ?>
276           //<?xml-stylesheet type="text/xsl" href="report.xsl"?>
277           //<Statistics>
278           //  <Tests>687</Tests>
279           //  <FailuresTotal>0</FailuresTotal>
280           //  <Errors>0</Errors>
281           //  <Failures>0</Failures>
282           //</Statistics>
283               try 
284               {
285                   ofstream fst( s_xml_file.c_str(), ios_base::out);
286           
287                   fst << "\
288           <?xml version=\"1.0\" encoding='ISO-8859-1' standalone='yes' ?>\
289           <Statistics>\
290             <Tests>" << s_tests << "</Tests>\
291           <FailuresTotal>" << s_errors.size() << "</FailuresTotal>\
292           <Errors>0</Errors>\
293           <Failures>0</Failures>\
294           </Statistics>";
295 mike  1.1 
296                   if ( fst.bad() )
297                       throw 1;
298               }
299               catch(...)
300               {
301                   cerr << "unable to open file " << s_xml_file << endl;
302               }
303           
304           }
305           
306           int main(int argc, char* argv[])
307           {
308               s_argv0 = argv[0];
309           
310               if ( !s_fn )
311               {
312                   cout << "no tests to run..." << endl;
313                   return 0;
314               }
315           
316 mike  1.1     CheckArguments(argc,argv);
317           
318               uint64 starttime = TimeNow();
319           
320               for ( unsigned int i = 0; i < s_fn->size(); i++ )
321               {
322                   (*s_fn)[i] ();
323               }
324           
325               cout << endl << endl 
326                   << "completed " << s_tests << " test" << (s_tests != 1 ? "s" : "" )
327                   << "; ";
328           
329               if ( s_errors.empty() )
330                   cout << "OK" << endl;
331               else
332                   cout << s_errors.size() << " FAILED" << endl << endl;
333           
334               uint64 elapsed = TimeNow() - starttime;
335               printf(" \tspent %d.%03d ms\n\n", 
336                   (int)(elapsed / 1000 ), //ms
337 mike  1.1         (int)(elapsed % 1000) ); // us
338           
339               for ( unsigned int i = 0; i < s_errors.size(); i++ )
340               {
341           
342                   cout << "test-case: " << s_errors[i].m_testcase << endl;
343                   cout << "function: " << s_errors[i].m_function << endl;
344                   cout << "file: " << s_errors[i].m_file << ":" << s_errors[i].m_line << endl;
345                   cout << "condition: " << s_errors[i].m_text << endl << endl;
346               }
347           
348               if (!s_warnings.empty())
349               {
350                   cout << endl << "Warnings:" << endl;
351           
352                   for ( unsigned int i = 0; i < s_warnings.size(); i++ )
353                   {
354           
355                       cout << s_warnings[i] << endl;
356                   }
357                   cout << endl;
358 mike  1.1 
359               }
360           
361               if ( !s_xml_file.empty())
362               {
363                   produceXmlOutput();
364               }
365           
366               delete s_fn; s_fn = 0;
367           
368               return s_errors.empty() ? 0 : 1;
369           }
370           
371           void __UT_TEST(
372               const char* testName, 
373               void (*setUp)(), 
374               void (*cleanUp)(), 
375               void (*test)())
376           {
377               bool setup_called = false;
378               unsigned int num = ut::testStarted(testName);
379 mike  1.1 
380               for(unsigned int counter = 0; counter < num; counter++)
381               {
382           	try 
383           	{
384           	    setUp();
385           	    setup_called = true;
386           	}
387           	catch (ut::UnittestException ex)
388           	{
389           	    ex.m_testcase = string(testName) + " --setup--";
390           	    testFailed(ex);
391           	}
392           
393           	if (setup_called) 
394           	{
395           	    try 
396           	    {
397           		test();
398           	    } 
399           	    catch (ut::UnittestException ex)
400 mike  1.1 	    {
401           		ex.m_testcase = testName; 
402           		testFailed(ex);
403           	    }
404           	}
405           
406           	if (setup_called) 
407           	{
408           	    try 
409           	    {
410           		cleanUp();
411           	    } 
412           	    catch (ut::UnittestException ex)
413           	    {
414           		ex.m_testcase = string(testName) + "  --cleanup--"; 
415           		testFailed(ex);
416           	    }
417           	}
418           
419           	ut::testCompleted(testName);
420               }
421 mike  1.1 }

ViewCVS 0.9.2