Home | History | Annotate | Download | only in base
      1 // Copyright 2014 The Android Open Source Project
      2 //
      3 // This software is licensed under the terms of the GNU General Public
      4 // License version 2, as published by the Free Software Foundation, and
      5 // may be copied, distributed, and modified under those terms.
      6 //
      7 // This program is distributed in the hope that it will be useful,
      8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 // GNU General Public License for more details.
     11 
     12 #include "android/base/Log.h"
     13 
     14 #include <errno.h>
     15 #include <stdio.h>
     16 #include <string.h>
     17 
     18 #include <gtest/gtest.h>
     19 
     20 namespace android {
     21 namespace base {
     22 
     23 // Create a severity level which is guaranteed to never generate a log
     24 // message. See LogOnlyEvaluatesArgumentsIfNeeded for usage.
     25 const LogSeverity LOG_INVISIBLE = -10000;
     26 
     27 class LogTest : public ::testing::Test, android::base::testing::LogOutput {
     28 public:
     29     LogTest() : mFatal(false) {
     30         mSavedOutput = ::android::base::testing::LogOutput::setNewOutput(this);
     31         mExpected[0] = '\0';
     32         mBuffer[0] = '\x7f';
     33         mBuffer[1] = '\0';
     34     }
     35 
     36     ~LogTest() {
     37         ::android::base::testing::LogOutput::setNewOutput(mSavedOutput);
     38     }
     39 
     40     void setExpected(LogSeverity severity, int line, const char* suffix) {
     41         mExpectedParams.file = __FILE__;
     42         mExpectedParams.lineno = line;
     43         mExpectedParams.severity = severity;
     44         snprintf(mExpected, sizeof(mExpected), "%s", suffix);
     45     }
     46 
     47     // LogOutput override
     48     void logMessage(const LogParams& params,
     49                     const char* message,
     50                     size_t messageLen) {
     51         mParams = params;
     52         if (messageLen > sizeof(mBuffer) - 1)
     53             messageLen = sizeof(mBuffer) - 1;
     54         ::memcpy(mBuffer, message, messageLen);
     55         mBuffer[messageLen] = '\0';
     56         mFatal = (params.severity >= LOG_FATAL);
     57     }
     58 
     59 protected:
     60     ::android::base::testing::LogOutput* mSavedOutput;
     61     LogParams mParams;
     62     LogParams mExpectedParams;
     63     char mExpected[1024];
     64     char mBuffer[1024];
     65     bool mFatal;
     66 };
     67 
     68 class CheckTest : public LogTest {
     69 };
     70 
     71 #if ENABLE_DCHECK != 0
     72 class DCheckEnabledTest : public LogTest {
     73 public:
     74     DCheckEnabledTest() : LogTest() {
     75         // Ensure DCHECKS() always run.
     76         mSavedLevel = setDcheckLevel(true);
     77     }
     78 
     79     ~DCheckEnabledTest() {
     80         setDcheckLevel(mSavedLevel);
     81     }
     82 private:
     83     bool mSavedLevel;
     84 };
     85 #endif  // ENABLE_DCHECK == 0
     86 
     87 #if ENABLE_DCHECK != 2
     88 class DCheckDisabledTest : public LogTest {
     89 public:
     90     DCheckDisabledTest() : LogTest() {
     91         mSavedLevel = setDcheckLevel(false);
     92     }
     93 
     94     ~DCheckDisabledTest() {
     95         setDcheckLevel(mSavedLevel);
     96     }
     97 private:
     98     bool mSavedLevel;
     99 };
    100 #endif  // ENABLE_DCHECK != 2
    101 
    102 class PLogTest : public LogTest {
    103 public:
    104     PLogTest() : LogTest(), mForcedErrno(-1000) {}
    105 
    106     void setForcedErrno(int errnoCode) {
    107         mForcedErrno = errnoCode;
    108     }
    109 
    110     void setExpectedErrno(LogSeverity severity,
    111                           int line,
    112                           int errnoCode,
    113                           const char* suffix) {
    114         mExpectedParams.file = __FILE__;
    115         mExpectedParams.lineno = line;
    116         mExpectedParams.severity = severity;
    117         snprintf(mExpected,
    118                  sizeof(mExpected),
    119                  "%sError message: %s",
    120                  suffix,
    121                  strerror(errnoCode));
    122     }
    123 
    124     void logMessage(const LogParams& params,
    125                     const char* message,
    126                     size_t messageLen) {
    127         LogTest::logMessage(params, message, messageLen);
    128 
    129         if (mForcedErrno != -1000)
    130             errno = mForcedErrno;
    131     }
    132 
    133 protected:
    134     int mForcedErrno;
    135 };
    136 
    137 #define STRINGIFY(x) STRINGIFY_(x)
    138 #define STRINGIFY_(x) #x
    139 
    140 #define EXPECTED_STRING_PREFIX(prefix, line) \
    141   prefix ":" __FILE__ ":" STRINGIFY(line) ": "
    142 
    143 #define CHECK_EXPECTATIONS() \
    144     EXPECT_STREQ(mExpectedParams.file, mParams.file); \
    145     EXPECT_EQ(mExpectedParams.lineno, mParams.lineno); \
    146     EXPECT_EQ(mExpectedParams.severity, mParams.severity); \
    147     EXPECT_STREQ(mExpected, mBuffer)
    148 
    149 // Helper function used to set a boolean |flag|, then return |string|.
    150 static const char* setFlag(bool* flag, const char* string) {
    151     *flag = true;
    152     return string;
    153 }
    154 
    155 TEST(LogString, EmptyString) {
    156     LogString ls("");
    157     EXPECT_STREQ("", ls.string());
    158 }
    159 
    160 TEST(LogString, SimpleString) {
    161     LogString ls("Hello");
    162     EXPECT_STREQ("Hello", ls.string());
    163 }
    164 
    165 TEST(LogString, FormattedString) {
    166     LogString ls("%d plus %d equals %d", 12, 23, 35);
    167     EXPECT_STREQ("12 plus 23 equals 35", ls.string());
    168 }
    169 
    170 TEST_F(LogTest, LogInfoEmpty) {
    171     setExpected(LOG_INFO, __LINE__ + 1, "");
    172     LOG(INFO);
    173     CHECK_EXPECTATIONS();
    174 }
    175 
    176 TEST_F(LogTest, LogInfoWithString) {
    177     static const char kString[] = "Hello World!";
    178     setExpected(LOG_INFO, __LINE__ + 1, kString);
    179     LOG(INFO) << kString;
    180     CHECK_EXPECTATIONS();
    181 }
    182 
    183 TEST_F(LogTest, LogInfoWithTwoStrings) {
    184     setExpected(LOG_INFO, __LINE__ + 1, "Hello Globe!");
    185     LOG(INFO) << "Hello " << "Globe!";
    186     CHECK_EXPECTATIONS();
    187 }
    188 
    189 TEST_F(LogTest, LogInfoWithLogString) {
    190     LogString ls("Hello You!");
    191     setExpected(LOG_INFO, __LINE__ + 1, ls.string());
    192     LOG(INFO) << ls;
    193     CHECK_EXPECTATIONS();
    194 }
    195 
    196 TEST_F(LogTest, LogWarning) {
    197     static const char kWarning[] = "Elvis has left the building!";
    198     setExpected(LOG_WARNING, __LINE__ + 1, kWarning);
    199     LOG(WARNING) << kWarning;
    200     CHECK_EXPECTATIONS();
    201 }
    202 
    203 TEST_F(LogTest, LogError) {
    204     static const char kError[] = "Bad Bad Robot!";
    205     setExpected(LOG_ERROR, __LINE__ + 1, kError);
    206     LOG(ERROR) << kError;
    207 
    208     CHECK_EXPECTATIONS();
    209 }
    210 
    211 TEST_F(LogTest, LogFatal) {
    212     static const char kFatalMessage[] = "I'm dying";
    213     setExpected(LOG_FATAL, __LINE__ + 1, kFatalMessage);
    214     LOG(FATAL) << kFatalMessage;
    215     CHECK_EXPECTATIONS();
    216     EXPECT_TRUE(mFatal);
    217 }
    218 
    219 TEST_F(LogTest, LogEvaluatesArgumentsIfNeeded) {
    220     // Use LOG_FATAL since it is always active.
    221     bool flag = false;
    222     setExpected(LOG_FATAL, __LINE__ + 1, "PANIC: Flag was set!");
    223     LOG(FATAL) << "PANIC: " << setFlag(&flag, "Flag was set!");
    224     CHECK_EXPECTATIONS();
    225     EXPECT_TRUE(mFatal);
    226     EXPECT_TRUE(flag);
    227 }
    228 
    229 TEST_F(LogTest, LogOnlyEvaluatesArgumentsIfNeeded) {
    230     bool flag = false;
    231     LOG(INVISIBLE) << setFlag(&flag, "Flag was set!");
    232     EXPECT_FALSE(flag);
    233 }
    234 
    235 
    236 // TODO(digit): Convert this to a real death test when this is supported
    237 // by our version of GTest.
    238 TEST_F(CheckTest, CheckFalse) {
    239     setExpected(LOG_FATAL, __LINE__ + 1, "Check failed: false. ");
    240     CHECK(false);
    241     CHECK_EXPECTATIONS();
    242 }
    243 
    244 TEST_F(CheckTest, CheckFalseEvaluatesArguments) {
    245     bool flag = false;
    246     setExpected(LOG_FATAL, __LINE__ + 1, "Check failed: false. Flag was set!");
    247     CHECK(false) << setFlag(&flag, "Flag was set!");
    248     EXPECT_TRUE(flag);
    249     CHECK_EXPECTATIONS();
    250 }
    251 
    252 TEST_F(CheckTest, CheckTrue) {
    253     CHECK(true);
    254     EXPECT_FALSE(mFatal);
    255 }
    256 
    257 TEST_F(CheckTest, CheckTrueDoesNotEvaluateArguments) {
    258     bool flag = false;
    259     CHECK(true) << setFlag(&flag, "Flag was set!");
    260     EXPECT_FALSE(flag);
    261     EXPECT_FALSE(mFatal);
    262 }
    263 
    264 #if ENABLE_DCHECK != 0
    265 TEST_F(DCheckEnabledTest, DCheckIsOnReturnsTrue) {
    266     EXPECT_TRUE(DCHECK_IS_ON());
    267 }
    268 
    269 TEST_F(DCheckEnabledTest, DCheckFalse) {
    270     bool flag = false;
    271     setExpected(LOG_FATAL, __LINE__ + 1, "Check failed: false. Flag was set!");
    272     DCHECK(false) << setFlag(&flag, "Flag was set!");
    273     CHECK_EXPECTATIONS();
    274 }
    275 
    276 TEST_F(DCheckEnabledTest, DCheckTrue) {
    277     bool flag = false;
    278     DCHECK(true) << setFlag(&flag, "Flag was set!");
    279     EXPECT_FALSE(flag);
    280     EXPECT_FALSE(mFatal);
    281 }
    282 #endif  // ENABLE_DCHECK != 0
    283 
    284 #if ENABLE_DCHECK != 2
    285 TEST_F(DCheckDisabledTest, DCheckIsOnReturnsFalse) {
    286     EXPECT_FALSE(DCHECK_IS_ON());
    287 }
    288 
    289 TEST_F(DCheckDisabledTest, DCheckFalse) {
    290     bool flag = false;
    291     DCHECK(false) << setFlag(&flag, "Flag was set!");
    292     EXPECT_FALSE(flag);
    293     EXPECT_FALSE(mFatal);
    294 }
    295 
    296 TEST_F(DCheckDisabledTest, DCheckTrue) {
    297     DCHECK(true);
    298 }
    299 #endif  // ENABLE_DCHECK != 2
    300 
    301 TEST_F(PLogTest, PLogInfoEmpty) {
    302     setExpectedErrno(LOG_INFO, __LINE__ + 2, EINVAL, "");
    303     errno = EINVAL;
    304     PLOG(INFO);
    305     CHECK_EXPECTATIONS();
    306 }
    307 
    308 TEST_F(PLogTest, PLogInfoPreservesErrno) {
    309     // Select a value that is unlikely to ever be raised by the logging
    310     // machinery.
    311     const int kErrnoCode = ENOEXEC;
    312     setForcedErrno(EINVAL);
    313     setExpectedErrno(LOG_INFO, __LINE__ + 2, kErrnoCode, "Hi");
    314     errno = kErrnoCode;
    315     PLOG(INFO) << "Hi";
    316     EXPECT_EQ(kErrnoCode, errno);
    317     CHECK_EXPECTATIONS();
    318 }
    319 
    320 }  // namespace base
    321 }  // namespace android
    322