Index: content/browser/service_worker/service_worker_version_unittest.cc |
diff --git a/content/browser/service_worker/service_worker_version_unittest.cc b/content/browser/service_worker/service_worker_version_unittest.cc |
index ea76b51478d093d008aff76da9dd50c117539845..bbe183a1c62e42d60c65e45277e933ea0879a6c6 100644 |
--- a/content/browser/service_worker/service_worker_version_unittest.cc |
+++ b/content/browser/service_worker/service_worker_version_unittest.cc |
@@ -10,6 +10,7 @@ |
#include "base/macros.h" |
#include "base/memory/ptr_util.h" |
#include "base/run_loop.h" |
+#include "base/test/histogram_tester.h" |
#include "content/browser/service_worker/embedded_worker_registry.h" |
#include "content/browser/service_worker/embedded_worker_status.h" |
#include "content/browser/service_worker/embedded_worker_test_helper.h" |
@@ -1327,6 +1328,29 @@ TEST_F(ServiceWorkerFailToStartTest, FailingWorkerUsesNewRendererProcess) { |
base::RunLoop().RunUntilIdle(); |
} |
+TEST_F(ServiceWorkerFailToStartTest, RestartStalledWorker) { |
+ ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_MAX_VALUE; |
+ ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_MAX_VALUE; |
+ version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME, |
+ CreateReceiverOnCurrentThread(&status1)); |
+ base::RunLoop().RunUntilIdle(); |
+ // The default start mode is StartMode::STALL. So the callback of StartWorker |
+ // is not called yet. |
+ EXPECT_EQ(SERVICE_WORKER_ERROR_MAX_VALUE, status1); |
+ |
+ // Set StartMode::SUCCEED. So the next start worker will be successful. |
+ set_start_mode(MessageReceiverDisallowStart::StartMode::SUCCEED); |
+ |
+ // StartWorker message will be sent again because OnStopped is called before |
+ // OnStarted. |
+ version_->StopWorker(CreateReceiverOnCurrentThread(&status2)); |
+ base::RunLoop().RunUntilIdle(); |
+ |
+ EXPECT_EQ(SERVICE_WORKER_OK, status1); |
+ EXPECT_EQ(SERVICE_WORKER_OK, status2); |
+ EXPECT_EQ(EmbeddedWorkerStatus::RUNNING, version_->running_status()); |
+} |
+ |
TEST_F(ServiceWorkerVersionTest, DispatchConcurrentEvent) { |
ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_NETWORK; // dummy value |
@@ -1545,4 +1569,157 @@ TEST_F(ServiceWorkerVersionTest, DispatchEvent_MultipleResponse) { |
EXPECT_TRUE(version_->FinishRequest(request_id2, true)); |
} |
+class ServiceWorkerNavigationHintUMATest : public ServiceWorkerVersionTest { |
+ protected: |
+ ServiceWorkerNavigationHintUMATest() : ServiceWorkerVersionTest() {} |
+ |
+ void StartWorker(ServiceWorkerMetrics::EventType purpose) { |
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
+ version_->StartWorker(purpose, CreateReceiverOnCurrentThread(&status)); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(SERVICE_WORKER_OK, status); |
+ } |
+ |
+ void StopWorker() { |
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
+ version_->StopWorker(CreateReceiverOnCurrentThread(&status)); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(SERVICE_WORKER_OK, status); |
+ } |
+ |
+ void SimpleNavigationHintTest( |
+ ServiceWorkerMetrics::EventType purpose, |
+ const char* changed_historam_name, |
+ const std::vector<const char*>& unchanged_historam_names) { |
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED); |
+ StartWorker(purpose); |
+ StopWorker(); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, true, 0); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, false, 1); |
+ histogram_tester_.ExpectBucketCount(changed_historam_name, true, 0); |
+ histogram_tester_.ExpectBucketCount(changed_historam_name, false, 1); |
+ for (const char* unchanged_historam_name : unchanged_historam_names) |
+ histogram_tester_.ExpectTotalCount(unchanged_historam_name, 0); |
+ |
+ StartWorker(purpose); |
+ SimulateDispatchEvent(ServiceWorkerMetrics::EventType::MESSAGE); |
+ StopWorker(); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, true, 0); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, false, 2); |
+ histogram_tester_.ExpectBucketCount(changed_historam_name, true, 0); |
+ histogram_tester_.ExpectBucketCount(changed_historam_name, false, 2); |
+ for (const char* unchanged_historam_name : unchanged_historam_names) |
+ histogram_tester_.ExpectTotalCount(unchanged_historam_name, 0); |
+ |
+ StartWorker(purpose); |
+ SimulateDispatchEvent(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME); |
+ StopWorker(); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, true, 1); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, false, 2); |
+ histogram_tester_.ExpectBucketCount(changed_historam_name, true, 1); |
+ histogram_tester_.ExpectBucketCount(changed_historam_name, false, 2); |
+ for (const char* unchanged_historam_name : unchanged_historam_names) |
+ histogram_tester_.ExpectTotalCount(unchanged_historam_name, 0); |
+ |
+ StartWorker(purpose); |
+ SimulateDispatchEvent(ServiceWorkerMetrics::EventType::FETCH_SUB_FRAME); |
+ StopWorker(); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, true, 2); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, false, 2); |
+ histogram_tester_.ExpectBucketCount(changed_historam_name, true, 2); |
+ histogram_tester_.ExpectBucketCount(changed_historam_name, false, 2); |
+ for (const char* unchanged_historam_name : unchanged_historam_names) |
+ histogram_tester_.ExpectTotalCount(unchanged_historam_name, 0); |
+ } |
+ |
+ static const char kNavigationHintPrecision[]; |
+ static const char kLinkMouseDown[]; |
+ static const char kLinkTapUnconfirmed[]; |
+ static const char kLinkTapDown[]; |
+ |
+ base::HistogramTester histogram_tester_; |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(ServiceWorkerNavigationHintUMATest); |
+}; |
+ |
+const char ServiceWorkerNavigationHintUMATest::kNavigationHintPrecision[] = |
+ "ServiceWorker.NavigationHintPrecision"; |
+const char ServiceWorkerNavigationHintUMATest::kLinkMouseDown[] = |
+ "ServiceWorker.NavigationHintPrecision.LINK_MOUSE_DOWN"; |
+const char ServiceWorkerNavigationHintUMATest::kLinkTapUnconfirmed[] = |
+ "ServiceWorker.NavigationHintPrecision.LINK_TAP_UNCONFIRMED"; |
+const char ServiceWorkerNavigationHintUMATest::kLinkTapDown[] = |
+ "ServiceWorker.NavigationHintPrecision.LINK_TAP_DOWN"; |
+ |
+TEST_F(ServiceWorkerNavigationHintUMATest, LinkMouseDown) { |
+ SimpleNavigationHintTest( |
+ ServiceWorkerMetrics::EventType::NAVIGATION_HINT_LINK_MOUSE_DOWN, |
+ kLinkMouseDown, {kLinkTapUnconfirmed, kLinkTapDown}); |
+} |
+ |
+TEST_F(ServiceWorkerNavigationHintUMATest, LinkTapUnconfirmed) { |
+ SimpleNavigationHintTest( |
+ ServiceWorkerMetrics::EventType::NAVIGATION_HINT_LINK_TAP_UNCONFIRMED, |
+ kLinkTapUnconfirmed, {kLinkMouseDown, kLinkTapDown}); |
+} |
+ |
+TEST_F(ServiceWorkerNavigationHintUMATest, LinkTapDown) { |
+ SimpleNavigationHintTest( |
+ ServiceWorkerMetrics::EventType::NAVIGATION_HINT_LINK_TAP_DOWN, |
+ kLinkTapDown, {kLinkMouseDown, kLinkTapUnconfirmed}); |
+} |
+ |
+TEST_F(ServiceWorkerNavigationHintUMATest, ConcurrentStart) { |
+ version_->SetStatus(ServiceWorkerVersion::ACTIVATED); |
+ ServiceWorkerStatusCode status1 = SERVICE_WORKER_ERROR_MAX_VALUE; |
+ ServiceWorkerStatusCode status2 = SERVICE_WORKER_ERROR_MAX_VALUE; |
+ version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME, |
+ CreateReceiverOnCurrentThread(&status1)); |
+ version_->StartWorker( |
+ ServiceWorkerMetrics::EventType::NAVIGATION_HINT_LINK_MOUSE_DOWN, |
+ CreateReceiverOnCurrentThread(&status2)); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(SERVICE_WORKER_OK, status1); |
+ EXPECT_EQ(SERVICE_WORKER_OK, status2); |
+ StopWorker(); |
+ // The first purpose of starting worker was not a navigation hint. |
+ histogram_tester_.ExpectTotalCount(kNavigationHintPrecision, 0); |
+ |
+ status1 = SERVICE_WORKER_ERROR_MAX_VALUE; |
+ status2 = SERVICE_WORKER_ERROR_MAX_VALUE; |
+ version_->StartWorker( |
+ ServiceWorkerMetrics::EventType::NAVIGATION_HINT_LINK_MOUSE_DOWN, |
+ CreateReceiverOnCurrentThread(&status2)); |
+ version_->StartWorker(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME, |
+ CreateReceiverOnCurrentThread(&status1)); |
+ base::RunLoop().RunUntilIdle(); |
+ EXPECT_EQ(SERVICE_WORKER_OK, status1); |
+ EXPECT_EQ(SERVICE_WORKER_OK, status2); |
+ SimulateDispatchEvent(ServiceWorkerMetrics::EventType::FETCH_MAIN_FRAME); |
+ StopWorker(); |
+ // The first purpose of starting worker was a navigation hint. |
+ histogram_tester_.ExpectTotalCount(kNavigationHintPrecision, 1); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, true, 1); |
+ histogram_tester_.ExpectBucketCount(kNavigationHintPrecision, false, 0); |
+} |
+ |
+TEST_F(ServiceWorkerNavigationHintUMATest, StartWhileStopping) { |
+ StartWorker(ServiceWorkerMetrics::EventType::NAVIGATION_HINT_LINK_MOUSE_DOWN); |
+ ServiceWorkerStatusCode status = SERVICE_WORKER_ERROR_MAX_VALUE; |
+ version_->StopWorker(CreateReceiverOnCurrentThread(&status)); |
+ EXPECT_EQ(EmbeddedWorkerStatus::STOPPING, version_->running_status()); |
+ histogram_tester_.ExpectTotalCount(kLinkMouseDown, 0); |
+ |
+ StartWorker(ServiceWorkerMetrics::EventType::NAVIGATION_HINT_LINK_TAP_DOWN); |
+ // The UMA for kLinkMouseDown must be recorded while restarting. |
+ histogram_tester_.ExpectTotalCount(kLinkMouseDown, 1); |
+ histogram_tester_.ExpectTotalCount(kLinkTapDown, 0); |
+ EXPECT_EQ(SERVICE_WORKER_OK, status); |
+ StopWorker(); |
+ // The UMA for kLinkMouseDown must be recorded when the worker stopped. |
+ histogram_tester_.ExpectTotalCount(kLinkMouseDown, 1); |
+ histogram_tester_.ExpectTotalCount(kLinkTapDown, 1); |
+} |
+ |
} // namespace content |