devtools_network_controller_unittest.cc revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
1// Copyright 2014 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 <string> 6 7#include "base/memory/ref_counted.h" 8#include "base/memory/scoped_ptr.h" 9#include "base/message_loop/message_loop.h" 10#include "base/run_loop.h" 11#include "chrome/browser/devtools/devtools_network_conditions.h" 12#include "chrome/browser/devtools/devtools_network_controller.h" 13#include "chrome/browser/devtools/devtools_network_interceptor.h" 14#include "chrome/browser/devtools/devtools_network_transaction.h" 15#include "net/http/http_transaction_test_util.h" 16#include "testing/gtest/include/gtest/gtest.h" 17#include "url/gurl.h" 18 19namespace test { 20 21const char kClientId[] = "42"; 22const char kAnotherClientId[] = "24"; 23 24class TestCallback { 25 public: 26 TestCallback() : run_count_(0), value_(0) {} 27 void Run(int value) { 28 run_count_++; 29 value_ = value; 30 } 31 int run_count() { return run_count_; } 32 int value() { return value_; } 33 34 private: 35 int run_count_; 36 int value_; 37}; 38 39class DevToolsNetworkControllerHelper { 40 public: 41 DevToolsNetworkControllerHelper() : 42 completion_callback_( 43 base::Bind(&TestCallback::Run, base::Unretained(&callback_))), 44 mock_transaction_(kSimpleGET_Transaction), 45 buffer_(new net::IOBuffer(64)) { 46 mock_transaction_.test_mode = TEST_MODE_SYNC_NET_START; 47 mock_transaction_.url = "http://dot.com"; 48 mock_transaction_.request_headers = 49 "X-DevTools-Emulate-Network-Conditions-Client-Id: 42\r\n"; 50 AddMockTransaction(&mock_transaction_); 51 52 scoped_ptr<net::HttpTransaction> network_transaction; 53 network_layer_.CreateTransaction( 54 net::DEFAULT_PRIORITY, &network_transaction); 55 transaction_.reset(new DevToolsNetworkTransaction( 56 &controller_, network_transaction.Pass())); 57 } 58 59 net::HttpRequestInfo* GetRequest() { 60 if (!request_) 61 request_.reset(new MockHttpRequest(mock_transaction_)); 62 return request_.get(); 63 } 64 65 void SetNetworkState(const std::string id, bool offline) { 66 scoped_refptr<DevToolsNetworkConditions> conditions( 67 new DevToolsNetworkConditions(offline)); 68 controller_.SetNetworkStateOnIO(id, conditions); 69 } 70 71 int Start() { 72 return transaction_->Start( 73 GetRequest(), completion_callback_, net::BoundNetLog()); 74 } 75 76 int Read() { 77 return transaction_->Read(buffer_.get(), 64, completion_callback_); 78 } 79 80 bool ShouldFail() { 81 return transaction_->interceptor_->ShouldFail(transaction_.get()); 82 } 83 84 ~DevToolsNetworkControllerHelper() { 85 RemoveMockTransaction(&mock_transaction_); 86 } 87 88 TestCallback* callback() { return &callback_; } 89 MockTransaction* mock_transaction() { return &mock_transaction_; } 90 DevToolsNetworkController* controller() { return &controller_; } 91 DevToolsNetworkTransaction* transaction() { return transaction_.get(); } 92 93 private: 94 base::MessageLoop message_loop_; 95 MockNetworkLayer network_layer_; 96 TestCallback callback_; 97 net::CompletionCallback completion_callback_; 98 MockTransaction mock_transaction_; 99 DevToolsNetworkController controller_; 100 scoped_ptr<DevToolsNetworkTransaction> transaction_; 101 scoped_refptr<net::IOBuffer> buffer_; 102 scoped_ptr<MockHttpRequest> request_; 103}; 104 105TEST(DevToolsNetworkControllerTest, SingleDisableEnable) { 106 DevToolsNetworkControllerHelper helper; 107 helper.SetNetworkState(kClientId, false); 108 helper.Start(); 109 110 EXPECT_FALSE(helper.ShouldFail()); 111 helper.SetNetworkState(kClientId, true); 112 EXPECT_TRUE(helper.ShouldFail()); 113 helper.SetNetworkState(kClientId, false); 114 EXPECT_FALSE(helper.ShouldFail()); 115 116 base::RunLoop().RunUntilIdle(); 117} 118 119TEST(DevToolsNetworkControllerTest, InterceptorIsolation) { 120 DevToolsNetworkControllerHelper helper; 121 helper.SetNetworkState(kClientId, false); 122 helper.Start(); 123 124 EXPECT_FALSE(helper.ShouldFail()); 125 helper.SetNetworkState(kAnotherClientId, true); 126 EXPECT_FALSE(helper.ShouldFail()); 127 helper.SetNetworkState(kClientId, true); 128 EXPECT_TRUE(helper.ShouldFail()); 129 130 helper.SetNetworkState(kAnotherClientId, false); 131 helper.SetNetworkState(kClientId, false); 132 base::RunLoop().RunUntilIdle(); 133} 134 135TEST(DevToolsNetworkControllerTest, FailOnStart) { 136 DevToolsNetworkControllerHelper helper; 137 helper.SetNetworkState(kClientId, true); 138 139 int rv = helper.Start(); 140 EXPECT_EQ(rv, net::ERR_INTERNET_DISCONNECTED); 141 142 base::RunLoop().RunUntilIdle(); 143 EXPECT_EQ(helper.callback()->run_count(), 0); 144} 145 146TEST(DevToolsNetworkControllerTest, FailRunningTransaction) { 147 DevToolsNetworkControllerHelper helper; 148 helper.SetNetworkState(kClientId, false); 149 TestCallback* callback = helper.callback(); 150 151 int rv = helper.Start(); 152 EXPECT_EQ(rv, net::OK); 153 154 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(64)); 155 rv = helper.Read(); 156 EXPECT_EQ(rv, net::ERR_IO_PENDING); 157 EXPECT_EQ(callback->run_count(), 0); 158 159 helper.SetNetworkState(kClientId, true); 160 EXPECT_EQ(callback->run_count(), 1); 161 EXPECT_EQ(callback->value(), net::ERR_INTERNET_DISCONNECTED); 162 163 // Wait until HttpTrancation completes reading and invokes callback. 164 // DevToolsNetworkTransaction should ignore callback, because it has 165 // reported network error already. 166 base::RunLoop().RunUntilIdle(); 167 EXPECT_EQ(callback->run_count(), 1); 168 169 // Check that transaction in not failed second time. 170 helper.SetNetworkState(kClientId, false); 171 helper.SetNetworkState(kClientId, true); 172 EXPECT_EQ(callback->run_count(), 1); 173} 174 175TEST(DevToolsNetworkControllerTest, ReadAfterFail) { 176 DevToolsNetworkControllerHelper helper; 177 helper.SetNetworkState(kClientId, false); 178 179 int rv = helper.Start(); 180 EXPECT_EQ(rv, net::OK); 181 EXPECT_TRUE(helper.transaction()->request()); 182 183 helper.SetNetworkState(kClientId, true); 184 EXPECT_TRUE(helper.transaction()->failed()); 185 186 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(64)); 187 rv = helper.Read(); 188 EXPECT_EQ(rv, net::ERR_INTERNET_DISCONNECTED); 189 190 // Check that callback is never invoked. 191 base::RunLoop().RunUntilIdle(); 192 EXPECT_EQ(helper.callback()->run_count(), 0); 193} 194 195TEST(DevToolsNetworkControllerTest, AllowsDevToolsRequests) { 196 DevToolsNetworkControllerHelper helper; 197 helper.SetNetworkState(kClientId, false); 198 helper.mock_transaction()->request_headers = 199 "X-DevTools-Emulate-Network-Conditions-Client-Id: 42\r\n" 200 "X-DevTools-Request-Initiator: frontend\r\n"; 201 helper.Start(); 202 203 EXPECT_FALSE(helper.ShouldFail()); 204 helper.SetNetworkState(kClientId, true); 205 EXPECT_FALSE(helper.ShouldFail()); 206} 207 208} // namespace test 209