shill: Throttle diagnostics log stashing (and uploading).
BUG=chromium-os:36775
TEST=unit tests
Change-Id: Ibb050cf7422a246dd903bfb39cb321105eaa02a1
Reviewed-on: https://gerrit.chromium.org/gerrit/39187
Tested-by: Darin Petkov <petkov@chromium.org>
Reviewed-by: Paul Stewart <pstew@chromium.org>
Commit-Ready: Darin Petkov <petkov@chromium.org>
diff --git a/diagnostics_reporter.cc b/diagnostics_reporter.cc
index e1bb730..8f730be 100644
--- a/diagnostics_reporter.cc
+++ b/diagnostics_reporter.cc
@@ -5,6 +5,7 @@
#include "shill/diagnostics_reporter.h"
#include "shill/glib.h"
+#include "shill/shill_time.h"
namespace shill {
@@ -15,7 +16,13 @@
} // namespace
-DiagnosticsReporter::DiagnosticsReporter() : glib_(NULL) {}
+// static
+const int DiagnosticsReporter::kLogStashThrottleSeconds = 30 * 60;
+
+DiagnosticsReporter::DiagnosticsReporter()
+ : glib_(NULL),
+ time_(Time::GetInstance()),
+ last_log_stash_(0) {}
DiagnosticsReporter::~DiagnosticsReporter() {}
@@ -56,7 +63,15 @@
void DiagnosticsReporter::OnConnectivityEvent() {
LOG(INFO) << "Diagnostics event triggered.";
- // TODO(petkov): Throttle log stashing (crosbug.com/36775).
+ struct timeval now = (const struct timeval){ 0 };
+ time_->GetTimeMonotonic(&now);
+ if (last_log_stash_ + kLogStashThrottleSeconds >
+ static_cast<uint64>(now.tv_sec)) {
+ LOG(INFO) << "Diagnostics throttled.";
+ return;
+ }
+
+ last_log_stash_ = now.tv_sec;
// TODO(petkov): Stash away logs for potential inclusion in feedback
// (crosbug.com/36923).
diff --git a/diagnostics_reporter.h b/diagnostics_reporter.h
index 22a9beb..cb0b1bc 100644
--- a/diagnostics_reporter.h
+++ b/diagnostics_reporter.h
@@ -10,6 +10,7 @@
namespace shill {
class GLib;
+class Time;
class DiagnosticsReporter {
public:
@@ -36,7 +37,11 @@
friend struct base::DefaultLazyInstanceTraits<DiagnosticsReporter>;
friend class DiagnosticsReporterTest;
+ static const int kLogStashThrottleSeconds;
+
GLib *glib_;
+ Time *time_;
+ uint64 last_log_stash_; // Monotonic time seconds.
DISALLOW_COPY_AND_ASSIGN(DiagnosticsReporter);
};
diff --git a/diagnostics_reporter_unittest.cc b/diagnostics_reporter_unittest.cc
index e0c82e3..3332e51 100644
--- a/diagnostics_reporter_unittest.cc
+++ b/diagnostics_reporter_unittest.cc
@@ -8,24 +8,14 @@
#include <gtest/gtest.h>
#include "shill/mock_glib.h"
+#include "shill/mock_time.h"
using testing::_;
using testing::Return;
+using testing::SetArgumentPointee;
namespace shill {
-class DiagnosticsReporterTest : public testing::Test {
- public:
- DiagnosticsReporterTest() {}
-
- protected:
- bool IsReportingEnabled() {
- return DiagnosticsReporter::GetInstance()->IsReportingEnabled();
- }
-
- MockGLib glib_;
-};
-
namespace {
class ReporterUnderTest : public DiagnosticsReporter {
@@ -42,24 +32,71 @@
} // namespace
+class DiagnosticsReporterTest : public testing::Test {
+ public:
+ DiagnosticsReporterTest() {
+ reporter_.time_ = &time_;
+ reporter_.Init(&glib_);
+ }
+
+ protected:
+ bool IsReportingEnabled() {
+ return DiagnosticsReporter::GetInstance()->IsReportingEnabled();
+ }
+
+ void SetLastLogStash(uint64 time) { reporter_.last_log_stash_ = time; }
+ uint64 GetLastLogStash() { return reporter_.last_log_stash_; }
+ uint64 GetLogStashThrottleSeconds() {
+ return DiagnosticsReporter::kLogStashThrottleSeconds;
+ }
+
+ MockGLib glib_;
+ MockTime time_;
+ ReporterUnderTest reporter_;
+};
+
TEST_F(DiagnosticsReporterTest, ReportEnabled) {
- ReporterUnderTest reporter;
- EXPECT_CALL(reporter, IsReportingEnabled()).WillOnce(Return(true));
+ EXPECT_CALL(reporter_, IsReportingEnabled()).WillOnce(Return(true));
EXPECT_CALL(glib_, SpawnSync(_, _, _, _, _, _, _, _, _, _)).Times(1);
- reporter.Init(&glib_);
- reporter.Report();
+ reporter_.Report();
}
TEST_F(DiagnosticsReporterTest, ReportDisabled) {
- ReporterUnderTest reporter;
- EXPECT_CALL(reporter, IsReportingEnabled()).WillOnce(Return(false));
+ EXPECT_CALL(reporter_, IsReportingEnabled()).WillOnce(Return(false));
EXPECT_CALL(glib_, SpawnSync(_, _, _, _, _, _, _, _, _, _)).Times(0);
- reporter.Init(&glib_);
- reporter.Report();
+ reporter_.Report();
}
TEST_F(DiagnosticsReporterTest, IsReportingEnabled) {
EXPECT_FALSE(IsReportingEnabled());
}
+TEST_F(DiagnosticsReporterTest, OnConnectivityEventThrottle) {
+ const uint64 kLastStash = 50;
+ const uint64 kNow = kLastStash + GetLogStashThrottleSeconds() - 1;
+ SetLastLogStash(kLastStash);
+ const struct timeval now = {
+ .tv_sec = static_cast<long int>(kNow),
+ .tv_usec = 0
+ };
+ EXPECT_CALL(time_, GetTimeMonotonic(_))
+ .WillOnce(DoAll(SetArgumentPointee<0>(now), Return(0)));
+ reporter_.OnConnectivityEvent();
+ EXPECT_EQ(kLastStash, GetLastLogStash());
+}
+
+TEST_F(DiagnosticsReporterTest, OnConnectivityEvent) {
+ const uint64 kLastStash = 50;
+ const uint64 kNow = kLastStash + GetLogStashThrottleSeconds() + 1;
+ SetLastLogStash(kLastStash);
+ const struct timeval now = {
+ .tv_sec = static_cast<long int>(kNow),
+ .tv_usec = 0
+ };
+ EXPECT_CALL(time_, GetTimeMonotonic(_))
+ .WillOnce(DoAll(SetArgumentPointee<0>(now), Return(0)));
+ reporter_.OnConnectivityEvent();
+ EXPECT_EQ(kNow, GetLastLogStash());
+}
+
} // namespace shill