1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.
3 // http://code.google.com/p/protobuf/
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
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>
24 #include <sys/types.h>
40 #define mkdir(name, mode) mkdir(name)
45 #define O_BINARY _O_BINARY
47 #define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
51 string
TestSourceDir() {
53 // Look for the "src" directory.
56 while (!File::Exists(prefix
+ "/src/google/protobuf")) {
57 if (!File::Exists(prefix
)) {
59 << "Could not find protobuf source code. Please run tests from "
60 "somewhere within the protobuf source package.";
64 return prefix
+ "/src";
66 // automake sets the "srcdir" environment variable.
67 char* result
= getenv("srcdir");
69 // Otherwise, the test must be run from the source directory.
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
83 string result
= tmpnam(NULL
);
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
, "\\")) {
94 // Creates a temporary directory on demand and deletes it when the process
96 class TempDirDeleter
{
100 if (!name_
.empty()) {
101 File::DeleteRecursively(name_
, NULL
, NULL
);
105 string
GetTempDir() {
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");
121 TempDirDeleter temp_dir_deleter_
;
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);
147 string
GetCapturedTestStderr() {
148 GOOGLE_CHECK_NE(original_stderr_
, -1) << "Not capturing.";
151 dup2(original_stderr_
, 2);
152 original_stderr_
= -1;
155 File::ReadFileToStringOrDie(stderr_capture_filename_
, &result
);
157 remove(stderr_capture_filename_
.c_str());
162 ScopedMemoryLog
* ScopedMemoryLog::active_log_
= NULL
;
164 ScopedMemoryLog::ScopedMemoryLog() {
165 GOOGLE_CHECK(active_log_
== NULL
);
167 old_handler_
= SetLogHandler(&HandleLog
);
170 ScopedMemoryLog::~ScopedMemoryLog() {
171 SetLogHandler(old_handler_
);
175 const vector
<string
>& ScopedMemoryLog::GetMessages(LogLevel dummy
) const {
176 GOOGLE_CHECK_EQ(dummy
, ERROR
);
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