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.
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"
21 const char kClientId
[] = "42";
22 const char kAnotherClientId
[] = "24";
26 TestCallback() : run_count_(0), value_(0) {}
31 int run_count() { return run_count_
; }
32 int value() { return value_
; }
39 class DevToolsNetworkControllerHelper
{
41 DevToolsNetworkControllerHelper() :
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_
);
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()));
59 net::HttpRequestInfo
* GetRequest() {
61 request_
.reset(new MockHttpRequest(mock_transaction_
));
62 return request_
.get();
65 void SetNetworkState(const std::string id
, bool offline
) {
66 scoped_ptr
<DevToolsNetworkConditions
> conditions(
67 new DevToolsNetworkConditions(offline
));
68 controller_
.SetNetworkStateOnIO(id
, conditions
.Pass());
72 return transaction_
->Start(
73 GetRequest(), completion_callback_
, net::BoundNetLog());
77 return transaction_
->Read(buffer_
.get(), 64, completion_callback_
);
81 return transaction_
->interceptor_
->ShouldFail(transaction_
.get());
84 ~DevToolsNetworkControllerHelper() {
85 RemoveMockTransaction(&mock_transaction_
);
88 TestCallback
* callback() { return &callback_
; }
89 MockTransaction
* mock_transaction() { return &mock_transaction_
; }
90 DevToolsNetworkController
* controller() { return &controller_
; }
91 DevToolsNetworkTransaction
* transaction() { return transaction_
.get(); }
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_
;
105 TEST(DevToolsNetworkControllerTest
, SingleDisableEnable
) {
106 DevToolsNetworkControllerHelper helper
;
107 helper
.SetNetworkState(kClientId
, false);
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());
116 base::RunLoop().RunUntilIdle();
119 TEST(DevToolsNetworkControllerTest
, InterceptorIsolation
) {
120 DevToolsNetworkControllerHelper helper
;
121 helper
.SetNetworkState(kClientId
, false);
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());
130 helper
.SetNetworkState(kAnotherClientId
, false);
131 helper
.SetNetworkState(kClientId
, false);
132 base::RunLoop().RunUntilIdle();
135 TEST(DevToolsNetworkControllerTest
, FailOnStart
) {
136 DevToolsNetworkControllerHelper helper
;
137 helper
.SetNetworkState(kClientId
, true);
139 int rv
= helper
.Start();
140 EXPECT_EQ(rv
, net::ERR_INTERNET_DISCONNECTED
);
142 base::RunLoop().RunUntilIdle();
143 EXPECT_EQ(helper
.callback()->run_count(), 0);
146 TEST(DevToolsNetworkControllerTest
, FailRunningTransaction
) {
147 DevToolsNetworkControllerHelper helper
;
148 helper
.SetNetworkState(kClientId
, false);
149 TestCallback
* callback
= helper
.callback();
151 int rv
= helper
.Start();
152 EXPECT_EQ(rv
, net::OK
);
154 scoped_refptr
<net::IOBuffer
> buffer(new net::IOBuffer(64));
156 EXPECT_EQ(rv
, net::ERR_IO_PENDING
);
157 EXPECT_EQ(callback
->run_count(), 0);
159 helper
.SetNetworkState(kClientId
, true);
160 EXPECT_EQ(callback
->run_count(), 1);
161 EXPECT_EQ(callback
->value(), net::ERR_INTERNET_DISCONNECTED
);
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);
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);
175 TEST(DevToolsNetworkControllerTest
, ReadAfterFail
) {
176 DevToolsNetworkControllerHelper helper
;
177 helper
.SetNetworkState(kClientId
, false);
179 int rv
= helper
.Start();
180 EXPECT_EQ(rv
, net::OK
);
181 EXPECT_TRUE(helper
.transaction()->request());
183 helper
.SetNetworkState(kClientId
, true);
184 EXPECT_TRUE(helper
.transaction()->failed());
186 scoped_refptr
<net::IOBuffer
> buffer(new net::IOBuffer(64));
188 EXPECT_EQ(rv
, net::ERR_INTERNET_DISCONNECTED
);
190 // Check that callback is never invoked.
191 base::RunLoop().RunUntilIdle();
192 EXPECT_EQ(helper
.callback()->run_count(), 0);
195 TEST(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";
203 EXPECT_FALSE(helper
.ShouldFail());
204 helper
.SetNetworkState(kClientId
, true);
205 EXPECT_FALSE(helper
.ShouldFail());