Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(386)

Side by Side Diff: chrome/browser/devtools/adb_client_socket_browsertest.cc

Issue 43793002: [DevTools] Added browser tests for adb_client_socket.cc and android_device.cc (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Extracted adb server to separate class. Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/chrome_tests.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 "base/strings/string_number_conversions.h"
6 #include "chrome/browser/devtools/android_device.h"
7 #include "chrome/browser/ui/browser.h"
8 #include "chrome/test/base/in_process_browser_test.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/test/browser_test.h"
11 #include "content/public/test/test_utils.h"
12 #include "net/base/host_port_pair.h"
13 #include "net/base/io_buffer.h"
14 #include "net/base/ip_endpoint.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/net_log.h"
17 #include "net/socket/stream_socket.h"
18 #include "net/socket/tcp_server_socket.h"
19
20 using namespace net;
21
22 static const char kDeviceModelCommand[] = "shell:getprop ro.product.model";
23 static const char kDeviceModel[] = "Nexus 8";
24
25 static const int kBufferSize = 16*1024;
26 static const int kAdbPort = 5037;
27
28 static const int kAdbMessageHeaderSize = 4;
29
30 class MockAdbServer {
31 public:
32 MockAdbServer() {
33 input_buffer_ = new net::GrowableIOBuffer();
34 input_buffer_->SetCapacity(kBufferSize);
35
36 output_buffer_ = new net::GrowableIOBuffer();
37 }
38
39 void Start(base::Callback<bool(void)> callback) {
40 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
41
42 IPAddressNumber address;
43 ParseIPLiteralToNumber("127.0.0.1", &address);
44
45 IPEndPoint endpoint(address, kAdbPort);
46
47 server_socket_.reset(new TCPServerSocket(NULL, NetLog::Source()));
48 server_socket_->Listen(endpoint, 2);
49
50 callback.Run();
51
52 AcceptConnection();
53 }
54
55 void Shutdown(base::Callback<bool(void)> callback) {
56 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
57 server_socket_.reset();
58
59 if (client_socket_) {
60 client_socket_->Disconnect();
61 client_socket_.reset();
62 }
63
64 callback.Run();
65 }
66
67 private:
68 void AcceptConnection() {
69 if (client_socket_) {
70 client_socket_->Disconnect();
71 client_socket_.reset();
72 }
73
74 int accept_result = server_socket_->Accept(&client_socket_,
75 base::Bind(&MockAdbServer::OnAccepted, base::Unretained(this)));
76 if (accept_result != ERR_IO_PENDING)
77 OnAccepted(accept_result);
78 }
79
80 void OnAccepted(int result) {
81 ASSERT_EQ(result, 0);
82 ReadData();
83 }
84
85 void ReadData() {
86 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
87
88 int read_result = client_socket_->Read(
89 input_buffer_.get(),
90 input_buffer_->RemainingCapacity(),
91 base::Bind(&MockAdbServer::OnDataRead, base::Unretained(this)));
92
93 if (read_result != ERR_IO_PENDING)
94 OnDataRead(read_result);
95 }
96
97 void OnDataRead(int count) {
98 if (count <= 0) {
99 AcceptConnection();
100 return;
101 }
102
103 input_buffer_->set_offset(input_buffer_->offset() + count);
104
105 if (!TryProcessCommand()) {
106 // Posting is needed not to enter deep recursion in case too synchronous
Vladislav Kaznacheev 2013/10/28 14:12:37 in case OF too ...
107 // replies.
108 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
109 base::Bind(&MockAdbServer::ReadData, base::Unretained(this)));
110 }
111 }
112
113 void WriteData() {
114 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
115 ASSERT_NE(output_buffer_->offset(), output_buffer_->capacity());
116 int write_result = client_socket_->Write(
117 output_buffer_,
118 output_buffer_->capacity() - output_buffer_->offset(),
119 base::Bind(&MockAdbServer::OnDataWritten,
120 base::Unretained(this)));
121 if (write_result != ERR_IO_PENDING)
122 OnDataWritten(write_result);
123 }
124
125 void OnDataWritten(int count) {
126 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
127 if (count < 0) {
128 AcceptConnection();
129 return;
130 }
131
132 ASSERT_TRUE(count > 0);
133 ASSERT_TRUE(output_buffer_->offset() + count <= output_buffer_->capacity());
134
135 output_buffer_->set_offset(output_buffer_->offset() + count);
136 if (output_buffer_->offset() != output_buffer_->capacity())
137 WriteData();
138 else if (!TryProcessCommand())
139 ReadData();
140 }
141
142 bool TryProcessCommand() {
Vladislav Kaznacheev 2013/10/28 14:12:37 Lets split it one more time: a generic server that
143 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
144 char* data = input_buffer_->StartOfBuffer();
145 int data_size = input_buffer_->offset();
146
147 if (data_size >= kAdbMessageHeaderSize) {
148 std::string message_header(data, kAdbMessageHeaderSize);
149 int message_size;
150
151 EXPECT_TRUE(base::HexStringToInt(message_header, &message_size));
152
153 if (data_size >= message_size + kAdbMessageHeaderSize) {
154 std::string message_body(data + kAdbMessageHeaderSize, message_size );
155
156 memmove(data, data + message_size,
157 data_size - message_size - kAdbMessageHeaderSize);
158 input_buffer_->set_offset(
159 data_size - message_size - kAdbMessageHeaderSize);
160
161 ProcessCommand(message_body);
162
163 return true;
164 }
165 }
166
167 return false;
168 }
169
170 void ProcessCommand(const std::string& command) {
171 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
172
173 if (command == "host:devices") {
174 SendResponse("1498B321301A00A\tdevice");
175 } else if (command == "host:transport:1498B321301A00A") {
176 SendResponse("");
177 } else if (command == kDeviceModelCommand) {
178 SendResponse(kDeviceModel);
179 } else {
180 NOTREACHED() << "Unknown command - " << command;
181 }
182 }
183
184 void SendResponse(const std::string& response) {
185 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
186
187 std::stringstream response_stream;
188 response_stream << "OKAY";
189
190 int size = response.size();
191 if (size > 0) {
192 static const char kHexChars[] = "0123456789ABCDEF";
193 for (int i = 3; i >= 0; i--)
194 response_stream << kHexChars[ (size >> 4*i) & 0x0f ];
195 response_stream << response;
196 }
197
198 std::string response_data = response_stream.str();
199
200 output_buffer_->SetCapacity(response_data.size());
201 output_buffer_->set_offset(0);
202 mempcpy(output_buffer_->StartOfBuffer(), response_data.c_str(),
203 response_data.size());
204 WriteData();
205 }
206
207 private:
208 scoped_ptr<TCPServerSocket> server_socket_;
209 scoped_ptr<StreamSocket> client_socket_;
210 scoped_refptr<net::GrowableIOBuffer> input_buffer_;
211 scoped_refptr<net::GrowableIOBuffer> output_buffer_;
212 };
213
214 class AdbClientSocketTest : public InProcessBrowserTest {
215 public:
216 void StartTest() {
217 adb_thread_ = RefCountedAdbThread::GetInstance();
218 adb_server_.reset(new MockAdbServer());
219
220 content::BrowserThread::PostTask(
221 content::BrowserThread::IO,
222 FROM_HERE,
223 base::Bind(
224 &MockAdbServer::Start,
225 base::Unretained(adb_server_.get()),
226 base::Bind(
227 &content::BrowserThread::PostTask,
228 content::BrowserThread::UI,
229 FROM_HERE,
230 base::Bind(
231 &AdbClientSocketTest::QueryDevices,
232 base::Unretained(this)))));
233 }
234
235 void EndTest() {
236 adb_provider_ = NULL;
237 adb_thread_ = NULL;
238
239 content::BrowserThread::PostTask(
240 content::BrowserThread::IO,
241 FROM_HERE,
242 base::Bind(
243 &MockAdbServer::Shutdown,
244 base::Unretained(adb_server_.get()),
245 base::Bind(
246 &content::BrowserThread::PostTask,
247 content::BrowserThread::UI,
248 FROM_HERE,
249 base::Bind(
250 &content::MessageLoopRunner::Quit,
251 runner))));
252 }
253
254 private:
255 void QueryDevices() {
256 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
257
258 adb_provider_ = AndroidDeviceProvider::GetAdbDeviceProvider();
259 adb_provider_->QueryDevices(
260 base::Bind(&AdbClientSocketTest::AdbDevicesReceived,
261 base::Unretained(this)));
262 }
263
264 void AdbDevicesReceived(
265 const AndroidDeviceProvider::AndroidDevices& received_devices) {
266 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
267 #if defined(DEBUG_DEVTOOLS)
268 // Mock device is added
269 ASSERT_EQ(2U, received_devices.size());
270 #else
271 ASSERT_EQ(1U, received_devices.size());
272 #endif
273 android_device_ = received_devices.back();
274 ASSERT_EQ(android_device_->serial(), "1498B321301A00A");
275 ASSERT_TRUE(android_device_->is_connected());
276
277
278 adb_thread_->message_loop()->PostTask(
279 FROM_HERE,
280 base::Bind(&AndroidDevice::RunCommand,
281 android_device_,
282 kDeviceModelCommand,
283 base::Bind(&AdbClientSocketTest::AdbDeviceModelReceived,
284 base::Unretained(this))));
285 }
286
287 void AdbDeviceModelReceived(int result_code, const std::string& model) {
288 DCHECK_EQ(adb_thread_->message_loop(), base::MessageLoop::current());
289 ASSERT_EQ(result_code, 0);
290 ASSERT_EQ(model, kDeviceModel);
291 EndTest();
292 }
293
294 public:
295 scoped_refptr<content::MessageLoopRunner> runner;
296
297 private:
298 scoped_ptr<MockAdbServer> adb_server_;
299
300 scoped_refptr<RefCountedAdbThread> adb_thread_;
301 scoped_refptr<AndroidDeviceProvider> adb_provider_;
302 scoped_refptr<AndroidDevice> android_device_;
303 };
304
305 IN_PROC_BROWSER_TEST_F(AdbClientSocketTest, TestAdbClientSocket) {
306 runner = new content::MessageLoopRunner;
307
308 StartTest();
309
310 runner->Run();
311 }
OLDNEW
« no previous file with comments | « no previous file | chrome/chrome_tests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698