Loading metrics/counter.cc +16 −15 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ #include "counter.h" #include <sys/file.h> #include <fcntl.h> #include <base/eintr_wrapper.h> #include <base/logging.h> Loading @@ -12,26 +12,28 @@ namespace chromeos_metrics { // TaggedCounter::Record implementation. void TaggedCounter::Record::Init(int tag, int count) { void TaggedCounter::Record::Init(int32 tag, int32 count) { tag_ = tag; count_ = (count > 0) ? count : 0; } void TaggedCounter::Record::Add(int count) { void TaggedCounter::Record::Add(int32 count) { if (count <= 0) return; count_ += count; // Saturates on postive overflow. if (count_ < 0) { count_ = INT_MAX; } // Saturates on positive overflow. int64 new_count = static_cast<int64>(count_) + static_cast<int64>(count); if (new_count > kint32max) count_ = kint32max; else count_ = static_cast<int32>(new_count); } // TaggedCounter implementation. TaggedCounter::TaggedCounter() : filename_(NULL), reporter_(NULL), reporter_handle_(NULL), : filename_(NULL), reporter_(NULL), reporter_handle_(NULL), record_state_(kRecordInvalid) {} TaggedCounter::~TaggedCounter() {} Loading @@ -45,7 +47,7 @@ void TaggedCounter::Init(const char* filename, record_state_ = kRecordInvalid; } void TaggedCounter::Update(int tag, int count) { void TaggedCounter::Update(int32 tag, int32 count) { UpdateInternal(tag, count, false); // No flush. Loading @@ -57,7 +59,7 @@ void TaggedCounter::Flush() { true); // Do flush. } void TaggedCounter::UpdateInternal(int tag, int count, bool flush) { void TaggedCounter::UpdateInternal(int32 tag, int32 count, bool flush) { if (flush) { // Flushing but record is null, so nothing to do. if (record_state_ == kRecordNull) Loading Loading @@ -104,11 +106,10 @@ void TaggedCounter::ReadRecord(int fd) { record_state_ = kRecordNullDirty; return; } record_state_ = kRecordNull; } void TaggedCounter::ReportRecord(int tag, bool flush) { void TaggedCounter::ReportRecord(int32 tag, bool flush) { // If no valid record, there's nothing to report. if (record_state_ != kRecordValid) { DCHECK_EQ(record_state_, kRecordNull); Loading @@ -126,7 +127,7 @@ void TaggedCounter::ReportRecord(int tag, bool flush) { record_state_ = kRecordNullDirty; } void TaggedCounter::UpdateRecord(int tag, int count, bool flush) { void TaggedCounter::UpdateRecord(int32 tag, int32 count, bool flush) { if (flush) { DCHECK(record_state_ == kRecordNull || record_state_ == kRecordNullDirty); return; Loading metrics/counter.h +19 −13 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #ifndef METRICS_COUNTER_H_ #define METRICS_COUNTER_H_ #include <base/basictypes.h> #include <gtest/gtest_prod.h> // for FRIEND_TEST namespace chromeos_metrics { Loading @@ -18,6 +19,11 @@ namespace chromeos_metrics { // event counts. The aggregated count is reported through the // callback when the counter is explicitly flushed or when data for a // new tag arrives. // // The primary reason for using an interface is to allow easier unit // testing in clients through mocking thus avoiding file access and // callbacks. Of course, it also enables alternative implementations // of the counter with additional features. class TaggedCounterInterface { public: // Callback type used for reporting aggregated or flushed data. Loading @@ -27,7 +33,7 @@ class TaggedCounterInterface { // |handle| is the |reporter_handle| pointer passed through Init. // |tag| is the tag associated with the aggregated count. // |count| is aggregated count. typedef void (*Reporter)(void* handle, int tag, int count); typedef void (*Reporter)(void* handle, int32 tag, int32 count); virtual ~TaggedCounterInterface() {} Loading @@ -44,7 +50,7 @@ class TaggedCounterInterface { // Adds |count| of events for the given |tag|. If there's an // existing aggregated count for a different tag, it's reported // through the reporter callback and discarded. virtual void Update(int tag, int count) = 0; virtual void Update(int32 tag, int32 count) = 0; // Reports the current aggregated count (if any) through the // reporter callback and discards it. Loading @@ -58,7 +64,7 @@ class TaggedCounter : public TaggedCounterInterface { // Implementation of interface methods. void Init(const char* filename, Reporter reporter, void* reporter_handle); void Update(int tag, int count); void Update(int32 tag, int32 count); void Flush(); private: Loading Loading @@ -89,25 +95,25 @@ class TaggedCounter : public TaggedCounterInterface { // Initializes with |tag| and |count|. If |count| is negative, // |count_| is set to 0. void Init(int tag, int count); void Init(int32 tag, int32 count); // Adds |count| to the current |count_|. Negative |count| is // ignored. In case of positive overflow, |count_| is saturated to // INT_MAX. void Add(int count); // kint32max. void Add(int32 count); int tag() const { return tag_; } int count() const { return count_; } int32 tag() const { return tag_; } int32 count() const { return count_; } private: int tag_; int count_; int32 tag_; int32 count_; }; // Implementation of the Update and Flush methods. Goes through the // necessary steps to read, report, update, and sync the aggregated // record. void UpdateInternal(int tag, int count, bool flush); void UpdateInternal(int32 tag, int32 count, bool flush); // If the current cached record is invalid, reads it from persistent // storage specified through file descriptor |fd| and updates the Loading @@ -119,13 +125,13 @@ class TaggedCounter : public TaggedCounterInterface { // or the new |tag| is different than the old one, reports the // aggregated data through the reporter callback and resets the // cached record. void ReportRecord(int tag, bool flush); void ReportRecord(int32 tag, bool flush); // Updates the cached record given the new |tag| and |count|. This // method expects either a null cached record, or a valid cached // record with the same tag as |tag|. If |flush| is true, the method // asserts that the cached record is null and returns. void UpdateRecord(int tag, int count, bool flush); void UpdateRecord(int32 tag, int32 count, bool flush); // If the cached record state is dirty, updates the persistent // storage specified through file descriptor |fd| and switches the Loading metrics/counter_mock.h +1 −0 Original line number Diff line number Diff line Loading @@ -24,3 +24,4 @@ class TaggedCounterMock : public TaggedCounterInterface { } // namespace chromeos_metrics #endif // METRICS_COUNTER_MOCK_H_ metrics/counter_test.cc +10 −9 Original line number Diff line number Diff line Loading @@ -62,8 +62,8 @@ class TaggedCounterTest : public testing::Test { // Asserts that the record file contains the specified contents. testing::AssertionResult AssertRecord(const char* expr_tag, const char* expr_count, int expected_tag, int expected_count) { int32 expected_tag, int32 expected_count) { int fd = HANDLE_EINTR(open(kTestRecordFile, O_RDONLY)); if (fd < 0) { testing::Message msg; Loading Loading @@ -105,7 +105,7 @@ class TaggedCounterTest : public testing::Test { // Adds a reporter call expectation that the specified tag/count // callback will be generated. void ExpectReporterCall(int tag, int count) { void ExpectReporterCall(int32 tag, int32 count) { EXPECT_CALL(reporter_, Call(_, tag, count)) .Times(1) .RetiresOnSaturation(); Loading @@ -113,7 +113,7 @@ class TaggedCounterTest : public testing::Test { // The reporter callback forwards the call to the reporter mock so // that we can set call expectations. static void Reporter(void* handle, int tag, int count) { static void Reporter(void* handle, int32 tag, int32 count) { TaggedCounterTest* test = static_cast<TaggedCounterTest*>(handle); ASSERT_FALSE(NULL == test); test->reporter_.Call(handle, tag, count); Loading @@ -130,7 +130,7 @@ class TaggedCounterTest : public testing::Test { } // Returns true if the counter log contains |pattern|, false otherwise. bool LogContains(const std::string& pattern) { bool LogContains(const std::string& pattern) const { return log_.find(pattern) != std::string::npos; } Loading @@ -141,7 +141,8 @@ class TaggedCounterTest : public testing::Test { std::string log_; // Reporter mock to set callback expectations on. StrictMock<MockFunction<void(void* handle, int tag, int count)> > reporter_; StrictMock<MockFunction<void(void* handle, int32 tag, int32 count)> > reporter_; // Pointer to the current test fixture. static TaggedCounterTest* test_; Loading Loading @@ -173,11 +174,11 @@ TEST_F(RecordTest, Add) { record_.Add(/* count */ -2); EXPECT_EQ(15, record_.count()); record_.Add(/* count */ INT_MAX); EXPECT_EQ(INT_MAX, record_.count()); record_.Add(/* count */ kint32max); EXPECT_EQ(kint32max, record_.count()); record_.Add(/* count */ 1); EXPECT_EQ(INT_MAX, record_.count()); EXPECT_EQ(kint32max, record_.count()); } TEST_F(TaggedCounterTest, BadFileLocation) { Loading Loading
metrics/counter.cc +16 −15 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ #include "counter.h" #include <sys/file.h> #include <fcntl.h> #include <base/eintr_wrapper.h> #include <base/logging.h> Loading @@ -12,26 +12,28 @@ namespace chromeos_metrics { // TaggedCounter::Record implementation. void TaggedCounter::Record::Init(int tag, int count) { void TaggedCounter::Record::Init(int32 tag, int32 count) { tag_ = tag; count_ = (count > 0) ? count : 0; } void TaggedCounter::Record::Add(int count) { void TaggedCounter::Record::Add(int32 count) { if (count <= 0) return; count_ += count; // Saturates on postive overflow. if (count_ < 0) { count_ = INT_MAX; } // Saturates on positive overflow. int64 new_count = static_cast<int64>(count_) + static_cast<int64>(count); if (new_count > kint32max) count_ = kint32max; else count_ = static_cast<int32>(new_count); } // TaggedCounter implementation. TaggedCounter::TaggedCounter() : filename_(NULL), reporter_(NULL), reporter_handle_(NULL), : filename_(NULL), reporter_(NULL), reporter_handle_(NULL), record_state_(kRecordInvalid) {} TaggedCounter::~TaggedCounter() {} Loading @@ -45,7 +47,7 @@ void TaggedCounter::Init(const char* filename, record_state_ = kRecordInvalid; } void TaggedCounter::Update(int tag, int count) { void TaggedCounter::Update(int32 tag, int32 count) { UpdateInternal(tag, count, false); // No flush. Loading @@ -57,7 +59,7 @@ void TaggedCounter::Flush() { true); // Do flush. } void TaggedCounter::UpdateInternal(int tag, int count, bool flush) { void TaggedCounter::UpdateInternal(int32 tag, int32 count, bool flush) { if (flush) { // Flushing but record is null, so nothing to do. if (record_state_ == kRecordNull) Loading Loading @@ -104,11 +106,10 @@ void TaggedCounter::ReadRecord(int fd) { record_state_ = kRecordNullDirty; return; } record_state_ = kRecordNull; } void TaggedCounter::ReportRecord(int tag, bool flush) { void TaggedCounter::ReportRecord(int32 tag, bool flush) { // If no valid record, there's nothing to report. if (record_state_ != kRecordValid) { DCHECK_EQ(record_state_, kRecordNull); Loading @@ -126,7 +127,7 @@ void TaggedCounter::ReportRecord(int tag, bool flush) { record_state_ = kRecordNullDirty; } void TaggedCounter::UpdateRecord(int tag, int count, bool flush) { void TaggedCounter::UpdateRecord(int32 tag, int32 count, bool flush) { if (flush) { DCHECK(record_state_ == kRecordNull || record_state_ == kRecordNullDirty); return; Loading
metrics/counter.h +19 −13 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #ifndef METRICS_COUNTER_H_ #define METRICS_COUNTER_H_ #include <base/basictypes.h> #include <gtest/gtest_prod.h> // for FRIEND_TEST namespace chromeos_metrics { Loading @@ -18,6 +19,11 @@ namespace chromeos_metrics { // event counts. The aggregated count is reported through the // callback when the counter is explicitly flushed or when data for a // new tag arrives. // // The primary reason for using an interface is to allow easier unit // testing in clients through mocking thus avoiding file access and // callbacks. Of course, it also enables alternative implementations // of the counter with additional features. class TaggedCounterInterface { public: // Callback type used for reporting aggregated or flushed data. Loading @@ -27,7 +33,7 @@ class TaggedCounterInterface { // |handle| is the |reporter_handle| pointer passed through Init. // |tag| is the tag associated with the aggregated count. // |count| is aggregated count. typedef void (*Reporter)(void* handle, int tag, int count); typedef void (*Reporter)(void* handle, int32 tag, int32 count); virtual ~TaggedCounterInterface() {} Loading @@ -44,7 +50,7 @@ class TaggedCounterInterface { // Adds |count| of events for the given |tag|. If there's an // existing aggregated count for a different tag, it's reported // through the reporter callback and discarded. virtual void Update(int tag, int count) = 0; virtual void Update(int32 tag, int32 count) = 0; // Reports the current aggregated count (if any) through the // reporter callback and discards it. Loading @@ -58,7 +64,7 @@ class TaggedCounter : public TaggedCounterInterface { // Implementation of interface methods. void Init(const char* filename, Reporter reporter, void* reporter_handle); void Update(int tag, int count); void Update(int32 tag, int32 count); void Flush(); private: Loading Loading @@ -89,25 +95,25 @@ class TaggedCounter : public TaggedCounterInterface { // Initializes with |tag| and |count|. If |count| is negative, // |count_| is set to 0. void Init(int tag, int count); void Init(int32 tag, int32 count); // Adds |count| to the current |count_|. Negative |count| is // ignored. In case of positive overflow, |count_| is saturated to // INT_MAX. void Add(int count); // kint32max. void Add(int32 count); int tag() const { return tag_; } int count() const { return count_; } int32 tag() const { return tag_; } int32 count() const { return count_; } private: int tag_; int count_; int32 tag_; int32 count_; }; // Implementation of the Update and Flush methods. Goes through the // necessary steps to read, report, update, and sync the aggregated // record. void UpdateInternal(int tag, int count, bool flush); void UpdateInternal(int32 tag, int32 count, bool flush); // If the current cached record is invalid, reads it from persistent // storage specified through file descriptor |fd| and updates the Loading @@ -119,13 +125,13 @@ class TaggedCounter : public TaggedCounterInterface { // or the new |tag| is different than the old one, reports the // aggregated data through the reporter callback and resets the // cached record. void ReportRecord(int tag, bool flush); void ReportRecord(int32 tag, bool flush); // Updates the cached record given the new |tag| and |count|. This // method expects either a null cached record, or a valid cached // record with the same tag as |tag|. If |flush| is true, the method // asserts that the cached record is null and returns. void UpdateRecord(int tag, int count, bool flush); void UpdateRecord(int32 tag, int32 count, bool flush); // If the cached record state is dirty, updates the persistent // storage specified through file descriptor |fd| and switches the Loading
metrics/counter_mock.h +1 −0 Original line number Diff line number Diff line Loading @@ -24,3 +24,4 @@ class TaggedCounterMock : public TaggedCounterInterface { } // namespace chromeos_metrics #endif // METRICS_COUNTER_MOCK_H_
metrics/counter_test.cc +10 −9 Original line number Diff line number Diff line Loading @@ -62,8 +62,8 @@ class TaggedCounterTest : public testing::Test { // Asserts that the record file contains the specified contents. testing::AssertionResult AssertRecord(const char* expr_tag, const char* expr_count, int expected_tag, int expected_count) { int32 expected_tag, int32 expected_count) { int fd = HANDLE_EINTR(open(kTestRecordFile, O_RDONLY)); if (fd < 0) { testing::Message msg; Loading Loading @@ -105,7 +105,7 @@ class TaggedCounterTest : public testing::Test { // Adds a reporter call expectation that the specified tag/count // callback will be generated. void ExpectReporterCall(int tag, int count) { void ExpectReporterCall(int32 tag, int32 count) { EXPECT_CALL(reporter_, Call(_, tag, count)) .Times(1) .RetiresOnSaturation(); Loading @@ -113,7 +113,7 @@ class TaggedCounterTest : public testing::Test { // The reporter callback forwards the call to the reporter mock so // that we can set call expectations. static void Reporter(void* handle, int tag, int count) { static void Reporter(void* handle, int32 tag, int32 count) { TaggedCounterTest* test = static_cast<TaggedCounterTest*>(handle); ASSERT_FALSE(NULL == test); test->reporter_.Call(handle, tag, count); Loading @@ -130,7 +130,7 @@ class TaggedCounterTest : public testing::Test { } // Returns true if the counter log contains |pattern|, false otherwise. bool LogContains(const std::string& pattern) { bool LogContains(const std::string& pattern) const { return log_.find(pattern) != std::string::npos; } Loading @@ -141,7 +141,8 @@ class TaggedCounterTest : public testing::Test { std::string log_; // Reporter mock to set callback expectations on. StrictMock<MockFunction<void(void* handle, int tag, int count)> > reporter_; StrictMock<MockFunction<void(void* handle, int32 tag, int32 count)> > reporter_; // Pointer to the current test fixture. static TaggedCounterTest* test_; Loading Loading @@ -173,11 +174,11 @@ TEST_F(RecordTest, Add) { record_.Add(/* count */ -2); EXPECT_EQ(15, record_.count()); record_.Add(/* count */ INT_MAX); EXPECT_EQ(INT_MAX, record_.count()); record_.Add(/* count */ kint32max); EXPECT_EQ(kint32max, record_.count()); record_.Add(/* count */ 1); EXPECT_EQ(INT_MAX, record_.count()); EXPECT_EQ(kint32max, record_.count()); } TEST_F(TaggedCounterTest, BadFileLocation) { Loading