Use gtest and gmock if installed.
[platform/upstream/glog.git] / src / googletest.h
1 #ifdef GOOGLETEST_H__
2 #error You must not include this file twice.
3 #endif
4 #define GOOGLETEST_H__
5
6 #include <ctype.h>
7 #include <setjmp.h>
8 #include <time.h>
9
10 #include <map>
11 #include <sstream>
12 #include <string>
13 #include <vector>
14
15 #include <sys/types.h>
16 #include <sys/stat.h>
17 #include <fcntl.h>
18 #ifdef HAVE_UNISTD_H
19 # include <unistd.h>
20 #endif
21
22 #include "base/commandlineflags.h"
23
24 using std::map;
25 using std::string;
26 using std::vector;
27
28 _START_GOOGLE_NAMESPACE_
29
30 extern GOOGLE_GLOG_DLL_DECL void (*g_logging_fail_func)();
31
32 _END_GOOGLE_NAMESPACE_
33
34 #undef GOOGLE_GLOG_DLL_DECL
35 #define GOOGLE_GLOG_DLL_DECL
36
37 static string GetTempDir() {
38 #ifndef OS_WINDOWS
39   return "/tmp";
40 #else
41   char tmp[MAX_PATH];
42   GetTempPathA(MAX_PATH, tmp);
43   return tmp;
44 #endif
45 }
46
47 #ifdef OS_WINDOWS
48 // The test will run in glog/vsproject/<project name>
49 // (e.g., glog/vsproject/logging_unittest).
50 static const char TEST_SRC_DIR[] = "../..";
51 #else
52 static const char TEST_SRC_DIR[] = ".";
53 #endif
54
55 DEFINE_string(test_tmpdir, GetTempDir(), "Dir we use for temp files");
56 DEFINE_string(test_srcdir, TEST_SRC_DIR,
57               "Source-dir root, needed to find glog_unittest_flagfile");
58 #ifdef NDEBUG
59 DEFINE_int32(benchmark_iters, 100000000, "Number of iterations per benchmark");
60 #else
61 DEFINE_int32(benchmark_iters, 1000000, "Number of iterations per benchmark");
62 #endif
63
64 #ifdef HAVE_LIB_GTEST
65 # include <gtest/gtest.h>
66 // Use our ASSERT_DEATH implementation.
67 # undef ASSERT_DEATH
68 # undef ASSERT_DEBUG_DEATH
69 using testing::InitGoogleTest;
70 #else
71
72 _START_GOOGLE_NAMESPACE_
73
74 void InitGoogleTest(int* argc, char** argv) {}
75
76 // The following is some bare-bones testing infrastructure
77
78 #define EXPECT_TRUE(cond)                               \
79   do {                                                  \
80     if (!(cond)) {                                      \
81       fprintf(stderr, "Check failed: %s\n", #cond);     \
82       exit(1);                                          \
83     }                                                   \
84   } while (0)
85
86 #define EXPECT_FALSE(cond)  EXPECT_TRUE(!(cond))
87
88 #define EXPECT_OP(op, val1, val2)                                       \
89   do {                                                                  \
90     if (!((val1) op (val2))) {                                          \
91       fprintf(stderr, "Check failed: %s %s %s\n", #val1, #op, #val2);   \
92       exit(1);                                                          \
93     }                                                                   \
94   } while (0)
95
96 #define EXPECT_EQ(val1, val2)  EXPECT_OP(==, val1, val2)
97 #define EXPECT_NE(val1, val2)  EXPECT_OP(!=, val1, val2)
98 #define EXPECT_GT(val1, val2)  EXPECT_OP(>, val1, val2)
99 #define EXPECT_LT(val1, val2)  EXPECT_OP(<, val1, val2)
100
101 #define EXPECT_NAN(arg)                                         \
102   do {                                                          \
103     if (!isnan(arg)) {                                          \
104       fprintf(stderr, "Check failed: isnan(%s)\n", #arg);       \
105       exit(1);                                                  \
106     }                                                           \
107   } while (0)
108
109 #define EXPECT_INF(arg)                                         \
110   do {                                                          \
111     if (!isinf(arg)) {                                          \
112       fprintf(stderr, "Check failed: isinf(%s)\n", #arg);       \
113       exit(1);                                                  \
114     }                                                           \
115   } while (0)
116
117 #define EXPECT_DOUBLE_EQ(val1, val2)                                    \
118   do {                                                                  \
119     if (((val1) < (val2) - 0.001 || (val1) > (val2) + 0.001)) {         \
120       fprintf(stderr, "Check failed: %s == %s\n", #val1, #val2);        \
121       exit(1);                                                          \
122     }                                                                   \
123   } while (0)
124
125 #define EXPECT_STREQ(val1, val2)                                        \
126   do {                                                                  \
127     if (strcmp((val1), (val2)) != 0) {                                  \
128       fprintf(stderr, "Check failed: streq(%s, %s)\n", #val1, #val2);   \
129       exit(1);                                                          \
130     }                                                                   \
131   } while (0)
132
133 vector<void (*)()> g_testlist;  // the tests to run
134
135 #define TEST(a, b)                                      \
136   struct Test_##a##_##b {                               \
137     Test_##a##_##b() { g_testlist.push_back(&Run); }    \
138     static void Run() { FlagSaver fs; RunTest(); }      \
139     static void RunTest();                              \
140   };                                                    \
141   static Test_##a##_##b g_test_##a##_##b;               \
142   void Test_##a##_##b::RunTest()
143
144
145 static int RUN_ALL_TESTS() {
146   vector<void (*)()>::const_iterator it;
147   for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
148     (*it)();
149   }
150   fprintf(stderr, "Passed %d tests\n\nPASS\n", (int)g_testlist.size());
151   return 0;
152 }
153
154 _END_GOOGLE_NAMESPACE_
155
156 #endif
157
158 _START_GOOGLE_NAMESPACE_
159
160 static bool g_called_abort;
161 static jmp_buf g_jmp_buf;
162 static void CalledAbort() {
163   g_called_abort = true;
164   longjmp(g_jmp_buf, 1);
165 }
166
167 #ifdef OS_WINDOWS
168 // TODO(hamaji): Death test somehow doesn't work in Windows.
169 #define ASSERT_DEATH(fn, msg)
170 #else
171 #define ASSERT_DEATH(fn, msg)                                           \
172   do {                                                                  \
173     g_called_abort = false;                                             \
174     /* in logging.cc */                                                 \
175     void (*original_logging_fail_func)() = g_logging_fail_func;         \
176     g_logging_fail_func = &CalledAbort;                                 \
177     if (!setjmp(g_jmp_buf)) fn;                                         \
178     /* set back to their default */                                     \
179     g_logging_fail_func = original_logging_fail_func;                   \
180     if (!g_called_abort) {                                              \
181       fprintf(stderr, "Function didn't die (%s): %s\n", msg, #fn);      \
182       exit(1);                                                          \
183     }                                                                   \
184   } while (0)
185 #endif
186
187 #ifdef NDEBUG
188 #define ASSERT_DEBUG_DEATH(fn, msg)
189 #else
190 #define ASSERT_DEBUG_DEATH(fn, msg) ASSERT_DEATH(fn, msg)
191 #endif  // NDEBUG
192
193 // Benchmark tools.
194
195 #define BENCHMARK(n) static BenchmarkRegisterer __benchmark_ ## n (#n, &n);
196
197 map<string, void (*)(int)> g_benchlist;  // the benchmarks to run
198
199 class BenchmarkRegisterer {
200  public:
201   BenchmarkRegisterer(const char* name, void (*function)(int iters)) {
202     EXPECT_TRUE(g_benchlist.insert(std::make_pair(name, function)).second);
203   }
204 };
205
206 static void RunSpecifiedBenchmarks() {
207   int iter_cnt = FLAGS_benchmark_iters;
208   puts("Benchmark\tTime(ns)\tIterations");
209   for (map<string, void (*)(int)>::const_iterator iter = g_benchlist.begin();
210        iter != g_benchlist.end();
211        ++iter) {
212     clock_t start = clock();
213     iter->second(iter_cnt);
214     double elapsed_ns =
215         ((double)clock() - start) / CLOCKS_PER_SEC * 1000*1000*1000;
216     printf("%s\t%8.2lf\t%10d\n",
217            iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt);
218   }
219   puts("");
220 }
221
222 // ----------------------------------------------------------------------
223 // Golden file functions
224 // ----------------------------------------------------------------------
225
226 class CapturedStream {
227  public:
228   CapturedStream(int fd, const string & filename) :
229     fd_(fd),
230     uncaptured_fd_(-1),
231     filename_(filename) {
232     Capture();
233   }
234
235   ~CapturedStream() {
236     if (uncaptured_fd_ != -1) {
237       CHECK(close(uncaptured_fd_) != -1);
238     }
239   }
240
241   // Start redirecting output to a file
242   void Capture() {
243     // Keep original stream for later
244     CHECK(uncaptured_fd_ == -1) << ", Stream " << fd_ << " already captured!";
245     uncaptured_fd_ = dup(fd_);
246     CHECK(uncaptured_fd_ != -1);
247
248     // Open file to save stream to
249     int cap_fd = open(filename_.c_str(),
250                       O_CREAT | O_TRUNC | O_WRONLY,
251                       S_IRUSR | S_IWUSR);
252     CHECK(cap_fd != -1);
253
254     // Send stdout/stderr to this file
255     fflush(NULL);
256     CHECK(dup2(cap_fd, fd_) != -1);
257     CHECK(close(cap_fd) != -1);
258   }
259
260   // Remove output redirection
261   void StopCapture() {
262     // Restore original stream
263     if (uncaptured_fd_ != -1) {
264       fflush(NULL);
265       CHECK(dup2(uncaptured_fd_, fd_) != -1);
266     }
267   }
268
269   const string & filename() const { return filename_; }
270
271  private:
272   int fd_;             // file descriptor being captured
273   int uncaptured_fd_;  // where the stream was originally being sent to
274   string filename_;    // file where stream is being saved
275 };
276 static CapturedStream * s_captured_streams[STDERR_FILENO+1];
277 // Redirect a file descriptor to a file.
278 //   fd       - Should be STDOUT_FILENO or STDERR_FILENO
279 //   filename - File where output should be stored
280 static void CaptureTestOutput(int fd, const string & filename) {
281   CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
282   CHECK(s_captured_streams[fd] == NULL);
283   s_captured_streams[fd] = new CapturedStream(fd, filename);
284 }
285 static void CaptureTestStderr() {
286   CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err");
287 }
288 // Return the size (in bytes) of a file
289 static size_t GetFileSize(FILE * file) {
290   fseek(file, 0, SEEK_END);
291   return static_cast<size_t>(ftell(file));
292 }
293 // Read the entire content of a file as a string
294 static string ReadEntireFile(FILE * file) {
295   const size_t file_size = GetFileSize(file);
296   char * const buffer = new char[file_size];
297
298   size_t bytes_last_read = 0;  // # of bytes read in the last fread()
299   size_t bytes_read = 0;       // # of bytes read so far
300
301   fseek(file, 0, SEEK_SET);
302
303   // Keep reading the file until we cannot read further or the
304   // pre-determined file size is reached.
305   do {
306     bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
307     bytes_read += bytes_last_read;
308   } while (bytes_last_read > 0 && bytes_read < file_size);
309
310   const string content = string(buffer, buffer+bytes_read);
311   delete[] buffer;
312
313   return content;
314 }
315 // Get the captured stdout (when fd is STDOUT_FILENO) or stderr (when
316 // fd is STDERR_FILENO) as a string
317 static string GetCapturedTestOutput(int fd) {
318   CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO);
319   CapturedStream * const cap = s_captured_streams[fd];
320   CHECK(cap)
321     << ": did you forget CaptureTestStdout() or CaptureTestStderr()?";
322
323   // Make sure everything is flushed.
324   cap->StopCapture();
325
326   // Read the captured file.
327   FILE * const file = fopen(cap->filename().c_str(), "r");
328   const string content = ReadEntireFile(file);
329   fclose(file);
330
331   delete cap;
332   s_captured_streams[fd] = NULL;
333
334   return content;
335 }
336 // Get the captured stderr of a test as a string.
337 static string GetCapturedTestStderr() {
338   return GetCapturedTestOutput(STDERR_FILENO);
339 }
340
341 // Check if the string is [IWEF](\d{4}|DATE)
342 static bool IsLoggingPrefix(const string& s) {
343   if (s.size() != 5) return false;
344   if (!strchr("IWEF", s[0])) return false;
345   for (int i = 1; i <= 4; ++i) {
346     if (!isdigit(s[i]) && s[i] != "DATE"[i-1]) return false;
347   }
348   return true;
349 }
350
351 // Convert log output into normalized form.
352 //
353 // Example:
354 //     I0102 030405 logging_unittest.cc:345] RAW: vlog -1
355 //  => IDATE TIME__ logging_unittest.cc:LINE] RAW: vlog -1
356 static string MungeLine(const string& line) {
357   std::istringstream iss(line);
358   string before, logcode_date, time, thread_lineinfo;
359   iss >> logcode_date;
360   while (!IsLoggingPrefix(logcode_date)) {
361     before += " " + logcode_date;
362     if (!(iss >> logcode_date)) {
363       // We cannot find the header of log output.
364       return before;
365     }
366   }
367   if (!before.empty()) before += " ";
368   iss >> time;
369   CHECK_EQ(6, time.size());
370   iss >> thread_lineinfo;
371   CHECK(!thread_lineinfo.empty());
372   if (thread_lineinfo[thread_lineinfo.size() - 1] != ']') {
373     // We found thread ID.
374     string tmp;
375     iss >> tmp;
376     CHECK(!tmp.empty());
377     CHECK_EQ(']', tmp[tmp.size() - 1]);
378     thread_lineinfo = "THREADID " + tmp;
379   }
380   size_t index = thread_lineinfo.find(':');
381   CHECK_NE(string::npos, index);
382   thread_lineinfo = thread_lineinfo.substr(0, index+1) + "LINE]";
383   string rest;
384   std::getline(iss, rest);
385   return (before + logcode_date[0] + "DATE TIME__ " + thread_lineinfo +
386           MungeLine(rest));
387 }
388
389 static void StringReplace(string* str,
390                           const string& oldsub,
391                           const string& newsub) {
392   size_t pos = str->find(oldsub);
393   if (pos != string::npos) {
394     str->replace(pos, oldsub.size(), newsub.c_str());
395   }
396 }
397
398 static string Munge(const string& filename) {
399   FILE* fp = fopen(filename.c_str(), "rb");
400   CHECK(fp != NULL) << filename << ": couldn't open";
401   char buf[4096];
402   string result;
403   while (fgets(buf, 4095, fp)) {
404     string line = MungeLine(buf);
405     char null_str[256];
406     sprintf(null_str, "%p", NULL);
407     StringReplace(&line, "__NULLP__", null_str);
408     // Remove 0x prefix produced by %p. VC++ doesn't put the prefix.
409     StringReplace(&line, " 0x", " ");
410
411     char errmsg_buf[100];
412     posix_strerror_r(0, errmsg_buf, sizeof(errmsg_buf));
413     if (*errmsg_buf == '\0') {
414       // MacOSX 10.4 and FreeBSD return empty string for errno=0.
415       // In such case, the we need to remove an extra space.
416       StringReplace(&line, "__SUCCESS__ ", "");
417     } else {
418       StringReplace(&line, "__SUCCESS__", errmsg_buf);
419     }
420     StringReplace(&line, "__ENOENT__", strerror(ENOENT));
421     StringReplace(&line, "__EINTR__", strerror(EINTR));
422     StringReplace(&line, "__ENXIO__", strerror(ENXIO));
423     StringReplace(&line, "__ENOEXEC__", strerror(ENOEXEC));
424     result += line + "\n";
425   }
426   fclose(fp);
427   return result;
428 }
429
430 static void WriteToFile(const string& body, const string& file) {
431   FILE* fp = fopen(file.c_str(), "wb");
432   fwrite(body.data(), 1, body.size(), fp);
433   fclose(fp);
434 }
435
436 static bool MungeAndDiffTestStderr(const string& golden_filename) {
437   CapturedStream* cap = s_captured_streams[STDERR_FILENO];
438   CHECK(cap) << ": did you forget CaptureTestStderr()?";
439
440   cap->StopCapture();
441
442   // Run munge
443   const string captured = Munge(cap->filename());
444   const string golden = Munge(golden_filename);
445   if (captured != golden) {
446     fprintf(stderr,
447             "Test with golden file failed. We'll try to show the diff:\n");
448     string munged_golden = golden_filename + ".munged";
449     WriteToFile(golden, munged_golden);
450     string munged_captured = cap->filename() + ".munged";
451     WriteToFile(captured, munged_captured);
452     string diffcmd("diff -u " + munged_golden + " " + munged_captured);
453     if (system(diffcmd.c_str()) != 0) {
454       fprintf(stderr, "diff command was failed.\n");
455     }
456     unlink(munged_golden.c_str());
457     unlink(munged_captured.c_str());
458     return false;
459   }
460   LOG(INFO) << "Diff was successful";
461   return true;
462 }
463
464 // Save flags used from logging_unittest.cc.
465 #ifndef HAVE_LIB_GFLAGS
466 struct FlagSaver {
467   FlagSaver()
468       : v_(FLAGS_v),
469         stderrthreshold_(FLAGS_stderrthreshold),
470         logtostderr_(FLAGS_logtostderr),
471         alsologtostderr_(FLAGS_alsologtostderr) {}
472   ~FlagSaver() {
473     FLAGS_v = v_;
474     FLAGS_stderrthreshold = stderrthreshold_;
475     FLAGS_logtostderr = logtostderr_;
476     FLAGS_alsologtostderr = alsologtostderr_;
477   }
478   int v_;
479   int stderrthreshold_;
480   bool logtostderr_;
481   bool alsologtostderr_;
482 };
483 #endif
484
485 class Thread {
486  public:
487   void SetJoinable(bool joinable) {}
488 #if defined(HAVE_PTHREAD)
489   void Start() {
490     pthread_create(&th_, NULL, &Thread::InvokeThread, this);
491   }
492   void Join() {
493     pthread_join(th_, NULL);
494   }
495 #elif defined(OS_WINDOWS)
496   void Start() {
497     handle_ = CreateThread(NULL,
498                            0,
499                            (LPTHREAD_START_ROUTINE)&Thread::InvokeThread,
500                            (LPVOID)this,
501                            0,
502                            &th_);
503     CHECK(handle_) << "CreateThread";
504   }
505   void Join() {
506     WaitForSingleObject(handle_, INFINITE);
507   }
508 #else
509 # error No thread implementation.
510 #endif
511
512  protected:
513   virtual void Run() = 0;
514
515  private:
516   static void* InvokeThread(void* self) {
517     ((Thread*)self)->Run();
518     return NULL;
519   }
520
521   pthread_t th_;
522 #ifdef OS_WINDOWS
523   HANDLE handle_;
524 #endif
525 };
526
527 static void SleepForMilliseconds(int t) {
528 #ifndef OS_WINDOWS
529   usleep(t * 1000);
530 #else
531   Sleep(t);
532 #endif
533 }
534
535 // Add hook for operator new to ensure there are no memory allocation.
536
537 void (*g_new_hook)() = NULL;
538
539 _END_GOOGLE_NAMESPACE_
540
541 void* operator new(size_t size) {
542   if (GOOGLE_NAMESPACE::g_new_hook) {
543     GOOGLE_NAMESPACE::g_new_hook();
544   }
545   return malloc(size);
546 }
547
548 void* operator new[](size_t size) {
549   return ::operator new(size);
550 }
551
552 void operator delete(void* p) {
553   free(p);
554 }
555
556 void operator delete[](void* p) {
557   ::operator delete(p);
558 }