diff options
author | ricea <ricea@chromium.org> | 2014-10-29 04:35:45 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-10-29 11:36:11 +0000 |
commit | fa874fd422dd79886729d6884b032b44572c43ee (patch) | |
tree | 466f522bff083c2cfe57fd176d804b6dace40b5a /base/time | |
parent | b8aecf83be3b90d288a0a71a8571f0dd3f99bec5 (diff) | |
download | chromium_src-fa874fd422dd79886729d6884b032b44572c43ee.zip chromium_src-fa874fd422dd79886729d6884b032b44572c43ee.tar.gz chromium_src-fa874fd422dd79886729d6884b032b44572c43ee.tar.bz2 |
Add logging support for base::Time* types.
Define operator<<(ostream&,Time) to permit Time, TimeDelta and TimeTicks
types to be used in logging assertions such as DCHECK_EQ().
BUG=425941
TEST=base_unittests
Review URL: https://codereview.chromium.org/669083002
Cr-Commit-Position: refs/heads/master@{#301815}
Diffstat (limited to 'base/time')
-rw-r--r-- | base/time/time.cc | 31 | ||||
-rw-r--r-- | base/time/time.h | 15 | ||||
-rw-r--r-- | base/time/time_unittest.cc | 105 |
3 files changed, 148 insertions, 3 deletions
diff --git a/base/time/time.cc b/base/time/time.cc index f731356..ce9d12c 100644 --- a/base/time/time.cc +++ b/base/time/time.cc @@ -4,12 +4,15 @@ #include "base/time/time.h" +#include <ios> #include <limits> #include <ostream> +#include <sstream> #include "base/float_util.h" #include "base/lazy_instance.h" #include "base/logging.h" +#include "base/strings/stringprintf.h" #include "base/third_party/nspr/prtime.h" namespace base { @@ -94,6 +97,10 @@ int64 TimeDelta::InMicroseconds() const { return delta_; } +std::ostream& operator<<(std::ostream& os, TimeDelta time_delta) { + return os << time_delta.InSecondsF() << "s"; +} + // Time ----------------------------------------------------------------------- // static @@ -230,6 +237,20 @@ bool Time::FromStringInternal(const char* time_string, return true; } +std::ostream& operator<<(std::ostream& os, Time time) { + Time::Exploded exploded; + time.UTCExplode(&exploded); + // Use StringPrintf because iostreams formatting is painful. + return os << StringPrintf("%04d-%02d-%02d %02d:%02d:%02d.%03d UTC", + exploded.year, + exploded.month, + exploded.day_of_month, + exploded.hour, + exploded.minute, + exploded.second, + exploded.millisecond); +} + // Local helper class to hold the conversion from Time to TickTime at the // time of the Unix epoch. class UnixEpochSingleton { @@ -253,6 +274,16 @@ TimeTicks TimeTicks::UnixEpoch() { return leaky_unix_epoch_singleton_instance.Get().unix_epoch(); } +std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks) { + // This function formats a TimeTicks object as "bogo-microseconds". + // The origin and granularity of the count are platform-specific, and may very + // from run to run. Although bogo-microseconds usually roughly correspond to + // real microseconds, the only real guarantee is that the number never goes + // down during a single run. + const TimeDelta as_time_delta = time_ticks - TimeTicks(); + return os << as_time_delta.InMicroseconds() << " bogo-microseconds"; +} + // Time::Exploded ------------------------------------------------------------- inline bool is_in_range(int value, int lo, int hi) { diff --git a/base/time/time.h b/base/time/time.h index 3cf3746..641f465 100644 --- a/base/time/time.h +++ b/base/time/time.h @@ -19,12 +19,18 @@ // // These classes are represented as only a 64-bit value, so they can be // efficiently passed by value. +// +// Definitions of operator<< are provided to make these types work with +// DCHECK_EQ() and other log macros. For human-readable formatting, see +// "base/i18n/time_formatting.h". #ifndef BASE_TIME_TIME_H_ #define BASE_TIME_TIME_H_ #include <time.h> +#include <iosfwd> + #include "base/base_export.h" #include "base/basictypes.h" #include "build/build_config.h" @@ -206,6 +212,9 @@ inline TimeDelta operator*(int64 a, TimeDelta td) { return TimeDelta(a * td.delta_); } +// For logging use only. +BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeDelta time_delta); + // Time ----------------------------------------------------------------------- // Represents a wall clock time in UTC. @@ -561,6 +570,9 @@ inline Time TimeDelta::operator+(Time t) const { return Time(t.us_ + delta_); } +// For logging use only. +BASE_EXPORT std::ostream& operator<<(std::ostream& os, Time time); + // TimeTicks ------------------------------------------------------------------ class BASE_EXPORT TimeTicks { @@ -723,6 +735,9 @@ inline TimeTicks TimeDelta::operator+(TimeTicks t) const { return TimeTicks(t.ticks_ + delta_); } +// For logging use only. +BASE_EXPORT std::ostream& operator<<(std::ostream& os, TimeTicks time_ticks); + } // namespace base #endif // BASE_TIME_TIME_H_ diff --git a/base/time/time_unittest.cc b/base/time/time_unittest.cc index d8f1e5e..ef80e438 100644 --- a/base/time/time_unittest.cc +++ b/base/time/time_unittest.cc @@ -6,6 +6,8 @@ #include <time.h> +#include <string> + #include "base/compiler_specific.h" #include "base/logging.h" #include "base/strings/stringprintf.h" @@ -13,9 +15,9 @@ #include "build/build_config.h" #include "testing/gtest/include/gtest/gtest.h" -using base::Time; -using base::TimeDelta; -using base::TimeTicks; +namespace base { + +namespace { // Specialized test fixture allowing time strings without timezones to be // tested by comparing them to a known time in the local zone. @@ -780,3 +782,100 @@ TEST(TimeDelta, WindowsEpoch) { // We can't test 1601 epoch, since the system time functions on Linux // only compute years starting from 1900. } + +// We could define this separately for Time, TimeTicks and TimeDelta but the +// definitions would be identical anyway. +template <class Any> +std::string AnyToString(Any any) { + std::ostringstream oss; + oss << any; + return oss.str(); +} + +TEST(TimeDeltaLogging, DCheckEqCompiles) { + DCHECK_EQ(TimeDelta(), TimeDelta()); +} + +TEST(TimeDeltaLogging, EmptyIsZero) { + TimeDelta zero; + EXPECT_EQ("0s", AnyToString(zero)); +} + +TEST(TimeDeltaLogging, FiveHundredMs) { + TimeDelta five_hundred_ms = TimeDelta::FromMilliseconds(500); + EXPECT_EQ("0.5s", AnyToString(five_hundred_ms)); +} + +TEST(TimeDeltaLogging, MinusTenSeconds) { + TimeDelta minus_ten_seconds = TimeDelta::FromSeconds(-10); + EXPECT_EQ("-10s", AnyToString(minus_ten_seconds)); +} + +TEST(TimeDeltaLogging, DoesNotMessUpFormattingFlags) { + std::ostringstream oss; + std::ios_base::fmtflags flags_before = oss.flags(); + oss << TimeDelta(); + EXPECT_EQ(flags_before, oss.flags()); +} + +TEST(TimeDeltaLogging, DoesNotMakeStreamBad) { + std::ostringstream oss; + oss << TimeDelta(); + EXPECT_TRUE(oss.good()); +} + +TEST(TimeLogging, DCheckEqCompiles) { + DCHECK_EQ(Time(), Time()); +} + +TEST(TimeLogging, ChromeBirthdate) { + Time birthdate; + ASSERT_TRUE(Time::FromString("Tue, 02 Sep 2008 09:42:18 GMT", &birthdate)); + EXPECT_EQ("2008-09-02 09:42:18.000 UTC", AnyToString(birthdate)); +} + +TEST(TimeLogging, DoesNotMessUpFormattingFlags) { + std::ostringstream oss; + std::ios_base::fmtflags flags_before = oss.flags(); + oss << Time(); + EXPECT_EQ(flags_before, oss.flags()); +} + +TEST(TimeLogging, DoesNotMakeStreamBad) { + std::ostringstream oss; + oss << Time(); + EXPECT_TRUE(oss.good()); +} + +TEST(TimeTicksLogging, DCheckEqCompiles) { + DCHECK_EQ(TimeTicks(), TimeTicks()); +} + +TEST(TimeTicksLogging, ZeroTime) { + TimeTicks zero; + EXPECT_EQ("0 bogo-microseconds", AnyToString(zero)); +} + +TEST(TimeTicksLogging, FortyYearsLater) { + TimeTicks forty_years_later = + TimeTicks() + TimeDelta::FromDays(365.25 * 40); + EXPECT_EQ("1262304000000000 bogo-microseconds", + AnyToString(forty_years_later)); +} + +TEST(TimeTicksLogging, DoesNotMessUpFormattingFlags) { + std::ostringstream oss; + std::ios_base::fmtflags flags_before = oss.flags(); + oss << TimeTicks(); + EXPECT_EQ(flags_before, oss.flags()); +} + +TEST(TimeTicksLogging, DoesNotMakeStreamBad) { + std::ostringstream oss; + oss << TimeTicks(); + EXPECT_TRUE(oss.good()); +} + +} // namespace + +} // namespace base |