Initial import of v2.0.0beta
[protobuf.git] / src / google / protobuf / testing / googletest.cc
blobaabc657fb789e1512315a65285fd8b73aadea2d1
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
17 // Author: kenton@google.com (Kenton Varda)
18 // emulates google3/testing/base/public/googletest.cc
20 #include <google/protobuf/testing/googletest.h>
21 #include <google/protobuf/testing/file.h>
22 #include <google/protobuf/stubs/strutil.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <errno.h>
26 #include <stdlib.h>
27 #ifdef _MSC_VER
28 #include <io.h>
29 #include <direct.h>
30 #else
31 #include <unistd.h>
32 #endif
33 #include <stdio.h>
34 #include <fcntl.h>
36 namespace google {
37 namespace protobuf {
39 #ifdef _WIN32
40 #define mkdir(name, mode) mkdir(name)
41 #endif
43 #ifndef O_BINARY
44 #ifdef _O_BINARY
45 #define O_BINARY _O_BINARY
46 #else
47 #define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
48 #endif
49 #endif
51 string TestSourceDir() {
52 #ifdef _MSC_VER
53 // Look for the "src" directory.
54 string prefix = ".";
56 while (!File::Exists(prefix + "/src/google/protobuf")) {
57 if (!File::Exists(prefix)) {
58 GOOGLE_LOG(FATAL)
59 << "Could not find protobuf source code. Please run tests from "
60 "somewhere within the protobuf source package.";
62 prefix += "/..";
64 return prefix + "/src";
65 #else
66 // automake sets the "srcdir" environment variable.
67 char* result = getenv("srcdir");
68 if (result == NULL) {
69 // Otherwise, the test must be run from the source directory.
70 return ".";
71 } else {
72 return result;
74 #endif
77 namespace {
79 string GetTemporaryDirectoryName() {
80 // tmpnam() is generally not considered safe but we're only using it for
81 // testing. We cannot use tmpfile() or mkstemp() since we're creating a
82 // directory.
83 string result = tmpnam(NULL);
84 #ifdef _WIN32
85 // On Win32, tmpnam() returns a file prefixed with '\', but which is supposed
86 // to be used in the current working directory. WTF?
87 if (HasPrefixString(result, "\\")) {
88 result.erase(0, 1);
90 #endif // _WIN32
91 return result;
94 // Creates a temporary directory on demand and deletes it when the process
95 // quits.
96 class TempDirDeleter {
97 public:
98 TempDirDeleter() {}
99 ~TempDirDeleter() {
100 if (!name_.empty()) {
101 File::DeleteRecursively(name_, NULL, NULL);
105 string GetTempDir() {
106 if (name_.empty()) {
107 name_ = GetTemporaryDirectoryName();
108 GOOGLE_CHECK(mkdir(name_.c_str(), 0777) == 0) << strerror(errno);
110 // Stick a file in the directory that tells people what this is, in case
111 // we abort and don't get a chance to delete it.
112 File::WriteStringToFileOrDie("", name_ + "/TEMP_DIR_FOR_PROTOBUF_TESTS");
114 return name_;
117 private:
118 string name_;
121 TempDirDeleter temp_dir_deleter_;
123 } // namespace
125 string TestTempDir() {
126 return temp_dir_deleter_.GetTempDir();
129 static string stderr_capture_filename_;
130 static int original_stderr_ = -1;
132 void CaptureTestStderr() {
133 GOOGLE_CHECK_EQ(original_stderr_, -1) << "Already capturing.";
135 stderr_capture_filename_ = TestTempDir() + "/captured_stderr";
137 int fd = open(stderr_capture_filename_.c_str(),
138 O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0777);
139 GOOGLE_CHECK(fd >= 0) << "open: " << strerror(errno);
141 original_stderr_ = dup(2);
142 close(2);
143 dup2(fd, 2);
144 close(fd);
147 string GetCapturedTestStderr() {
148 GOOGLE_CHECK_NE(original_stderr_, -1) << "Not capturing.";
150 close(2);
151 dup2(original_stderr_, 2);
152 original_stderr_ = -1;
154 string result;
155 File::ReadFileToStringOrDie(stderr_capture_filename_, &result);
157 remove(stderr_capture_filename_.c_str());
159 return result;
162 ScopedMemoryLog* ScopedMemoryLog::active_log_ = NULL;
164 ScopedMemoryLog::ScopedMemoryLog() {
165 GOOGLE_CHECK(active_log_ == NULL);
166 active_log_ = this;
167 old_handler_ = SetLogHandler(&HandleLog);
170 ScopedMemoryLog::~ScopedMemoryLog() {
171 SetLogHandler(old_handler_);
172 active_log_ = NULL;
175 const vector<string>& ScopedMemoryLog::GetMessages(LogLevel dummy) const {
176 GOOGLE_CHECK_EQ(dummy, ERROR);
177 return messages_;
180 void ScopedMemoryLog::HandleLog(LogLevel level, const char* filename,
181 int line, const string& message) {
182 GOOGLE_CHECK(active_log_ != NULL);
183 if (level == ERROR) {
184 active_log_->messages_.push_back(message);
188 } // namespace protobuf
189 } // namespace google