Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/media/router/event_page_request_manager.h" | |
| 6 | |
| 7 #include "base/macros.h" | |
| 8 #include "base/test/histogram_tester.h" | |
| 9 #include "chrome/browser/media/router/mojo/media_router_mojo_metrics.h" | |
| 10 #include "chrome/test/base/testing_profile.h" | |
| 11 #include "content/public/test/test_browser_thread_bundle.h" | |
| 12 #include "extensions/browser/event_page_tracker.h" | |
| 13 #include "extensions/browser/extension_registry.h" | |
| 14 #include "extensions/browser/process_manager.h" | |
| 15 #include "extensions/browser/process_manager_factory.h" | |
| 16 #include "media/base/gmock_callback_support.h" | |
| 17 #include "testing/gmock/include/gmock/gmock.h" | |
| 18 #include "testing/gtest/include/gtest/gtest.h" | |
| 19 | |
| 20 using testing::_; | |
| 21 using testing::Return; | |
| 22 using testing::SaveArg; | |
| 23 using testing::StrictMock; | |
| 24 | |
| 25 namespace media_router { | |
| 26 | |
| 27 namespace { | |
| 28 | |
| 29 constexpr char kExtensionId[] = "extension_id"; | |
| 30 | |
| 31 // ProcessManager with a mocked method subset, for testing extension suspension. | |
| 32 class TestProcessManager : public extensions::ProcessManager { | |
| 33 public: | |
| 34 explicit TestProcessManager(content::BrowserContext* context) | |
| 35 : extensions::ProcessManager( | |
| 36 context, | |
| 37 context, | |
| 38 extensions::ExtensionRegistry::Get(context)) {} | |
| 39 ~TestProcessManager() override = default; | |
| 40 | |
| 41 static std::unique_ptr<KeyedService> Create( | |
| 42 content::BrowserContext* context) { | |
| 43 return base::MakeUnique<TestProcessManager>(context); | |
| 44 } | |
| 45 | |
| 46 MOCK_METHOD1(IsEventPageSuspended, bool(const std::string& ext_id)); | |
| 47 MOCK_METHOD2(WakeEventPage, | |
| 48 bool(const std::string& extension_id, | |
| 49 const base::Callback<void(bool)>& callback)); | |
| 50 | |
| 51 private: | |
| 52 DISALLOW_COPY_AND_ASSIGN(TestProcessManager); | |
| 53 }; | |
| 54 | |
| 55 class MockRequest { | |
|
imcheng
2017/06/30 00:17:38
Can you use base::MockCallback? https://cs.chromiu
takumif
2017/07/01 01:16:44
Done.
| |
| 56 public: | |
| 57 MockRequest() = default; | |
| 58 virtual ~MockRequest() = default; | |
| 59 | |
| 60 MOCK_METHOD0(Request, void()); | |
| 61 }; | |
| 62 | |
| 63 } // namespace | |
| 64 | |
| 65 class EventPageRequestManagerTest : public ::testing::Test { | |
| 66 public: | |
| 67 EventPageRequestManagerTest() = default; | |
| 68 ~EventPageRequestManagerTest() override = default; | |
| 69 | |
| 70 protected: | |
| 71 void SetUp() override { | |
| 72 profile_ = base::MakeUnique<TestingProfile>(); | |
| 73 // Set up a mock ProcessManager instance. | |
| 74 extensions::ProcessManagerFactory::GetInstance()->SetTestingFactory( | |
| 75 profile_.get(), &TestProcessManager::Create); | |
| 76 process_manager_ = static_cast<TestProcessManager*>( | |
| 77 extensions::ProcessManager::Get(profile_.get())); | |
| 78 DCHECK(process_manager_); | |
| 79 | |
| 80 request_manager_.reset(new EventPageRequestManager(profile_.get())); | |
| 81 request_manager_->SetExtensionId(kExtensionId); | |
| 82 } | |
| 83 | |
| 84 void TearDown() override { | |
| 85 request_manager_.reset(); | |
| 86 profile_.reset(); | |
| 87 } | |
| 88 | |
| 89 void ExpectWakeReasonBucketCount(MediaRouteProviderWakeReason reason, | |
| 90 int expected_count) { | |
| 91 histogram_tester_.ExpectBucketCount("MediaRouter.Provider.WakeReason", | |
| 92 static_cast<int>(reason), | |
| 93 expected_count); | |
| 94 } | |
| 95 | |
| 96 void ExpectWakeupBucketCount(MediaRouteProviderWakeup wakeup, | |
| 97 int expected_count) { | |
| 98 histogram_tester_.ExpectBucketCount("MediaRouter.Provider.Wakeup", | |
| 99 static_cast<int>(wakeup), | |
| 100 expected_count); | |
| 101 } | |
| 102 | |
| 103 TestProcessManager* process_manager_ = nullptr; | |
| 104 std::unique_ptr<EventPageRequestManager> request_manager_; | |
| 105 | |
| 106 private: | |
| 107 std::unique_ptr<TestingProfile> profile_; | |
| 108 base::HistogramTester histogram_tester_; | |
| 109 content::TestBrowserThreadBundle thread_bundle_; | |
| 110 | |
| 111 DISALLOW_COPY_AND_ASSIGN(EventPageRequestManagerTest); | |
| 112 }; | |
| 113 | |
| 114 TEST_F(EventPageRequestManagerTest, SetExtensionId) { | |
| 115 request_manager_->SetExtensionId(kExtensionId); | |
| 116 EXPECT_EQ(kExtensionId, | |
| 117 request_manager_->media_route_provider_extension_id()); | |
| 118 } | |
| 119 | |
| 120 TEST_F(EventPageRequestManagerTest, RunRequestImmediately) { | |
| 121 StrictMock<MockRequest> request; | |
| 122 request_manager_->SetWakeReason(MediaRouteProviderWakeReason::DETACH_ROUTE); | |
| 123 request_manager_->OnMojoConnectionsReady(); | |
| 124 | |
| 125 EXPECT_CALL(request, Request()); | |
| 126 request_manager_->RunOrDefer( | |
| 127 base::BindOnce(&MockRequest::Request, base::Unretained(&request))); | |
| 128 ExpectWakeReasonBucketCount(MediaRouteProviderWakeReason::DETACH_ROUTE, 1); | |
| 129 ExpectWakeupBucketCount(MediaRouteProviderWakeup::SUCCESS, 0); | |
| 130 } | |
| 131 | |
| 132 TEST_F(EventPageRequestManagerTest, DoNotRunRequestAfterConnectionError) { | |
| 133 StrictMock<MockRequest> request; | |
| 134 request_manager_->OnMojoConnectionsReady(); | |
| 135 request_manager_->OnMojoConnectionError(); | |
| 136 request_manager_->RunOrDefer( | |
| 137 base::BindOnce(&MockRequest::Request, base::Unretained(&request))); | |
| 138 } | |
| 139 | |
| 140 TEST_F(EventPageRequestManagerTest, RunRequestsOnConnectionsReady) { | |
| 141 StrictMock<MockRequest> request1; | |
| 142 StrictMock<MockRequest> request2; | |
| 143 request_manager_->SetWakeReason(MediaRouteProviderWakeReason::DETACH_ROUTE); | |
| 144 request_manager_->RunOrDefer( | |
| 145 base::BindOnce(&MockRequest::Request, base::Unretained(&request1))); | |
| 146 request_manager_->RunOrDefer( | |
| 147 base::BindOnce(&MockRequest::Request, base::Unretained(&request2))); | |
| 148 | |
| 149 EXPECT_CALL(request1, Request()); | |
| 150 EXPECT_CALL(request2, Request()); | |
| 151 request_manager_->OnMojoConnectionsReady(); | |
| 152 ExpectWakeReasonBucketCount(MediaRouteProviderWakeReason::DETACH_ROUTE, 1); | |
| 153 ExpectWakeupBucketCount(MediaRouteProviderWakeup::SUCCESS, 1); | |
| 154 } | |
| 155 | |
| 156 TEST_F(EventPageRequestManagerTest, DropOldestPendingRequest) { | |
| 157 StrictMock<MockRequest> request1; | |
| 158 MockRequest request2; | |
| 159 request_manager_->RunOrDefer( | |
| 160 base::BindOnce(&MockRequest::Request, base::Unretained(&request1))); | |
| 161 for (int i = 0; i < EventPageRequestManager::kMaxPendingRequests; i++) { | |
| 162 request_manager_->RunOrDefer( | |
| 163 base::BindOnce(&MockRequest::Request, base::Unretained(&request2))); | |
| 164 } | |
| 165 // Now the call on |request1| should have been pushed out of the queue and not | |
| 166 // be called. | |
| 167 EXPECT_CALL(request2, Request()); | |
| 168 request_manager_->OnMojoConnectionsReady(); | |
| 169 } | |
| 170 | |
| 171 TEST_F(EventPageRequestManagerTest, FailedWakeupDrainsQueue) { | |
| 172 StrictMock<MockRequest> request1; | |
| 173 StrictMock<MockRequest> request2; | |
| 174 request_manager_->SetWakeReason(MediaRouteProviderWakeReason::CREATE_ROUTE); | |
| 175 | |
| 176 base::Callback<void(bool)> extension_wakeup_callback; | |
| 177 EXPECT_CALL(*process_manager_, IsEventPageSuspended(kExtensionId)) | |
| 178 .WillOnce(Return(true)); | |
| 179 EXPECT_CALL(*process_manager_, WakeEventPage(kExtensionId, _)) | |
| 180 .WillOnce( | |
| 181 testing::DoAll(SaveArg<1>(&extension_wakeup_callback), Return(true))); | |
| 182 request_manager_->RunOrDefer( | |
| 183 base::BindOnce(&MockRequest::Request, base::Unretained(&request1))); | |
| 184 // Run the callback with false to indicate that the wakeup failed. This call | |
| 185 // drains the request queue, so |request1| won't be called. | |
| 186 extension_wakeup_callback.Run(false); | |
| 187 | |
| 188 EXPECT_CALL(*process_manager_, IsEventPageSuspended(kExtensionId)) | |
| 189 .WillRepeatedly(Return(false)); | |
| 190 // Requests that come in after queue is drained should be queued. | |
| 191 request_manager_->RunOrDefer( | |
| 192 base::BindOnce(&MockRequest::Request, base::Unretained(&request2))); | |
| 193 EXPECT_CALL(request2, Request()); | |
| 194 request_manager_->OnMojoConnectionsReady(); | |
| 195 } | |
| 196 | |
| 197 TEST_F(EventPageRequestManagerTest, TooManyWakeupAttemptsDrainsQueue) { | |
| 198 StrictMock<MockRequest> request1; | |
| 199 StrictMock<MockRequest> request2; | |
| 200 | |
| 201 // After these calls the request queue is drained, so |request1| won't be | |
| 202 // called. | |
| 203 EXPECT_CALL(*process_manager_, IsEventPageSuspended(kExtensionId)) | |
| 204 .WillRepeatedly(Return(true)); | |
| 205 EXPECT_CALL(*process_manager_, WakeEventPage(kExtensionId, _)) | |
| 206 .WillRepeatedly(Return(true)); | |
| 207 for (int i = 0; i <= EventPageRequestManager::kMaxWakeupAttemptCount; i++) { | |
| 208 request_manager_->RunOrDefer( | |
| 209 base::BindOnce(&MockRequest::Request, base::Unretained(&request1))); | |
| 210 } | |
| 211 EXPECT_CALL(*process_manager_, IsEventPageSuspended(kExtensionId)) | |
| 212 .WillRepeatedly(Return(false)); | |
| 213 | |
| 214 // Requests that come in after queue is drained should be queued. | |
| 215 request_manager_->RunOrDefer( | |
| 216 base::BindOnce(&MockRequest::Request, base::Unretained(&request2))); | |
| 217 EXPECT_CALL(request2, Request()); | |
| 218 request_manager_->OnMojoConnectionsReady(); | |
| 219 } | |
| 220 | |
| 221 } // namespace media_router | |
| OLD | NEW |