Home | History | Annotate | Download | only in gtest
      1 // Copyright 2008, 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: wan (at) google.com (Zhanyong Wan)
     31 
     32 #include <gtest/internal/gtest-port.h>
     33 
     34 #include <limits.h>
     35 #ifdef GTEST_HAS_DEATH_TEST
     36 #include <regex.h>
     37 #endif  // GTEST_HAS_DEATH_TEST
     38 #include <stdlib.h>
     39 #include <stdio.h>
     40 
     41 #include <gtest/gtest-spi.h>
     42 #include <gtest/gtest-message.h>
     43 #include <gtest/internal/gtest-string.h>
     44 
     45 namespace testing {
     46 namespace internal {
     47 
     48 #ifdef GTEST_HAS_DEATH_TEST
     49 
     50 // Implements RE.  Currently only needed for death tests.
     51 
     52 RE::~RE() {
     53   regfree(&regex_);
     54   free(const_cast<char*>(pattern_));
     55 }
     56 
     57 // Returns true iff str contains regular expression re.
     58 bool RE::PartialMatch(const char* str, const RE& re) {
     59   if (!re.is_valid_) return false;
     60 
     61   regmatch_t match;
     62   return regexec(&re.regex_, str, 1, &match, 0) == 0;
     63 }
     64 
     65 // Initializes an RE from its string representation.
     66 void RE::Init(const char* regex) {
     67   pattern_ = strdup(regex);
     68   is_valid_ = regcomp(&regex_, regex, REG_EXTENDED) == 0;
     69   EXPECT_TRUE(is_valid_)
     70       << "Regular expression \"" << regex
     71       << "\" is not a valid POSIX Extended regular expression.";
     72 }
     73 
     74 #endif  // GTEST_HAS_DEATH_TEST
     75 
     76 // Logs a message at the given severity level.
     77 void GTestLog(GTestLogSeverity severity, const char* file,
     78               int line, const char* msg) {
     79   const char* const marker =
     80       severity == GTEST_INFO ?    "[  INFO ]" :
     81       severity == GTEST_WARNING ? "[WARNING]" :
     82       severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
     83   fprintf(stderr, "\n%s %s:%d: %s\n", marker, file, line, msg);
     84   if (severity == GTEST_FATAL) {
     85     abort();
     86   }
     87 }
     88 
     89 #ifdef GTEST_HAS_DEATH_TEST
     90 
     91 // Defines the stderr capturer.
     92 
     93 class CapturedStderr {
     94  public:
     95   // The ctor redirects stderr to a temporary file.
     96   CapturedStderr() {
     97     uncaptured_fd_ = dup(STDERR_FILENO);
     98 
     99     char name_template[] = "captured_stderr.XXXXXX";
    100     const int captured_fd = mkstemp(name_template);
    101     filename_ = name_template;
    102     fflush(NULL);
    103     dup2(captured_fd, STDERR_FILENO);
    104     close(captured_fd);
    105   }
    106 
    107   ~CapturedStderr() {
    108     remove(filename_.c_str());
    109   }
    110 
    111   // Stops redirecting stderr.
    112   void StopCapture() {
    113     // Restores the original stream.
    114     fflush(NULL);
    115     dup2(uncaptured_fd_, STDERR_FILENO);
    116     close(uncaptured_fd_);
    117     uncaptured_fd_ = -1;
    118   }
    119 
    120   // Returns the name of the temporary file holding the stderr output.
    121   // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we
    122   // can use it here.
    123   ::std::string filename() const { return filename_; }
    124 
    125  private:
    126   int uncaptured_fd_;
    127   ::std::string filename_;
    128 };
    129 
    130 static CapturedStderr* g_captured_stderr = NULL;
    131 
    132 // Returns the size (in bytes) of a file.
    133 static size_t GetFileSize(FILE * file) {
    134   fseek(file, 0, SEEK_END);
    135   return static_cast<size_t>(ftell(file));
    136 }
    137 
    138 // Reads the entire content of a file as a string.
    139 // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can
    140 // use it here.
    141 static ::std::string ReadEntireFile(FILE * file) {
    142   const size_t file_size = GetFileSize(file);
    143   char* const buffer = new char[file_size];
    144 
    145   size_t bytes_last_read = 0;  // # of bytes read in the last fread()
    146   size_t bytes_read = 0;       // # of bytes read so far
    147 
    148   fseek(file, 0, SEEK_SET);
    149 
    150   // Keeps reading the file until we cannot read further or the
    151   // pre-determined file size is reached.
    152   do {
    153     bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
    154     bytes_read += bytes_last_read;
    155   } while (bytes_last_read > 0 && bytes_read < file_size);
    156 
    157   const ::std::string content(buffer, buffer+bytes_read);
    158   delete[] buffer;
    159 
    160   return content;
    161 }
    162 
    163 // Starts capturing stderr.
    164 void CaptureStderr() {
    165   if (g_captured_stderr != NULL) {
    166     GTEST_LOG(FATAL, "Only one stderr capturer can exist at one time.");
    167   }
    168   g_captured_stderr = new CapturedStderr;
    169 }
    170 
    171 // Stops capturing stderr and returns the captured string.
    172 // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can
    173 // use it here.
    174 ::std::string GetCapturedStderr() {
    175   g_captured_stderr->StopCapture();
    176   FILE* const file = fopen(g_captured_stderr->filename().c_str(), "r");
    177   const ::std::string content = ReadEntireFile(file);
    178   fclose(file);
    179 
    180   delete g_captured_stderr;
    181   g_captured_stderr = NULL;
    182 
    183   return content;
    184 }
    185 
    186 // A copy of all command line arguments.  Set by InitGoogleTest().
    187 ::std::vector<String> g_argvs;
    188 
    189 // Returns the command line as a vector of strings.
    190 const ::std::vector<String>& GetArgvs() { return g_argvs; }
    191 
    192 #endif  // GTEST_HAS_DEATH_TEST
    193 
    194 // Returns the name of the environment variable corresponding to the
    195 // given flag.  For example, FlagToEnvVar("foo") will return
    196 // "GTEST_FOO" in the open-source version.
    197 static String FlagToEnvVar(const char* flag) {
    198   const String full_flag = (Message() << GTEST_FLAG_PREFIX << flag).GetString();
    199 
    200   Message env_var;
    201   for (int i = 0; i != full_flag.GetLength(); i++) {
    202     env_var << static_cast<char>(toupper(full_flag.c_str()[i]));
    203   }
    204 
    205   return env_var.GetString();
    206 }
    207 
    208 // Reads and returns the Boolean environment variable corresponding to
    209 // the given flag; if it's not set, returns default_value.
    210 //
    211 // The value is considered true iff it's not "0".
    212 bool BoolFromGTestEnv(const char* flag, bool default_value) {
    213   const String env_var = FlagToEnvVar(flag);
    214   const char* const string_value = GetEnv(env_var.c_str());
    215   return string_value == NULL ?
    216       default_value : strcmp(string_value, "0") != 0;
    217 }
    218 
    219 // Parses 'str' for a 32-bit signed integer.  If successful, writes
    220 // the result to *value and returns true; otherwise leaves *value
    221 // unchanged and returns false.
    222 bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
    223   // Parses the environment variable as a decimal integer.
    224   char* end = NULL;
    225   const long long_value = strtol(str, &end, 10);  // NOLINT
    226 
    227   // Has strtol() consumed all characters in the string?
    228   if (*end != '\0') {
    229     // No - an invalid character was encountered.
    230     Message msg;
    231     msg << "WARNING: " << src_text
    232         << " is expected to be a 32-bit integer, but actually"
    233         << " has value \"" << str << "\".\n";
    234     printf("%s", msg.GetString().c_str());
    235     fflush(stdout);
    236     return false;
    237   }
    238 
    239   // Is the parsed value in the range of an Int32?
    240   const Int32 result = static_cast<Int32>(long_value);
    241   if (long_value == LONG_MAX || long_value == LONG_MIN ||
    242       // The parsed value overflows as a long.  (strtol() returns
    243       // LONG_MAX or LONG_MIN when the input overflows.)
    244       result != long_value
    245       // The parsed value overflows as an Int32.
    246       ) {
    247     Message msg;
    248     msg << "WARNING: " << src_text
    249         << " is expected to be a 32-bit integer, but actually"
    250         << " has value " << str << ", which overflows.\n";
    251     printf("%s", msg.GetString().c_str());
    252     fflush(stdout);
    253     return false;
    254   }
    255 
    256   *value = result;
    257   return true;
    258 }
    259 
    260 // Reads and returns a 32-bit integer stored in the environment
    261 // variable corresponding to the given flag; if it isn't set or
    262 // doesn't represent a valid 32-bit integer, returns default_value.
    263 Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
    264   const String env_var = FlagToEnvVar(flag);
    265   const char* const string_value = GetEnv(env_var.c_str());
    266   if (string_value == NULL) {
    267     // The environment variable is not set.
    268     return default_value;
    269   }
    270 
    271   Int32 result = default_value;
    272   if (!ParseInt32(Message() << "Environment variable " << env_var,
    273                   string_value, &result)) {
    274     printf("The default value %s is used.\n",
    275            (Message() << default_value).GetString().c_str());
    276     fflush(stdout);
    277     return default_value;
    278   }
    279 
    280   return result;
    281 }
    282 
    283 // Reads and returns the string environment variable corresponding to
    284 // the given flag; if it's not set, returns default_value.
    285 const char* StringFromGTestEnv(const char* flag, const char* default_value) {
    286   const String env_var = FlagToEnvVar(flag);
    287   const char* const value = GetEnv(env_var.c_str());
    288   return value == NULL ? default_value : value;
    289 }
    290 
    291 }  // namespace internal
    292 }  // namespace testing
    293