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

Side by Side Diff: blimp/client/session/assignment_source_unittest.cc

Issue 1687393002: Add assigner support to Blimp (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Build the ProxyConfigService on the main thread. Created 4 years, 10 months 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
OLDNEW
(Empty)
1 // Copyright 2016 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 "blimp/client/session/assignment_source.h"
6
7 #include "base/command_line.h"
8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h"
10 #include "base/test/test_simple_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "base/values.h"
13 #include "blimp/client/app/blimp_client_switches.h"
14 #include "blimp/common/protocol_version.h"
15 #include "net/url_request/test_url_fetcher_factory.h"
16 #include "testing/gmock/include/gmock/gmock.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 using testing::_;
20 using testing::InSequence;
21
22 namespace blimp {
23 namespace client {
24 namespace {
25
26 MATCHER_P(AssignmentEquals, assignment, "") {
27 return arg.transport_protocol == assignment.transport_protocol &&
28 arg.ip_endpoint == assignment.ip_endpoint &&
29 arg.client_token == assignment.client_token &&
30 arg.certificate == assignment.certificate &&
31 arg.certificate_fingerprint == assignment.certificate_fingerprint;
32 }
33
34 net::IPEndPoint BuildIPEndPoint(const std::string& ip, int port) {
35 net::IPAddress ip_address;
36 EXPECT_TRUE(ip_address.AssignFromIPLiteral(ip));
37
38 return net::IPEndPoint(ip_address, port);
39 }
40
41 Assignment BuildValidAssignment() {
42 Assignment assignment;
43 assignment.transport_protocol = Assignment::TransportProtocol::SSL;
44 assignment.ip_endpoint = BuildIPEndPoint("100.150.200.250", 500);
45 assignment.client_token = "SecretT0kenz";
46 assignment.certificate_fingerprint = "WhaleWhaleWhale";
47 assignment.certificate = "whaaaaaaaaaaaaale";
48 return assignment;
49 }
50
51 std::string BuildResponseFromAssignment(const Assignment& assignment) {
52 base::DictionaryValue dict;
53 dict.SetString("clientToken", assignment.client_token);
54 dict.SetString("host", assignment.ip_endpoint.address().ToString());
55 dict.SetInteger("port", assignment.ip_endpoint.port());
56 dict.SetString("certificateFingerprint", assignment.certificate_fingerprint);
57 dict.SetString("certificate", assignment.certificate);
58
59 std::string json;
60 base::JSONWriter::Write(dict, &json);
61 return json;
62 }
63
64 class AssignmentSourceTest : public testing::Test {
65 public:
66 AssignmentSourceTest()
67 : task_runner_(new base::TestSimpleTaskRunner),
68 task_runner_handle_(task_runner_),
69 source_(task_runner_, task_runner_) {}
70
71 // This expects the AssignmentSource::GetAssignment to return a custom
72 // endpoint without having to hit the network.
nyquist 2016/02/18 01:58:40 Could you help me as a new reader to this to say t
David Trainor- moved to gerrit 2016/02/18 16:01:55 Done.
73 void GetAlternateAssignment() {
74 source_.GetAssignment("",
75 base::Bind(&AssignmentSourceTest::AssignmentResponse,
76 base::Unretained(this)));
77 EXPECT_EQ(nullptr, factory_.GetFetcherByID(0));
78 task_runner_->RunUntilIdle();
79 }
80
81 // See net/base/net_errors.h for possible status errors.
82 void GetAssignment(net::HttpStatusCode response_code,
nyquist 2016/02/18 01:58:40 This name is a little bit confusing on first read-
David Trainor- moved to gerrit 2016/02/18 16:01:54 Done.
83 int status,
84 const std::string& response,
85 const std::string& client_auth_token,
86 const std::string& protocol_version) {
87 source_.GetAssignment(client_auth_token,
88 base::Bind(&AssignmentSourceTest::AssignmentResponse,
89 base::Unretained(this)));
90
91 net::TestURLFetcher* fetcher = factory_.GetFetcherByID(0);
92
93 task_runner_->RunUntilIdle();
94
95 EXPECT_NE(nullptr, fetcher);
96 EXPECT_EQ(kDefaultAssignerURL, fetcher->GetOriginalURL().spec());
97
98 // Check that the request has a valid protocol_version.
99 scoped_ptr<base::Value> json =
100 base::JSONReader::Read(fetcher->upload_data());
101 EXPECT_NE(nullptr, json.get());
102
103 const base::DictionaryValue* dict;
104 EXPECT_TRUE(json->GetAsDictionary(&dict));
105
106 std::string uploaded_protocol_version;
107 EXPECT_TRUE(
108 dict->GetString("protocol_version", &uploaded_protocol_version));
109 EXPECT_EQ(protocol_version, uploaded_protocol_version);
110
111 // Check that the request has a valid authentication header.
112 net::HttpRequestHeaders headers;
113 fetcher->GetExtraRequestHeaders(&headers);
114
115 std::string authorization;
116 EXPECT_TRUE(headers.GetHeader("Authorization", &authorization));
117 EXPECT_EQ("Bearer " + client_auth_token, authorization);
118
119 // Send the fake response back.
120 fetcher->set_response_code(response_code);
121 fetcher->set_status(net::URLRequestStatus::FromError(status));
122 fetcher->SetResponseString(response);
123 fetcher->delegate()->OnURLFetchComplete(fetcher);
124
125 task_runner_->RunUntilIdle();
126 }
127
128 MOCK_METHOD2(AssignmentResponse,
129 void(AssignmentSource::Result, const Assignment&));
130
131 protected:
132 // Used to drive all AssignmentSource tasks.
133 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
134 base::ThreadTaskRunnerHandle task_runner_handle_;
135
136 net::TestURLFetcherFactory factory_;
137
138 AssignmentSource source_;
139 };
140
141 TEST_F(AssignmentSourceTest, TestTCPAlternateEndpointSuccess) {
142 Assignment assignment;
143 assignment.transport_protocol = Assignment::TransportProtocol::TCP;
144 assignment.ip_endpoint = BuildIPEndPoint("100.150.200.250", 500);
145 assignment.client_token = kDummyClientToken;
146
147 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
148 switches::kBlimpletEndpoint, "tcp:100.150.200.250:500");
149
150 EXPECT_CALL(*this, AssignmentResponse(AssignmentSource::Result::RESULT_OK,
151 AssignmentEquals(assignment)))
152 .Times(1);
153
154 GetAlternateAssignment();
155 }
156
157 TEST_F(AssignmentSourceTest, TestSSLAlternateEndpointSuccess) {
158 Assignment assignment;
159 assignment.transport_protocol = Assignment::TransportProtocol::SSL;
160 assignment.ip_endpoint = BuildIPEndPoint("100.150.200.250", 500);
161 assignment.client_token = kDummyClientToken;
162
163 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
164 switches::kBlimpletEndpoint, "ssl:100.150.200.250:500");
165
166 EXPECT_CALL(*this, AssignmentResponse(AssignmentSource::Result::RESULT_OK,
167 AssignmentEquals(assignment)))
168 .Times(1);
169
170 GetAlternateAssignment();
171 }
172
173 TEST_F(AssignmentSourceTest, TestQUICAlternateEndpointSuccess) {
174 Assignment assignment;
175 assignment.transport_protocol = Assignment::TransportProtocol::QUIC;
176 assignment.ip_endpoint = BuildIPEndPoint("100.150.200.250", 500);
177 assignment.client_token = kDummyClientToken;
178
179 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
180 switches::kBlimpletEndpoint, "quic:100.150.200.250:500");
181
182 EXPECT_CALL(*this, AssignmentResponse(AssignmentSource::Result::RESULT_OK,
183 AssignmentEquals(assignment)))
184 .Times(1);
185
186 GetAlternateAssignment();
187 }
188
189 TEST_F(AssignmentSourceTest, TestSuccess) {
190 Assignment assignment = BuildValidAssignment();
191
192 EXPECT_CALL(*this, AssignmentResponse(AssignmentSource::Result::RESULT_OK,
193 AssignmentEquals(assignment)))
194 .Times(1);
195
196 GetAssignment(net::HTTP_OK, net::Error::OK,
197 BuildResponseFromAssignment(assignment), "UserAuthT0kenz",
198 kEngineVersion);
199 }
200
201 TEST_F(AssignmentSourceTest, TestSecondRequestInterruptsFirst) {
202 InSequence sequence;
203 Assignment assignment = BuildValidAssignment();
204
205 source_.GetAssignment("",
206 base::Bind(&AssignmentSourceTest::AssignmentResponse,
207 base::Unretained(this)));
208
209 EXPECT_CALL(*this, AssignmentResponse(
210 AssignmentSource::Result::RESULT_SERVER_INTERRUPTED,
211 AssignmentEquals(Assignment())))
212 .Times(1)
213 .RetiresOnSaturation();
214
215 EXPECT_CALL(*this, AssignmentResponse(AssignmentSource::Result::RESULT_OK,
216 AssignmentEquals(assignment)))
217 .Times(1)
218 .RetiresOnSaturation();
219
220 GetAssignment(net::HTTP_OK, net::Error::OK,
221 BuildResponseFromAssignment(assignment), "UserAuthT0kenz",
222 kEngineVersion);
223 }
224
225 TEST_F(AssignmentSourceTest, TestValidAfterError) {
226 InSequence sequence;
227 Assignment assignment = BuildValidAssignment();
228
229 EXPECT_CALL(*this, AssignmentResponse(
230 AssignmentSource::Result::RESULT_NETWORK_FAILURE, _))
231 .Times(1)
232 .RetiresOnSaturation();
233
234 EXPECT_CALL(*this, AssignmentResponse(AssignmentSource::Result::RESULT_OK,
235 AssignmentEquals(assignment)))
236 .Times(1)
237 .RetiresOnSaturation();
238
239 GetAssignment(net::HTTP_OK, net::Error::ERR_INSUFFICIENT_RESOURCES, "",
240 "UserAuthT0kenz", kEngineVersion);
241
242 GetAssignment(net::HTTP_OK, net::Error::OK,
243 BuildResponseFromAssignment(assignment), "UserAuthT0kenz",
244 kEngineVersion);
245 }
246
247 TEST_F(AssignmentSourceTest, TestNetworkFailure) {
248 EXPECT_CALL(*this, AssignmentResponse(
249 AssignmentSource::Result::RESULT_NETWORK_FAILURE, _));
250 GetAssignment(net::HTTP_OK, net::Error::ERR_INSUFFICIENT_RESOURCES, "",
251 "UserAuthT0kenz", kEngineVersion);
252 }
253
254 TEST_F(AssignmentSourceTest, TestBadRequest) {
255 EXPECT_CALL(*this, AssignmentResponse(
256 AssignmentSource::Result::RESULT_BAD_REQUEST, _));
257 GetAssignment(net::HTTP_BAD_REQUEST, net::Error::OK, "", "UserAuthT0kenz",
258 kEngineVersion);
259 }
260
261 TEST_F(AssignmentSourceTest, TestUnauthorized) {
262 EXPECT_CALL(*this,
263 AssignmentResponse(
264 AssignmentSource::Result::RESULT_EXPIRED_ACCESS_TOKEN, _));
265 GetAssignment(net::HTTP_UNAUTHORIZED, net::Error::OK, "", "UserAuthT0kenz",
266 kEngineVersion);
267 }
268
269 TEST_F(AssignmentSourceTest, TestForbidden) {
270 EXPECT_CALL(*this, AssignmentResponse(
271 AssignmentSource::Result::RESULT_USER_INVALID, _));
272 GetAssignment(net::HTTP_FORBIDDEN, net::Error::OK, "", "UserAuthT0kenz",
273 kEngineVersion);
274 }
275
276 TEST_F(AssignmentSourceTest, TestTooManyRequests) {
277 EXPECT_CALL(*this, AssignmentResponse(
278 AssignmentSource::Result::RESULT_OUT_OF_VMS, _));
279 GetAssignment(static_cast<net::HttpStatusCode>(429), net::Error::OK, "",
280 "UserAuthT0kenz", kEngineVersion);
281 }
282
283 TEST_F(AssignmentSourceTest, TestInternalServerError) {
284 EXPECT_CALL(*this, AssignmentResponse(
285 AssignmentSource::Result::RESULT_SERVER_ERROR, _));
286 GetAssignment(net::HTTP_INTERNAL_SERVER_ERROR, net::Error::OK, "",
287 "UserAuthT0kenz", kEngineVersion);
288 }
289
290 TEST_F(AssignmentSourceTest, TestUnexpectedNetCodeFallback) {
291 EXPECT_CALL(*this, AssignmentResponse(
292 AssignmentSource::Result::RESULT_BAD_RESPONSE, _));
293 GetAssignment(net::HTTP_NOT_IMPLEMENTED, net::Error::OK, "", "UserAuthT0kenz",
294 kEngineVersion);
295 }
296
297 TEST_F(AssignmentSourceTest, TestInvalidJsonResponse) {
298 Assignment assignment = BuildValidAssignment();
299
300 // Remove half the response.
301 std::string response = BuildResponseFromAssignment(assignment);
302 response = response.substr(response.size() / 2);
303
304 EXPECT_CALL(*this, AssignmentResponse(
305 AssignmentSource::Result::RESULT_BAD_RESPONSE, _));
306 GetAssignment(net::HTTP_OK, net::Error::OK, response, "UserAuthT0kenz",
307 kEngineVersion);
308 }
309
310 TEST_F(AssignmentSourceTest, TestMissingResponsePort) {
311 // Purposely do not add the 'port' field to the response.
312 base::DictionaryValue dict;
313 dict.SetString("clientToken", "SecretT0kenz");
314 dict.SetString("host", "happywhales");
315 dict.SetString("certificateFingerprint", "WhaleWhaleWhale");
316 dict.SetString("certificate", "whaaaaaaaaaaaaale");
317
318 std::string response;
319 base::JSONWriter::Write(dict, &response);
320
321 EXPECT_CALL(*this, AssignmentResponse(
322 AssignmentSource::Result::RESULT_BAD_RESPONSE, _));
323 GetAssignment(net::HTTP_OK, net::Error::OK, response, "UserAuthT0kenz",
324 kEngineVersion);
325 }
326
327 TEST_F(AssignmentSourceTest, TestInvalidIPAddress) {
328 // Purposely add an invalid IP field to the response.
329 base::DictionaryValue dict;
330 dict.SetString("clientToken", "SecretT0kenz");
331 dict.SetString("host", "happywhales");
332 dict.SetInteger("port", 500);
333 dict.SetString("certificateFingerprint", "WhaleWhaleWhale");
334 dict.SetString("certificate", "whaaaaaaaaaaaaale");
335
336 std::string response;
337 base::JSONWriter::Write(dict, &response);
338
339 EXPECT_CALL(*this, AssignmentResponse(
340 AssignmentSource::Result::RESULT_BAD_RESPONSE, _));
341 GetAssignment(net::HTTP_OK, net::Error::OK, response, "UserAuthT0kenz",
342 kEngineVersion);
343 }
344
345 } // namespace
346 } // namespace client
347 } // namespace blimp
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698