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