(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 <fstream>
 32           #include <sstream>
 33 krisbash 1.3 #include <pal/format.h>
 34              #include <common.h>
 35 mike     1.1 
 36              #if defined(CONFIG_OS_WINDOWS)
 37              # include <time.h>
 38              #else
 39              # include <unistd.h>
 40              # include <sys/time.h>
 41              # include <sys/types.h>
 42              #endif
 43              
 44              using namespace std;
 45              
 46              namespace ut {
 47                  typedef unsigned long long uint64;
 48              
 49                  static vector< MODULE_TEST_CALLBACK > *s_fn;
 50                  static int  s_tests = 0;
 51                  static bool s_lastTestFailed = false;
 52                  static vector< UnittestException > s_errors;
 53                  static vector< string > s_warnings;
 54                  static string s_TestsToRun;
 55                  static unsigned int s_NumToRunEachTest = 1; // execute each test this number of times
 56 mike     1.1     static bool s_printTestName = false;
 57 krisbash 1.3     static bool s_summary = false;
 58 mike     1.1     static const char*  s_argv0;
 59                  static string s_xml_file;
 60 krisbash 1.3     static ut::uint64 s_test_start_time;
 61 mike     1.1     static std::map<std::string, string> s_attributes;
 62 krisbash 1.3     static bool s_started = false;
 63 mike     1.1 
 64                  /* helper functions */
 65 krisbash 1.3     static ut::uint64 TimeNow()
 66 mike     1.1     {
 67 krisbash 1.3 #if defined(CONFIG_OS_WINDOWS)
 68 mike     1.1         FILETIME ft;
 69                      ULARGE_INTEGER tmp;
 70              
 71                      GetSystemTimeAsFileTime(&ft);
 72                      tmp.u.LowPart = ft.dwLowDateTime;
 73                      tmp.u.HighPart = ft.dwHighDateTime;
 74                      tmp.QuadPart -= 0X19DB1DED53E8000;
 75                      return (tmp.QuadPart / (UINT64)10);
 76 krisbash 1.3 #else
 77 mike     1.1         struct timeval tv;
 78                      struct timezone tz;
 79                      memset(&tv, 0, sizeof(tv));
 80                      memset(&tz, 0, sizeof(tz));
 81              
 82                      if (gettimeofday(&tv, &tz) != 0)
 83                          return 0;
 84              
 85 krisbash 1.3         return ((ut::uint64)tv.tv_sec * (ut::uint64)1000000 + (ut::uint64)tv.tv_usec);
 86              #endif
 87 mike     1.1     }
 88              
 89                  void registerCallback(MODULE_TEST_CALLBACK pfn)
 90                  {
 91                      if ( !s_fn )
 92                          s_fn = new vector< MODULE_TEST_CALLBACK >;
 93              
 94                      s_fn->push_back( pfn );
 95                  }
 96              
 97                  unsigned int testStarted(const char* name)
 98                  {
 99                      if ( !s_TestsToRun.empty() &&
100                          s_TestsToRun.find(string(",") + name + ",") == s_TestsToRun.npos )
101                          return 0;
102              
103                      if (s_printTestName)
104 krisbash 1.3             Tprintf(ZT("%s"), scs(name));
105 mike     1.1 
106                      s_tests++;
107                      s_test_start_time = TimeNow();
108              
109                      return s_NumToRunEachTest;
110                  }
111              
112                  void testCompleted(const char* /*name*/)
113                  {
114 krisbash 1.3         if (s_summary || s_printTestName)
115                      {
116                          Tprintf(ZT("%s"), scs(s_lastTestFailed ? "X" : "*"));
117 mike     1.1 
118 krisbash 1.3             if (s_tests % 80 == 0)
119                              Tprintf(ZT("\n"));
120                      }
121 mike     1.1 
122                      if (s_printTestName)
123                      {
124 krisbash 1.3             ut::uint64 elapsed = TimeNow() - s_test_start_time;
125                          Tprintf(ZT(" (%d.%03d ms)\n"), 
126 mike     1.1                 (int)(elapsed / 1000 ), //ms
127                              (int)(elapsed % 1000) ); // us
128              
129                      }
130                      s_lastTestFailed = false;
131                  }
132              
133                  void testFailed(const UnittestException& ex)
134                  {
135                      s_lastTestFailed = true;
136                      s_errors.push_back(ex);
137                  }
138              
139                  void testWarning(const char* text)
140                  {
141                      s_warnings.push_back(text);
142                  }
143              
144                  bool testGetAttr(const std::string& name, std::string& value)
145                  {
146 krisbash 1.3         if (!s_started)
147                          return false;
148              
149 mike     1.1         map<string, string>::const_iterator it = s_attributes.find(name);
150              
151                      if (it == s_attributes.end())
152                          return false;
153              
154                      value = it->second;
155                      return true;
156                  }
157              
158              };
159              
160              using namespace ut;
161              
162 krisbash 1.3 #define USAGE ZT("\
163              Usage: %s [OPTIONS] [TESTS]\n\
164              \n\
165              Where TESTS is a comma separated list of tests to run.\n\
166              \n\
167              OPTIONS:\n\
168                  -h                  help screen\n\
169                  -n <number>         execute each test given number of times\n\
170                  -p                  print out test name\n\
171                  -xml <file>         create xml results file\n\
172                  -a <name>[=value]   set attribute for unittest\n\n")
173              
174 mike     1.1 static void Usage()
175              {
176 krisbash 1.3     Tprintf(USAGE, s_argv0);
177 mike     1.1 }
178              
179 krisbash 1.3 static void CheckArguments(int argc, _In_reads_(argc) CharPtr argv[])
180 mike     1.1 {
181                  for (int i = 0; i < argc; )
182                  {
183                      /* Check for -I option */
184 krisbash 1.3 #ifdef _PREFAST_
185              #pragma prefast (push)
186              #pragma prefast (disable: 26018)
187              #endif
188 mike     1.1         if (strcmp(argv[i], "-n") == 0)
189 krisbash 1.3 #ifdef _PREFAST_
190              #pragma prefast (pop)
191              #endif
192 mike     1.1         {
193                          /* Check for mandatory option argument */
194                          if (i + 1 == argc)
195                          {
196 krisbash 1.3                 Ftprintf(stderr, ZT("Missing option argument for -n"));
197 mike     1.1                 Usage();
198                              exit(1);
199                          }
200              
201                          /* Append path to array */
202                          s_NumToRunEachTest = atol(argv[i+1]);
203              
204                          /* Remove option and its argument from argv */
205                          memmove(&argv[i], &argv[i+2], sizeof(char*) * (argc-i-2));
206                          argc -= 2;
207                      }
208                      else if (strcmp(argv[i], "-xml") == 0)
209                      {
210                          /* Check for mandatory option argument */
211                          if (i + 1 == argc)
212                          {
213 krisbash 1.3                 Ftprintf(stderr, ZT("Missing option argument for -xml"));
214 mike     1.1                 Usage();
215                              exit(1);
216                          }
217              
218                          /* Append path to array */
219                          s_xml_file = argv[i+1];
220              
221                          /* Remove option and its argument from argv */
222                          memmove(&argv[i], &argv[i+2], sizeof(char*) * (argc-i-2));
223                          argc -= 2;
224                      }
225                      else if (strcmp(argv[i], "-p") == 0)
226                      {
227                          s_printTestName = true;
228              
229                          /* Remove option and its argument from argv */
230                          memmove(&argv[i], &argv[i+1], sizeof(char*) * (argc-i-1));
231                          argc--;
232                      }
233 krisbash 1.3         else if (strcmp(argv[i], "-s") == 0)
234                      {
235                          s_summary = true;
236              
237                          memmove(&argv[i], &argv[i+1], sizeof(char*) * (argc-i-1));
238                          argc--;
239                      }
240 mike     1.1         else if (strcmp(argv[i], "-a") == 0)
241                      {
242                          /* Check for mandatory option argument */
243                          if (i + 1 == argc)
244                          {
245 krisbash 1.3                 Ftprintf(stderr, ZT("Missing option argument for -a"));
246 mike     1.1                 Usage();
247                              exit(1);
248                          }
249              
250                          /* Append path to array */
251                          {
252                              const char* name = argv[i+1];
253                              const char* value = strchr(name, '=');
254              
255                              string strName, strValue;
256              
257                              if (value)
258                              {
259                                  strName = string(name, value);
260                                  strValue = value+1;
261                              }
262                              else
263                              {
264                                  strName = name;
265                              }
266                              //s_attributes[ strName ] = strValue;
267 mike     1.1                 s_attributes.insert(pair<string, string>(strName, strValue));
268              
269                          }
270              
271                          /* Remove option and its argument from argv */
272                          memmove(&argv[i], &argv[i+2], sizeof(char*) * (argc-i-2));
273                          argc -= 2;
274                      }
275                      else if (strcmp(argv[i], "-h") == 0)
276                      {
277                          Usage();
278                          exit(0);
279                      }
280                      else if (argv[i][0] == '-')
281                      {
282 krisbash 1.3             Ftprintf(stderr, ZT("unknown option: %s"), scs(argv[i]));
283 mike     1.1             Usage();
284                          exit(1);
285                      }
286                      else
287                          i++;
288                  }
289              
290                  if ( argc > 1 )
291                  {
292                      s_TestsToRun = string(",") + argv[1] + ",";
293                  }
294              
295              }
296              
297              static void produceXmlOutput()
298              {
299                  // create xml from results
300              //<?xml version="1.0" encoding='ISO-8859-1' standalone='yes' ?>
301              //<?xml-stylesheet type="text/xsl" href="report.xsl"?>
302              //<Statistics>
303              //  <Tests>687</Tests>
304 mike     1.1 //  <FailuresTotal>0</FailuresTotal>
305              //  <Errors>0</Errors>
306              //  <Failures>0</Failures>
307              //</Statistics>
308                  try 
309                  {
310                      ofstream fst( s_xml_file.c_str(), ios_base::out);
311              
312                      fst << "\
313              <?xml version=\"1.0\" encoding='ISO-8859-1' standalone='yes' ?>\
314              <Statistics>\
315                <Tests>" << s_tests << "</Tests>\
316              <FailuresTotal>" << s_errors.size() << "</FailuresTotal>\
317              <Errors>0</Errors>\
318              <Failures>0</Failures>\
319              </Statistics>";
320              
321                      if ( fst.bad() )
322                          throw 1;
323                  }
324                  catch(...)
325 mike     1.1     {
326 krisbash 1.3         Ftprintf(stderr, ZT("unable to open file %s\n"), 
327                          scs(s_xml_file.c_str()));
328 mike     1.1     }
329              
330              }
331              
332 krisbash 1.3 int MI_MAIN_CALL main(int argc, _In_reads_(argc) CharPtr argv[])
333 mike     1.1 {
334 krisbash 1.3     /* Some data structures could be touched during module load. Once we reach
335                   * this point, it is now safe to touch the other global variables. */
336                  s_started = true;
337              
338 mike     1.1     s_argv0 = argv[0];
339              
340 krisbash 1.3     if (!s_fn)
341 mike     1.1     {
342 krisbash 1.3         Tprintf(ZT("No tests to run\n"));
343 mike     1.1         return 0;
344                  }
345              
346 krisbash 1.3     /* Check command-line arguments */
347              
348 mike     1.1     CheckArguments(argc,argv);
349              
350 krisbash 1.3     /* Print program name */
351              
352                  Tprintf(ZT("==== %s:\n"), scs(s_argv0));
353              
354                  /* Save start time */
355              
356                  ut::uint64 starttime = TimeNow();
357              
358                  /* Run tests */
359 mike     1.1 
360                  for ( unsigned int i = 0; i < s_fn->size(); i++ )
361                  {
362                      (*s_fn)[i] ();
363                  }
364              
365 krisbash 1.3     Tprintf(ZT("\n"));
366              
367                  /* Print test executation summary */
368              
369              s_summary = true;
370              
371                  if (s_summary)
372                  {
373                      Tprintf(ZT("Completed %d test(s)"), s_tests);
374              
375                      if (s_errors.empty())
376                          Tprintf(ZT("OK\n"));
377                      else
378                          Tprintf(ZT("%u FAILED\n\n"), (int)s_errors.size());
379              
380                      ut::uint64 elapsed = TimeNow() - starttime;
381                      Tprintf(ZT(" \tspent %d.%03d ms\n\n"), 
382                          (int)(elapsed / 1000 ), //ms
383                          (int)(elapsed % 1000) ); // us
384                  }
385              
386 krisbash 1.3     /* Print any failures */
387 mike     1.1 
388                  for ( unsigned int i = 0; i < s_errors.size(); i++ )
389                  {
390 krisbash 1.3         Tprintf(ZT("test-case: %s\n"), scs(s_errors[i].m_testcase.c_str()));
391                      Tprintf(ZT("function: %s\n"), scs(s_errors[i].m_function.c_str()));
392                      Tprintf(ZT("file: %s:%u\n"), scs(s_errors[i].m_file.c_str()),
393                          (int)s_errors[i].m_line);
394                      Tprintf(ZT("condition: %s\n\n"), scs(s_errors[i].m_text.c_str()));
395                  }
396 mike     1.1 
397 krisbash 1.3     /* Print any warnings */
398 mike     1.1 
399                  if (!s_warnings.empty())
400                  {
401 krisbash 1.3         Tprintf(ZT("\nWarnings:\n"));
402 mike     1.1 
403                      for ( unsigned int i = 0; i < s_warnings.size(); i++ )
404                      {
405 krisbash 1.3             Tprintf(ZT("%s\n"), scs(s_warnings[i].c_str()));
406 mike     1.1         }
407 krisbash 1.3         Tprintf(ZT("\n"));
408                  }
409 mike     1.1 
410 krisbash 1.3     /* Create XML output files */
411 mike     1.1 
412                  if ( !s_xml_file.empty())
413                  {
414                      produceXmlOutput();
415                  }
416              
417                  delete s_fn; s_fn = 0;
418              
419                  return s_errors.empty() ? 0 : 1;
420              }
421              

ViewCVS 0.9.2