/* **============================================================================== ** ** Open Management Infrastructure (OMI) ** ** Copyright (c) Microsoft Corporation ** ** Licensed under the Apache License, Version 2.0 (the "License"); you may not ** use this file except in compliance with the License. You may obtain a copy ** of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY ** KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED ** WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, ** MERCHANTABLITY OR NON-INFRINGEMENT. ** ** See the Apache 2 License for the specific language governing permissions ** and limitations under the License. ** **============================================================================== */ // StorageServiceTest.cpp : Defines the entry point for the console application. // #include "ut.h" #include #include #include #include #include #if defined(CONFIG_OS_WINDOWS) # include #else # include # include # include #endif using namespace std; namespace ut { typedef unsigned long long uint64; static vector< MODULE_TEST_CALLBACK > *s_fn; static int s_tests = 0; static bool s_lastTestFailed = false; static vector< UnittestException > s_errors; static vector< string > s_warnings; static string s_TestsToRun; static unsigned int s_NumToRunEachTest = 1; // execute each test this number of times static bool s_printTestName = false; static const char* s_argv0; static string s_xml_file; static uint64 s_test_start_time; static std::map s_attributes; /* helper functions */ static uint64 TimeNow() { #if defined(CONFIG_OS_WINDOWS) FILETIME ft; ULARGE_INTEGER tmp; GetSystemTimeAsFileTime(&ft); tmp.u.LowPart = ft.dwLowDateTime; tmp.u.HighPart = ft.dwHighDateTime; tmp.QuadPart -= 0X19DB1DED53E8000; return (tmp.QuadPart / (UINT64)10); #else struct timeval tv; struct timezone tz; memset(&tv, 0, sizeof(tv)); memset(&tz, 0, sizeof(tz)); if (gettimeofday(&tv, &tz) != 0) return 0; return ((uint64)tv.tv_sec * (uint64)1000000 + (uint64)tv.tv_usec); #endif } void registerCallback(MODULE_TEST_CALLBACK pfn) { if ( !s_fn ) s_fn = new vector< MODULE_TEST_CALLBACK >; s_fn->push_back( pfn ); } unsigned int testStarted(const char* name) { if ( !s_TestsToRun.empty() && s_TestsToRun.find(string(",") + name + ",") == s_TestsToRun.npos ) return 0; if (s_printTestName) cout << endl << name; s_tests++; s_test_start_time = TimeNow(); return s_NumToRunEachTest; } void testCompleted(const char* /*name*/) { cout << (s_lastTestFailed ? "X" : "*"); if (s_tests % 80 == 0) cout << endl; if (s_printTestName) { uint64 elapsed = TimeNow() - s_test_start_time; printf(" \t%d.%03d ms", (int)(elapsed / 1000 ), //ms (int)(elapsed % 1000) ); // us } s_lastTestFailed = false; } void testFailed(const UnittestException& ex) { s_lastTestFailed = true; s_errors.push_back(ex); } void testWarning(const char* text) { s_warnings.push_back(text); } bool testGetAttr(const std::string& name, std::string& value) { map::const_iterator it = s_attributes.find(name); if (it == s_attributes.end()) return false; value = it->second; return true; } }; using namespace ut; static void Usage() { printf("\ unit-test program; usage:\n\ \t%s [options] [tests-to-run]\n\ \t\tSupported options are:\n\ \t\t-h - help screen\n\ \t\t-n - execute each test given number of times\n\ \t\t-p - print out test name\n\ \t\t-xml - create xml results file\n\ \t\t-a [=value] - set attribute for unittest\n\ \t\t - coma separated list of tests to run\n", s_argv0); } static void CheckArguments(int argc, char* argv[]) { for (int i = 0; i < argc; ) { /* Check for -I option */ if (strcmp(argv[i], "-n") == 0) { /* Check for mandatory option argument */ if (i + 1 == argc) { fprintf(stderr, "Missing option argument for -n"); Usage(); exit(1); } /* Append path to array */ s_NumToRunEachTest = atol(argv[i+1]); /* Remove option and its argument from argv */ memmove(&argv[i], &argv[i+2], sizeof(char*) * (argc-i-2)); argc -= 2; } else if (strcmp(argv[i], "-xml") == 0) { /* Check for mandatory option argument */ if (i + 1 == argc) { fprintf(stderr, "Missing option argument for -xml"); Usage(); exit(1); } /* Append path to array */ s_xml_file = argv[i+1]; /* Remove option and its argument from argv */ memmove(&argv[i], &argv[i+2], sizeof(char*) * (argc-i-2)); argc -= 2; } else if (strcmp(argv[i], "-p") == 0) { s_printTestName = true; /* Remove option and its argument from argv */ memmove(&argv[i], &argv[i+1], sizeof(char*) * (argc-i-1)); argc--; } else if (strcmp(argv[i], "-a") == 0) { /* Check for mandatory option argument */ if (i + 1 == argc) { fprintf(stderr, "Missing option argument for -a"); Usage(); exit(1); } /* Append path to array */ { const char* name = argv[i+1]; const char* value = strchr(name, '='); string strName, strValue; if (value) { strName = string(name, value); strValue = value+1; } else { strName = name; } //s_attributes[ strName ] = strValue; s_attributes.insert(pair(strName, strValue)); } /* Remove option and its argument from argv */ memmove(&argv[i], &argv[i+2], sizeof(char*) * (argc-i-2)); argc -= 2; } else if (strcmp(argv[i], "-h") == 0) { Usage(); exit(0); } else if (argv[i][0] == '-') { fprintf(stderr, "unknown option: %s", argv[i]); Usage(); exit(1); } else i++; } if ( argc > 1 ) { s_TestsToRun = string(",") + argv[1] + ","; } } static void produceXmlOutput() { // create xml from results // // // // 687 // 0 // 0 // 0 // try { ofstream fst( s_xml_file.c_str(), ios_base::out); fst << "\ \ \ " << s_tests << "\ " << s_errors.size() << "\ 0\ 0\ "; if ( fst.bad() ) throw 1; } catch(...) { cerr << "unable to open file " << s_xml_file << endl; } } int main(int argc, char* argv[]) { s_argv0 = argv[0]; if ( !s_fn ) { cout << "no tests to run..." << endl; return 0; } CheckArguments(argc,argv); uint64 starttime = TimeNow(); for ( unsigned int i = 0; i < s_fn->size(); i++ ) { (*s_fn)[i] (); } cout << endl << endl << "completed " << s_tests << " test" << (s_tests != 1 ? "s" : "" ) << "; "; if ( s_errors.empty() ) cout << "OK" << endl; else cout << s_errors.size() << " FAILED" << endl << endl; uint64 elapsed = TimeNow() - starttime; printf(" \tspent %d.%03d ms\n\n", (int)(elapsed / 1000 ), //ms (int)(elapsed % 1000) ); // us for ( unsigned int i = 0; i < s_errors.size(); i++ ) { cout << "test-case: " << s_errors[i].m_testcase << endl; cout << "function: " << s_errors[i].m_function << endl; cout << "file: " << s_errors[i].m_file << ":" << s_errors[i].m_line << endl; cout << "condition: " << s_errors[i].m_text << endl << endl; } if (!s_warnings.empty()) { cout << endl << "Warnings:" << endl; for ( unsigned int i = 0; i < s_warnings.size(); i++ ) { cout << s_warnings[i] << endl; } cout << endl; } if ( !s_xml_file.empty()) { produceXmlOutput(); } delete s_fn; s_fn = 0; return s_errors.empty() ? 0 : 1; } void __UT_TEST( const char* testName, void (*setUp)(), void (*cleanUp)(), void (*test)()) { bool setup_called = false; unsigned int num = ut::testStarted(testName); for(unsigned int counter = 0; counter < num; counter++) { try { setUp(); setup_called = true; } catch (ut::UnittestException ex) { ex.m_testcase = string(testName) + " --setup--"; testFailed(ex); } if (setup_called) { try { test(); } catch (ut::UnittestException ex) { ex.m_testcase = testName; testFailed(ex); } } if (setup_called) { try { cleanUp(); } catch (ut::UnittestException ex) { ex.m_testcase = string(testName) + " --cleanup--"; testFailed(ex); } } ut::testCompleted(testName); } }