diff options
Diffstat (limited to 'chromium/fuchsia/base/legacymetrics_client_unittest.cc')
-rw-r--r-- | chromium/fuchsia/base/legacymetrics_client_unittest.cc | 111 |
1 files changed, 106 insertions, 5 deletions
diff --git a/chromium/fuchsia/base/legacymetrics_client_unittest.cc b/chromium/fuchsia/base/legacymetrics_client_unittest.cc index 8c735bbbffe..1b48827418a 100644 --- a/chromium/fuchsia/base/legacymetrics_client_unittest.cc +++ b/chromium/fuchsia/base/legacymetrics_client_unittest.cc @@ -14,6 +14,7 @@ #include "base/threading/thread_task_runner_handle.h" #include "fuchsia/base/legacymetrics_client.h" #include "fuchsia/base/legacymetrics_histogram_flattener.h" +#include "fuchsia/base/result_receiver.h" #include "testing/gtest/include/gtest/gtest.h" namespace cr_fuchsia { @@ -45,10 +46,21 @@ class TestMetricsRecorder ack_callback_ = base::nullopt; } + void set_expect_ack_dropped(bool expect_dropped) { + expect_ack_dropped_ = expect_dropped; + } + // fuchsia::legacymetrics::MetricsRecorder implementation. void Record(std::vector<fuchsia::legacymetrics::Event> events, RecordCallback callback) override { - recorded_events_ = std::move(events); + std::move(events.begin(), events.end(), + std::back_inserter(recorded_events_)); + + // Received a call to Record() before the previous one was acknowledged, + // which can happen in some cases (e.g. flushing). + if (ack_callback_) + EXPECT_TRUE(expect_ack_dropped_); + ack_callback_ = std::move(callback); if (on_record_cb_) @@ -61,6 +73,7 @@ class TestMetricsRecorder std::vector<fuchsia::legacymetrics::Event> recorded_events_; base::OnceClosure on_record_cb_; base::Optional<RecordCallback> ack_callback_; + bool expect_ack_dropped_ = false; }; class LegacyMetricsClientTest : public testing::Test { @@ -71,9 +84,10 @@ class LegacyMetricsClientTest : public testing::Test { ~LegacyMetricsClientTest() override = default; void SetUp() override { - service_binding_ = std::make_unique<base::fuchsia::ScopedServiceBinding< - fuchsia::legacymetrics::MetricsRecorder>>( - test_context_.additional_services(), &test_recorder_); + service_binding_ = + std::make_unique<base::fuchsia::ScopedSingleClientServiceBinding< + fuchsia::legacymetrics::MetricsRecorder>>( + test_context_.additional_services(), &test_recorder_); base::SetRecordActionTaskRunner(base::ThreadTaskRunnerHandle::Get()); // Flush any dirty histograms from previous test runs in this process. @@ -84,7 +98,7 @@ class LegacyMetricsClientTest : public testing::Test { base::test::TaskEnvironment task_environment_; base::TestComponentContextForProcess test_context_; TestMetricsRecorder test_recorder_; - std::unique_ptr<base::fuchsia::ScopedServiceBinding< + std::unique_ptr<base::fuchsia::ScopedSingleClientServiceBinding< fuchsia::legacymetrics::MetricsRecorder>> service_binding_; LegacyMetricsClient client_; @@ -216,5 +230,92 @@ TEST_F(LegacyMetricsClientTest, Batching) { test_recorder_.SendAck(); } +TEST_F(LegacyMetricsClientTest, FlushWithPending) { + client_.Start(kReportInterval); + base::RunLoop().RunUntilIdle(); + + UMA_HISTOGRAM_COUNTS_1M("foo", 20); + + EXPECT_FALSE(test_recorder_.IsRecordInFlight()); + service_binding_->events().OnCloseSoon(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(test_recorder_.IsRecordInFlight()); + + // The service should be unbound once all data is drained. + EXPECT_TRUE(service_binding_->has_clients()); + auto events = test_recorder_.WaitForEvents(); + test_recorder_.SendAck(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1u, events.size()); + EXPECT_EQ("foo", events[0].histogram().name()); + EXPECT_FALSE(service_binding_->has_clients()); +} + +TEST_F(LegacyMetricsClientTest, FlushNoData) { + client_.Start(kReportInterval); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(service_binding_->has_clients()); + EXPECT_FALSE(test_recorder_.IsRecordInFlight()); + service_binding_->events().OnCloseSoon(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(service_binding_->has_clients()); +} + +TEST_F(LegacyMetricsClientTest, FlushWithOutstandingAck) { + client_.Start(kReportInterval); + base::RunLoop().RunUntilIdle(); + + // Send "foo", but don't ack. + UMA_HISTOGRAM_COUNTS_1M("foo", 20); + task_environment_.FastForwardBy(kReportInterval); + EXPECT_TRUE(test_recorder_.IsRecordInFlight()); + + // Allow the flush operation to call Record() without waiting for a prior ack. + test_recorder_.set_expect_ack_dropped(true); + + // Buffer another event and trigger a flush. + UMA_HISTOGRAM_COUNTS_1M("bar", 20); + EXPECT_TRUE(service_binding_->has_clients()); + service_binding_->events().OnCloseSoon(); + + // Simulate an asynchronous ack from the recorder, which be delivered around + // the same time as the flush's Record() call. The ack should be gracefully + // ignored by the client. + test_recorder_.SendAck(); + + base::RunLoop().RunUntilIdle(); + + auto events = test_recorder_.WaitForEvents(); + test_recorder_.SendAck(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(2u, events.size()); + EXPECT_EQ("foo", events[0].histogram().name()); + EXPECT_EQ("bar", events[1].histogram().name()); + EXPECT_FALSE(service_binding_->has_clients()); +} + +TEST_F(LegacyMetricsClientTest, ExternalFlushSignal) { + ResultReceiver<base::OnceClosure> flush_receiver; + client_.SetNotifyFlushCallback(flush_receiver.GetReceiveCallback()); + client_.Start(kReportInterval); + base::RunLoop().RunUntilIdle(); + + UMA_HISTOGRAM_COUNTS_1M("foo", 20); + + // Verify that reporting does not start until the flush completion callback is + // run. + EXPECT_FALSE(test_recorder_.IsRecordInFlight()); + service_binding_->events().OnCloseSoon(); + base::RunLoop().RunUntilIdle(); + EXPECT_FALSE(test_recorder_.IsRecordInFlight()); + + // Verify that invoking the completion callback unblocks reporting. + EXPECT_TRUE(flush_receiver.has_value()); + std::move(*flush_receiver).Run(); + base::RunLoop().RunUntilIdle(); + EXPECT_TRUE(test_recorder_.IsRecordInFlight()); +} + } // namespace } // namespace cr_fuchsia |