1 // Copyright 2007 Google Inc. All Rights Reserved.
2
3 // juberti@google.com (Justin Uberti)
4 //
5 // A reuseable entry point for gunit tests.
6
7 #ifdef WIN32
8 #include <crtdbg.h>
9 #endif
10
11 #include "talk/base/flags.h"
12 #include "talk/base/fileutils.h"
13 #include "talk/base/gunit.h"
14 #include "talk/base/logging.h"
15 #include "talk/base/pathutils.h"
16
17 DEFINE_bool(help, false, "prints this message");
18 DEFINE_string(log, "", "logging options to use");
19 #ifdef WIN32
20 DEFINE_int(crt_break_alloc, -1, "memory allocation to break on");
21 DEFINE_bool(default_error_handlers, false,
22 "leave the default exception/dbg handler functions in place");
23
TestInvalidParameterHandler(const wchar_t * expression,const wchar_t * function,const wchar_t * file,unsigned int line,uintptr_t pReserved)24 void TestInvalidParameterHandler(const wchar_t* expression,
25 const wchar_t* function,
26 const wchar_t* file,
27 unsigned int line,
28 uintptr_t pReserved) {
29 LOG(LS_ERROR) << "InvalidParameter Handler called. Exiting.";
30 LOG(LS_ERROR) << expression << std::endl << function << std::endl << file
31 << std::endl << line;
32 exit(1);
33 }
TestPureCallHandler()34 void TestPureCallHandler() {
35 LOG(LS_ERROR) << "Purecall Handler called. Exiting.";
36 exit(1);
37 }
TestCrtReportHandler(int report_type,char * msg,int * retval)38 int TestCrtReportHandler(int report_type, char* msg, int* retval) {
39 LOG(LS_ERROR) << "CrtReport Handler called...";
40 LOG(LS_ERROR) << msg;
41 if (report_type == _CRT_ASSERT) {
42 exit(1);
43 } else {
44 *retval = 0;
45 return TRUE;
46 }
47 }
48 #endif // WIN32
49
GetTalkDirectory()50 talk_base::Pathname GetTalkDirectory() {
51 // Locate talk directory.
52 talk_base::Pathname path = talk_base::Filesystem::GetCurrentDirectory();
53 std::string talk_folder_name("talk");
54 talk_folder_name += path.folder_delimiter();
55 while (path.folder_name() != talk_folder_name && !path.empty()) {
56 path.SetFolder(path.parent_folder());
57 }
58
59 // If not running inside "talk" folder, then assume running in its parent
60 // folder.
61 if (path.empty()) {
62 path = talk_base::Filesystem::GetCurrentDirectory();
63 path.AppendFolder("talk");
64 // Make sure the folder exist.
65 if (!talk_base::Filesystem::IsFolder(path)) {
66 path.clear();
67 }
68 }
69 return path;
70 }
71
main(int argc,char ** argv)72 int main(int argc, char** argv) {
73 testing::InitGoogleTest(&argc, argv);
74 FlagList::SetFlagsFromCommandLine(&argc, argv, false);
75 if (FLAG_help) {
76 FlagList::Print(NULL, false);
77 return 0;
78 }
79
80 #ifdef WIN32
81 if (!FLAG_default_error_handlers) {
82 // Make sure any errors don't throw dialogs hanging the test run.
83 _set_invalid_parameter_handler(TestInvalidParameterHandler);
84 _set_purecall_handler(TestPureCallHandler);
85 _CrtSetReportHook2(_CRT_RPTHOOK_INSTALL, TestCrtReportHandler);
86 }
87
88 #ifdef _DEBUG // Turn on memory leak checking on Windows.
89 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF |_CRTDBG_LEAK_CHECK_DF);
90 if (FLAG_crt_break_alloc >= 0) {
91 _crtBreakAlloc = FLAG_crt_break_alloc;
92 }
93 #endif // _DEBUG
94 #endif // WIN32
95
96 talk_base::Filesystem::SetOrganizationName("google");
97 talk_base::Filesystem::SetApplicationName("unittest");
98
99 // By default, log timestamps. Allow overrides by used of a --log flag.
100 talk_base::LogMessage::LogTimestamps();
101 if (*FLAG_log != '\0') {
102 talk_base::LogMessage::ConfigureLogging(FLAG_log, "unittest.log");
103 }
104
105 int res = RUN_ALL_TESTS();
106
107 // clean up logging so we don't appear to leak memory.
108 talk_base::LogMessage::ConfigureLogging("", "");
109
110 #ifdef WIN32
111 // Unhook crt function so that we don't ever log after statics have been
112 // uninitialized.
113 if (!FLAG_default_error_handlers)
114 _CrtSetReportHook2(_CRT_RPTHOOK_REMOVE, TestCrtReportHandler);
115 #endif
116
117 return res;
118 }
119