
Metrics: Extensions.MessagePipeline.OpenChannelStatus{WorkerStatus}{ChannelType} Extensions.MessagePipeline.OpenChannelWorkerDispatchStatus{ChannelType} Extensions.MessagePipeline.OpenChannelWorkerWakeUpStatus{ChannelType} This tracks several stages of the initial open channel portion of sending an extension message. It tracks each stage of this process as a separate metric. It emits a relevant value from MessageTracker::OpenChannelMessagePipelineResult that indicates where the process finishes (or fails). It also make some minor changes to ServiceWorkerTaskQueue to make it easier to emit a metric that is worker-based extension specific. After this change we will be able to determine where in the open channel process we might be experiencing issues which could contribute to messages to worker failures. Low-Coverage-Reason: OTHER message_port.cc DispatchOnConnect non-pure virtual method is empty. Bug: 371011217 Change-Id: I4ae6628018a4d3d1c2e367244bf787f7db1b326c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5938256 Auto-Submit: Justin Lulejian <jlulejian@chromium.org> Reviewed-by: Devlin Cronin <rdevlin.cronin@chromium.org> Commit-Queue: Devlin Cronin <rdevlin.cronin@chromium.org> Cr-Commit-Position: refs/heads/main@{#1388520}
180 lines
6.5 KiB
C++
180 lines
6.5 KiB
C++
// Copyright 2024 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "extensions/browser/message_tracker.h"
|
|
|
|
#include "base/strings/strcat.h"
|
|
#include "base/test/metrics/histogram_tester.h"
|
|
#include "base/test/task_environment.h"
|
|
#include "base/time/time.h"
|
|
#include "content/public/browser/browser_context.h"
|
|
#include "content/public/test/browser_task_environment.h"
|
|
#include "content/public/test/test_browser_context.h"
|
|
#include "extensions/browser/extensions_test.h"
|
|
#include "extensions/browser/test_extensions_browser_client.h"
|
|
#include "extensions/common/mojom/message_port.mojom-shared.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
|
|
namespace extensions {
|
|
|
|
namespace {
|
|
|
|
class MessageTrackerTestObserver : public MessageTracker::TestObserver {
|
|
public:
|
|
explicit MessageTrackerTestObserver(const base::UnguessableToken message_id)
|
|
: observed_message_id_(message_id) {
|
|
MessageTracker::SetObserverForTest(this);
|
|
}
|
|
|
|
~MessageTrackerTestObserver() override {
|
|
MessageTracker::SetObserverForTest(nullptr);
|
|
}
|
|
|
|
void WaitForMessageHung() { on_message_hung_runloop.Run(); }
|
|
|
|
private:
|
|
void OnStageTimeoutRan(const base::UnguessableToken& message_id) override {
|
|
if (observed_message_id_ == message_id) {
|
|
on_message_hung_runloop.Quit();
|
|
}
|
|
}
|
|
|
|
private:
|
|
base::UnguessableToken observed_message_id_;
|
|
base::RunLoop on_message_hung_runloop;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
class MessageTrackerUnitTest : public ExtensionsTest {
|
|
protected:
|
|
void SetUp() override {
|
|
ExtensionsTest::SetUp();
|
|
message_tracker_ = MessageTracker::Get(browser_context());
|
|
}
|
|
|
|
void TearDown() override {
|
|
message_tracker_ = nullptr;
|
|
ExtensionsTest::TearDown();
|
|
}
|
|
|
|
MessageTracker* message_tracker() { return message_tracker_; }
|
|
base::HistogramTester& histogram_tester() { return histogram_tester_; }
|
|
|
|
private:
|
|
raw_ptr<MessageTracker> message_tracker_;
|
|
base::HistogramTester histogram_tester_;
|
|
};
|
|
|
|
// Tests that the tracker correctly records and reports metrics when an
|
|
// extension message succeeds in its message stage.
|
|
TEST_F(MessageTrackerUnitTest, NotifyMessage) {
|
|
base::UnguessableToken message_id = base::UnguessableToken::Create();
|
|
MessageTrackerTestObserver observer(message_id);
|
|
message_tracker()->StartTrackingMessagingStage(
|
|
message_id, "Extensions.MessagePipeline.OpenChannelStatus",
|
|
mojom::ChannelType::kSendMessage);
|
|
|
|
message_tracker()->StopTrackingMessagingStage(
|
|
message_id, MessageTracker::OpenChannelMessagePipelineResult::kOpened);
|
|
|
|
histogram_tester().ExpectTotalCount(
|
|
"Extensions.MessagePipeline.OpenChannelStatus.SendMessageChannel",
|
|
/*expected_count=*/1);
|
|
histogram_tester().ExpectBucketCount(
|
|
"Extensions.MessagePipeline.OpenChannelStatus.SendMessageChannel",
|
|
MessageTracker::OpenChannelMessagePipelineResult::kOpened,
|
|
/*expected_count=*/1);
|
|
}
|
|
|
|
// Tests that the tracker correctly records and reports metrics when an
|
|
// extension message remains too long in its stage and becomes "hung".
|
|
TEST_F(MessageTrackerUnitTest, NotifyHungMessage) {
|
|
base::UnguessableToken message_id = base::UnguessableToken::Create();
|
|
MessageTrackerTestObserver observer(message_id);
|
|
message_tracker()->SetStageHungTimeoutForTest(base::Microseconds(1));
|
|
message_tracker()->StartTrackingMessagingStage(
|
|
message_id, "Extensions.MessagePipeline.OpenChannelStatus",
|
|
mojom::ChannelType::kSendMessage);
|
|
|
|
{
|
|
SCOPED_TRACE(
|
|
"waiting for timeout check to run after starting new message tracking");
|
|
observer.WaitForMessageHung();
|
|
}
|
|
|
|
histogram_tester().ExpectTotalCount(
|
|
"Extensions.MessagePipeline.OpenChannelStatus.SendMessageChannel",
|
|
/*expected_count=*/1);
|
|
histogram_tester().ExpectBucketCount(
|
|
"Extensions.MessagePipeline.OpenChannelStatus.SendMessageChannel",
|
|
MessageTracker::OpenChannelMessagePipelineResult::kHung,
|
|
/*expected_count=*/1);
|
|
}
|
|
|
|
// Tests that the tracker emits success metrics when an extension message hung
|
|
// check occurs *after* a message has successfully completed its messaging
|
|
// stage.
|
|
TEST_F(MessageTrackerUnitTest, NotifyOpenedMessageIfStoppedBeforeHung) {
|
|
base::UnguessableToken message_id = base::UnguessableToken::Create();
|
|
MessageTrackerTestObserver observer(message_id);
|
|
message_tracker()->SetStageHungTimeoutForTest(base::Seconds(1));
|
|
message_tracker()->StartTrackingMessagingStage(
|
|
message_id, "Extensions.MessagePipeline.OpenChannelStatus",
|
|
mojom::ChannelType::kSendMessage);
|
|
message_tracker()->StopTrackingMessagingStage(
|
|
message_id, MessageTracker::OpenChannelMessagePipelineResult::kOpened);
|
|
|
|
// This will wait for the hung check created by
|
|
// StartTrackingMessagingStage(), then proceed.
|
|
{
|
|
SCOPED_TRACE(
|
|
"waiting for hung check to run after starting and updating new "
|
|
"message tracking");
|
|
observer.WaitForMessageHung();
|
|
}
|
|
|
|
histogram_tester().ExpectTotalCount(
|
|
"Extensions.MessagePipeline.OpenChannelStatus.SendMessageChannel",
|
|
/*expected_count=*/1);
|
|
histogram_tester().ExpectBucketCount(
|
|
"Extensions.MessagePipeline.OpenChannelStatus.SendMessageChannel",
|
|
MessageTracker::OpenChannelMessagePipelineResult::kOpened,
|
|
/*expected_count=*/1);
|
|
}
|
|
|
|
// Tests that the tracker emits failure metrics when an extension message hung
|
|
// check occurs *before* a message has successfully completed its messaging
|
|
// stage.
|
|
TEST_F(MessageTrackerUnitTest, NotifyHungMessageIfStoppedAfterHung) {
|
|
base::UnguessableToken message_id = base::UnguessableToken::Create();
|
|
MessageTrackerTestObserver observer(message_id);
|
|
message_tracker()->SetStageHungTimeoutForTest(base::Seconds(1));
|
|
message_tracker()->StartTrackingMessagingStage(
|
|
message_id, "Extensions.MessagePipeline.OpenChannelStatus",
|
|
mojom::ChannelType::kSendMessage);
|
|
|
|
// This will wait for the hung check created by
|
|
// StartTrackingMessagingStage(), then proceed.
|
|
{
|
|
SCOPED_TRACE(
|
|
"waiting for timeout check to run after starting and updating new "
|
|
"message tracking");
|
|
observer.WaitForMessageHung();
|
|
}
|
|
|
|
message_tracker()->StopTrackingMessagingStage(
|
|
message_id, MessageTracker::OpenChannelMessagePipelineResult::kOpened);
|
|
|
|
histogram_tester().ExpectTotalCount(
|
|
"Extensions.MessagePipeline.OpenChannelStatus.SendMessageChannel",
|
|
/*expected_count=*/1);
|
|
histogram_tester().ExpectBucketCount(
|
|
"Extensions.MessagePipeline.OpenChannelStatus.SendMessageChannel",
|
|
MessageTracker::OpenChannelMessagePipelineResult::kHung,
|
|
/*expected_count=*/1);
|
|
}
|
|
|
|
} // namespace extensions
|