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