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

Side by Side Diff: remoting/host/setup/native_messaging_host_unittest.cc

Issue 23461030: Made sure NativeMessagingHostTest.All can handle out of order responses. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix clang warning Created 7 years, 3 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "remoting/host/setup/native_messaging_host.h" 5 #include "remoting/host/setup/native_messaging_host.h"
6 6
Lambros 2013/09/06 03:03:13 #include "base/basictypes.h" for arraysize().
alexeypa (please no reviews) 2013/09/06 16:14:57 Done.
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "base/json/json_reader.h" 8 #include "base/json/json_reader.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/run_loop.h" 11 #include "base/run_loop.h"
12 #include "base/stl_util.h" 12 #include "base/stl_util.h"
13 #include "base/strings/stringize_macros.h" 13 #include "base/strings/stringize_macros.h"
14 #include "base/values.h" 14 #include "base/values.h"
15 #include "google_apis/gaia/gaia_oauth_client.h" 15 #include "google_apis/gaia/gaia_oauth_client.h"
16 #include "net/base/file_stream.h" 16 #include "net/base/file_stream.h"
17 #include "net/base/net_util.h" 17 #include "net/base/net_util.h"
18 #include "remoting/host/pin_hash.h" 18 #include "remoting/host/pin_hash.h"
19 #include "remoting/host/setup/test_util.h" 19 #include "remoting/host/setup/test_util.h"
20 #include "remoting/protocol/pairing_registry.h" 20 #include "remoting/protocol/pairing_registry.h"
21 #include "remoting/protocol/protocol_mock_objects.h" 21 #include "remoting/protocol/protocol_mock_objects.h"
22 #include "testing/gtest/include/gtest/gtest.h" 22 #include "testing/gtest/include/gtest/gtest.h"
23 23
24 using remoting::protocol::MockPairingRegistryDelegate; 24 using remoting::protocol::MockPairingRegistryDelegate;
25 using remoting::protocol::PairingRegistry; 25 using remoting::protocol::PairingRegistry;
26 using remoting::protocol::SynchronousPairingRegistry; 26 using remoting::protocol::SynchronousPairingRegistry;
27 27
28 namespace { 28 namespace {
29 29
30 void VerifyHelloResponse(const base::DictionaryValue* response) { 30 void VerifyHelloResponse(scoped_ptr<base::DictionaryValue> response) {
Lambros 2013/09/06 03:03:13 Changing to scoped_ptr means that these functions
alexeypa (please no reviews) 2013/09/06 16:14:57 Yes. It expresses the intent of these functions be
31 ASSERT_TRUE(response); 31 ASSERT_TRUE(response);
32 std::string value; 32 std::string value;
33 EXPECT_TRUE(response->GetString("type", &value)); 33 EXPECT_TRUE(response->GetString("type", &value));
34 EXPECT_EQ("helloResponse", value); 34 EXPECT_EQ("helloResponse", value);
35 EXPECT_TRUE(response->GetString("version", &value)); 35 EXPECT_TRUE(response->GetString("version", &value));
36 EXPECT_EQ(STRINGIZE(VERSION), value); 36 EXPECT_EQ(STRINGIZE(VERSION), value);
37 } 37 }
38 38
39 void VerifyGetHostNameResponse(const base::DictionaryValue* response) { 39 void VerifyGetHostNameResponse(scoped_ptr<base::DictionaryValue> response) {
40 ASSERT_TRUE(response); 40 ASSERT_TRUE(response);
41 std::string value; 41 std::string value;
42 EXPECT_TRUE(response->GetString("type", &value)); 42 EXPECT_TRUE(response->GetString("type", &value));
43 EXPECT_EQ("getHostNameResponse", value); 43 EXPECT_EQ("getHostNameResponse", value);
44 EXPECT_TRUE(response->GetString("hostname", &value)); 44 EXPECT_TRUE(response->GetString("hostname", &value));
45 EXPECT_EQ(net::GetHostName(), value); 45 EXPECT_EQ(net::GetHostName(), value);
46 } 46 }
47 47
48 void VerifyGetPinHashResponse(const base::DictionaryValue* response) { 48 void VerifyGetPinHashResponse(scoped_ptr<base::DictionaryValue> response) {
49 ASSERT_TRUE(response); 49 ASSERT_TRUE(response);
50 std::string value; 50 std::string value;
51 EXPECT_TRUE(response->GetString("type", &value)); 51 EXPECT_TRUE(response->GetString("type", &value));
52 EXPECT_EQ("getPinHashResponse", value); 52 EXPECT_EQ("getPinHashResponse", value);
53 EXPECT_TRUE(response->GetString("hash", &value)); 53 EXPECT_TRUE(response->GetString("hash", &value));
54 EXPECT_EQ(remoting::MakeHostPinHash("my_host", "1234"), value); 54 EXPECT_EQ(remoting::MakeHostPinHash("my_host", "1234"), value);
55 } 55 }
56 56
57 void VerifyGenerateKeyPairResponse(const base::DictionaryValue* response) { 57 void VerifyGenerateKeyPairResponse(scoped_ptr<base::DictionaryValue> response) {
58 ASSERT_TRUE(response); 58 ASSERT_TRUE(response);
59 std::string value; 59 std::string value;
60 EXPECT_TRUE(response->GetString("type", &value)); 60 EXPECT_TRUE(response->GetString("type", &value));
61 EXPECT_EQ("generateKeyPairResponse", value); 61 EXPECT_EQ("generateKeyPairResponse", value);
62 EXPECT_TRUE(response->GetString("privateKey", &value)); 62 EXPECT_TRUE(response->GetString("privateKey", &value));
63 EXPECT_TRUE(response->GetString("publicKey", &value)); 63 EXPECT_TRUE(response->GetString("publicKey", &value));
64 } 64 }
65 65
66 void VerifyGetDaemonConfigResponse(const base::DictionaryValue* response) { 66 void VerifyGetDaemonConfigResponse(scoped_ptr<base::DictionaryValue> response) {
67 ASSERT_TRUE(response); 67 ASSERT_TRUE(response);
68 std::string value; 68 std::string value;
69 EXPECT_TRUE(response->GetString("type", &value)); 69 EXPECT_TRUE(response->GetString("type", &value));
70 EXPECT_EQ("getDaemonConfigResponse", value); 70 EXPECT_EQ("getDaemonConfigResponse", value);
71 const base::DictionaryValue* config = NULL; 71 const base::DictionaryValue* config = NULL;
72 EXPECT_TRUE(response->GetDictionary("config", &config)); 72 EXPECT_TRUE(response->GetDictionary("config", &config));
73 EXPECT_TRUE(base::DictionaryValue().Equals(config)); 73 EXPECT_TRUE(base::DictionaryValue().Equals(config));
74 } 74 }
75 75
76 void VerifyGetUsageStatsConsentResponse(const base::DictionaryValue* response) { 76 void VerifyGetUsageStatsConsentResponse(
77 scoped_ptr<base::DictionaryValue> response) {
77 ASSERT_TRUE(response); 78 ASSERT_TRUE(response);
78 std::string value; 79 std::string value;
79 EXPECT_TRUE(response->GetString("type", &value)); 80 EXPECT_TRUE(response->GetString("type", &value));
80 EXPECT_EQ("getUsageStatsConsentResponse", value); 81 EXPECT_EQ("getUsageStatsConsentResponse", value);
81 bool supported, allowed, set_by_policy; 82 bool supported, allowed, set_by_policy;
82 EXPECT_TRUE(response->GetBoolean("supported", &supported)); 83 EXPECT_TRUE(response->GetBoolean("supported", &supported));
83 EXPECT_TRUE(response->GetBoolean("allowed", &allowed)); 84 EXPECT_TRUE(response->GetBoolean("allowed", &allowed));
84 EXPECT_TRUE(response->GetBoolean("setByPolicy", &set_by_policy)); 85 EXPECT_TRUE(response->GetBoolean("setByPolicy", &set_by_policy));
85 EXPECT_TRUE(supported); 86 EXPECT_TRUE(supported);
86 EXPECT_TRUE(allowed); 87 EXPECT_TRUE(allowed);
87 EXPECT_TRUE(set_by_policy); 88 EXPECT_TRUE(set_by_policy);
88 } 89 }
89 90
90 void VerifyStopDaemonResponse(const base::DictionaryValue* response) { 91 void VerifyStopDaemonResponse(scoped_ptr<base::DictionaryValue> response) {
91 ASSERT_TRUE(response); 92 ASSERT_TRUE(response);
92 std::string value; 93 std::string value;
93 EXPECT_TRUE(response->GetString("type", &value)); 94 EXPECT_TRUE(response->GetString("type", &value));
94 EXPECT_EQ("stopDaemonResponse", value); 95 EXPECT_EQ("stopDaemonResponse", value);
95 EXPECT_TRUE(response->GetString("result", &value)); 96 EXPECT_TRUE(response->GetString("result", &value));
96 EXPECT_EQ("OK", value); 97 EXPECT_EQ("OK", value);
97 } 98 }
98 99
99 void VerifyGetDaemonStateResponse(const base::DictionaryValue* response) { 100 void VerifyGetDaemonStateResponse(scoped_ptr<base::DictionaryValue> response) {
100 ASSERT_TRUE(response); 101 ASSERT_TRUE(response);
101 std::string value; 102 std::string value;
102 EXPECT_TRUE(response->GetString("type", &value)); 103 EXPECT_TRUE(response->GetString("type", &value));
103 EXPECT_EQ("getDaemonStateResponse", value); 104 EXPECT_EQ("getDaemonStateResponse", value);
104 EXPECT_TRUE(response->GetString("state", &value)); 105 EXPECT_TRUE(response->GetString("state", &value));
105 EXPECT_EQ("STARTED", value); 106 EXPECT_EQ("STARTED", value);
106 } 107 }
107 108
108 void VerifyUpdateDaemonConfigResponse(const base::DictionaryValue* response) { 109 void VerifyUpdateDaemonConfigResponse(
110 scoped_ptr<base::DictionaryValue> response) {
109 ASSERT_TRUE(response); 111 ASSERT_TRUE(response);
110 std::string value; 112 std::string value;
111 EXPECT_TRUE(response->GetString("type", &value)); 113 EXPECT_TRUE(response->GetString("type", &value));
112 EXPECT_EQ("updateDaemonConfigResponse", value); 114 EXPECT_EQ("updateDaemonConfigResponse", value);
113 EXPECT_TRUE(response->GetString("result", &value)); 115 EXPECT_TRUE(response->GetString("result", &value));
114 EXPECT_EQ("OK", value); 116 EXPECT_EQ("OK", value);
115 } 117 }
116 118
117 void VerifyStartDaemonResponse(const base::DictionaryValue* response) { 119 void VerifyStartDaemonResponse(scoped_ptr<base::DictionaryValue> response) {
118 ASSERT_TRUE(response); 120 ASSERT_TRUE(response);
119 std::string value; 121 std::string value;
120 EXPECT_TRUE(response->GetString("type", &value)); 122 EXPECT_TRUE(response->GetString("type", &value));
121 EXPECT_EQ("startDaemonResponse", value); 123 EXPECT_EQ("startDaemonResponse", value);
122 EXPECT_TRUE(response->GetString("result", &value)); 124 EXPECT_TRUE(response->GetString("result", &value));
123 EXPECT_EQ("OK", value); 125 EXPECT_EQ("OK", value);
124 } 126 }
125 127
126 } // namespace 128 } // namespace
127 129
(...skipping 10 matching lines...) Expand all
138 bool consent, 140 bool consent,
139 const CompletionCallback& callback) OVERRIDE; 141 const CompletionCallback& callback) OVERRIDE;
140 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config, 142 virtual void UpdateConfig(scoped_ptr<base::DictionaryValue> config,
141 const CompletionCallback& callback) OVERRIDE; 143 const CompletionCallback& callback) OVERRIDE;
142 virtual void Stop(const CompletionCallback& callback) OVERRIDE; 144 virtual void Stop(const CompletionCallback& callback) OVERRIDE;
143 virtual void SetWindow(void* window_handle) OVERRIDE; 145 virtual void SetWindow(void* window_handle) OVERRIDE;
144 virtual void GetVersion(const GetVersionCallback& callback) OVERRIDE; 146 virtual void GetVersion(const GetVersionCallback& callback) OVERRIDE;
145 virtual void GetUsageStatsConsent( 147 virtual void GetUsageStatsConsent(
146 const GetUsageStatsConsentCallback& callback) OVERRIDE; 148 const GetUsageStatsConsentCallback& callback) OVERRIDE;
147 149
148 // Returns a record of functions called, so that unittests can verify these
149 // were called in the proper sequence.
150 std::string call_log() { return call_log_; }
151
152 private: 150 private:
153 std::string call_log_;
154
155 DISALLOW_COPY_AND_ASSIGN(MockDaemonController); 151 DISALLOW_COPY_AND_ASSIGN(MockDaemonController);
156 }; 152 };
157 153
158 MockDaemonController::MockDaemonController() {} 154 MockDaemonController::MockDaemonController() {}
159 155
160 MockDaemonController::~MockDaemonController() {} 156 MockDaemonController::~MockDaemonController() {}
161 157
162 DaemonController::State MockDaemonController::GetState() { 158 DaemonController::State MockDaemonController::GetState() {
163 call_log_ += "GetState:";
164 return DaemonController::STATE_STARTED; 159 return DaemonController::STATE_STARTED;
165 } 160 }
166 161
167 void MockDaemonController::GetConfig(const GetConfigCallback& callback) { 162 void MockDaemonController::GetConfig(const GetConfigCallback& callback) {
168 call_log_ += "GetConfig:";
169 scoped_ptr<base::DictionaryValue> config(new base::DictionaryValue()); 163 scoped_ptr<base::DictionaryValue> config(new base::DictionaryValue());
170 callback.Run(config.Pass()); 164 callback.Run(config.Pass());
171 } 165 }
172 166
173 void MockDaemonController::SetConfigAndStart( 167 void MockDaemonController::SetConfigAndStart(
174 scoped_ptr<base::DictionaryValue> config, bool consent, 168 scoped_ptr<base::DictionaryValue> config, bool consent,
175 const CompletionCallback& callback) { 169 const CompletionCallback& callback) {
176 call_log_ += "SetConfigAndStart:";
177 170
178 // Verify parameters passed in. 171 // Verify parameters passed in.
179 if (consent && config && config->HasKey("start")) { 172 if (consent && config && config->HasKey("start")) {
180 callback.Run(DaemonController::RESULT_OK); 173 callback.Run(DaemonController::RESULT_OK);
181 } else { 174 } else {
182 callback.Run(DaemonController::RESULT_FAILED); 175 callback.Run(DaemonController::RESULT_FAILED);
183 } 176 }
184 } 177 }
185 178
186 void MockDaemonController::UpdateConfig( 179 void MockDaemonController::UpdateConfig(
187 scoped_ptr<base::DictionaryValue> config, 180 scoped_ptr<base::DictionaryValue> config,
188 const CompletionCallback& callback) { 181 const CompletionCallback& callback) {
189 call_log_ += "UpdateConfig:";
190 if (config && config->HasKey("update")) { 182 if (config && config->HasKey("update")) {
191 callback.Run(DaemonController::RESULT_OK); 183 callback.Run(DaemonController::RESULT_OK);
192 } else { 184 } else {
193 callback.Run(DaemonController::RESULT_FAILED); 185 callback.Run(DaemonController::RESULT_FAILED);
194 } 186 }
195 } 187 }
196 188
197 void MockDaemonController::Stop(const CompletionCallback& callback) { 189 void MockDaemonController::Stop(const CompletionCallback& callback) {
198 call_log_ += "Stop:";
199 callback.Run(DaemonController::RESULT_OK); 190 callback.Run(DaemonController::RESULT_OK);
200 } 191 }
201 192
202 void MockDaemonController::SetWindow(void* window_handle) {} 193 void MockDaemonController::SetWindow(void* window_handle) {}
203 194
204 void MockDaemonController::GetVersion(const GetVersionCallback& callback) { 195 void MockDaemonController::GetVersion(const GetVersionCallback& callback) {
205 // Unused - NativeMessagingHost returns the compiled-in version string 196 // Unused - NativeMessagingHost returns the compiled-in version string
206 // instead of calling this method. 197 // instead of calling this method.
207 } 198 }
208 199
209 void MockDaemonController::GetUsageStatsConsent( 200 void MockDaemonController::GetUsageStatsConsent(
210 const GetUsageStatsConsentCallback& callback) { 201 const GetUsageStatsConsentCallback& callback) {
211 call_log_ += "GetUsageStatsConsent:";
212 callback.Run(true, true, true); 202 callback.Run(true, true, true);
213 } 203 }
214 204
215 class NativeMessagingHostTest : public testing::Test { 205 class NativeMessagingHostTest : public testing::Test {
216 public: 206 public:
217 NativeMessagingHostTest(); 207 NativeMessagingHostTest();
218 virtual ~NativeMessagingHostTest(); 208 virtual ~NativeMessagingHostTest();
219 209
220 virtual void SetUp() OVERRIDE; 210 virtual void SetUp() OVERRIDE;
221 virtual void TearDown() OVERRIDE; 211 virtual void TearDown() OVERRIDE;
222 212
223 void Run(); 213 void Run();
224 214
225 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); 215 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe();
226 216
227 void WriteMessageToInputPipe(const base::Value& message); 217 void WriteMessageToInputPipe(const base::Value& message);
228 218
229 // The Host process should shut down when it receives a malformed request. 219 // The Host process should shut down when it receives a malformed request.
230 // This is tested by sending a known-good request, followed by |message|, 220 // This is tested by sending a known-good request, followed by |message|,
231 // followed by the known-good request again. The response file should only 221 // followed by the known-good request again. The response file should only
232 // contain a single response from the first good request. 222 // contain a single response from the first good request.
233 void TestBadRequest(const base::Value& message); 223 void TestBadRequest(const base::Value& message);
234 224
235 protected: 225 protected:
236 // Reference to the MockDaemonController, which is owned by |host_|. 226 // Reference to the MockDaemonController, which is owned by |host_|.
237 MockDaemonController* daemon_controller_; 227 MockDaemonController* daemon_controller_;
238 std::string call_log_;
239 228
240 private: 229 private:
241 // Each test creates two unidirectional pipes: "input" and "output". 230 // Each test creates two unidirectional pipes: "input" and "output".
242 // NativeMessagingHost reads from input_read_handle and writes to 231 // NativeMessagingHost reads from input_read_handle and writes to
243 // output_write_handle. The unittest supplies data to input_write_handle, and 232 // output_write_handle. The unittest supplies data to input_write_handle, and
244 // verifies output from output_read_handle. 233 // verifies output from output_read_handle.
245 // 234 //
246 // unittest -> [input] -> NativeMessagingHost -> [output] -> unittest 235 // unittest -> [input] -> NativeMessagingHost -> [output] -> unittest
247 base::PlatformFile input_read_handle_; 236 base::PlatformFile input_read_handle_;
248 base::PlatformFile input_write_handle_; 237 base::PlatformFile input_write_handle_;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 278
290 void NativeMessagingHostTest::Run() { 279 void NativeMessagingHostTest::Run() {
291 // Close the write-end of input, so that the host sees EOF after reading 280 // Close the write-end of input, so that the host sees EOF after reading
292 // messages and won't block waiting for more input. 281 // messages and won't block waiting for more input.
293 base::ClosePlatformFile(input_write_handle_); 282 base::ClosePlatformFile(input_write_handle_);
294 host_->Start(); 283 host_->Start();
295 run_loop_.Run(); 284 run_loop_.Run();
296 285
297 // Destroy |host_| so that it closes its end of the output pipe, so that 286 // Destroy |host_| so that it closes its end of the output pipe, so that
298 // TestBadRequest() will see EOF and won't block waiting for more data. 287 // TestBadRequest() will see EOF and won't block waiting for more data.
299 // Since |host_| owns |daemon_controller_|, capture its call log first. 288 host_.reset();
300 call_log_ = daemon_controller_->call_log();
301 host_.reset(NULL);
302 } 289 }
303 290
304 scoped_ptr<base::DictionaryValue> 291 scoped_ptr<base::DictionaryValue>
305 NativeMessagingHostTest::ReadMessageFromOutputPipe() { 292 NativeMessagingHostTest::ReadMessageFromOutputPipe() {
306 uint32 length; 293 uint32 length;
307 int read_result = base::ReadPlatformFileAtCurrentPos( 294 int read_result = base::ReadPlatformFileAtCurrentPos(
308 output_read_handle_, reinterpret_cast<char*>(&length), sizeof(length)); 295 output_read_handle_, reinterpret_cast<char*>(&length), sizeof(length));
309 if (read_result != sizeof(length)) { 296 if (read_result != sizeof(length)) {
310 return scoped_ptr<base::DictionaryValue>(); 297 return scoped_ptr<base::DictionaryValue>();
311 } 298 }
(...skipping 24 matching lines...) Expand all
336 reinterpret_cast<char*>(&length), 323 reinterpret_cast<char*>(&length),
337 sizeof(length)); 324 sizeof(length));
338 base::WritePlatformFileAtCurrentPos(input_write_handle_, message_json.data(), 325 base::WritePlatformFileAtCurrentPos(input_write_handle_, message_json.data(),
339 length); 326 length);
340 } 327 }
341 328
342 void NativeMessagingHostTest::TestBadRequest(const base::Value& message) { 329 void NativeMessagingHostTest::TestBadRequest(const base::Value& message) {
343 base::DictionaryValue good_message; 330 base::DictionaryValue good_message;
344 good_message.SetString("type", "hello"); 331 good_message.SetString("type", "hello");
345 332
333 // This test currently relies on synchronous processing of hello messages and
334 // message parameters verification.
346 WriteMessageToInputPipe(good_message); 335 WriteMessageToInputPipe(good_message);
347 WriteMessageToInputPipe(message); 336 WriteMessageToInputPipe(message);
348 WriteMessageToInputPipe(good_message); 337 WriteMessageToInputPipe(good_message);
349 338
350 Run(); 339 Run();
351 340
352 // Read from output pipe, and verify responses. 341 // Read from output pipe, and verify responses.
353 scoped_ptr<base::DictionaryValue> response = 342 scoped_ptr<base::DictionaryValue> response =
354 ReadMessageFromOutputPipe(); 343 ReadMessageFromOutputPipe();
355 VerifyHelloResponse(response.get()); 344 VerifyHelloResponse(response.Pass());
356 345
357 response = ReadMessageFromOutputPipe(); 346 response = ReadMessageFromOutputPipe();
358 EXPECT_FALSE(response); 347 EXPECT_FALSE(response);
359 } 348 }
360 349
361 // Test all valid request-types. 350 // Test all valid request-types.
362 TEST_F(NativeMessagingHostTest, All) { 351 TEST_F(NativeMessagingHostTest, All) {
352 int next_id = 0;
363 base::DictionaryValue message; 353 base::DictionaryValue message;
354 message.SetInteger("id", next_id++);
Lambros 2013/09/06 03:03:13 Optional: Maybe have WriteMessageWithIdToInputPipe
alexeypa (please no reviews) 2013/09/06 16:14:57 I thought about it. The missing id test seems to b
364 message.SetString("type", "hello"); 355 message.SetString("type", "hello");
365 WriteMessageToInputPipe(message); 356 WriteMessageToInputPipe(message);
366 357
358 message.SetInteger("id", next_id++);
367 message.SetString("type", "getHostName"); 359 message.SetString("type", "getHostName");
368 WriteMessageToInputPipe(message); 360 WriteMessageToInputPipe(message);
369 361
362 message.SetInteger("id", next_id++);
370 message.SetString("type", "getPinHash"); 363 message.SetString("type", "getPinHash");
371 message.SetString("hostId", "my_host"); 364 message.SetString("hostId", "my_host");
372 message.SetString("pin", "1234"); 365 message.SetString("pin", "1234");
373 WriteMessageToInputPipe(message); 366 WriteMessageToInputPipe(message);
374 367
375 message.Clear(); 368 message.Clear();
369 message.SetInteger("id", next_id++);
376 message.SetString("type", "generateKeyPair"); 370 message.SetString("type", "generateKeyPair");
377 WriteMessageToInputPipe(message); 371 WriteMessageToInputPipe(message);
378 372
373 message.SetInteger("id", next_id++);
379 message.SetString("type", "getDaemonConfig"); 374 message.SetString("type", "getDaemonConfig");
380 WriteMessageToInputPipe(message); 375 WriteMessageToInputPipe(message);
381 376
377 message.SetInteger("id", next_id++);
382 message.SetString("type", "getUsageStatsConsent"); 378 message.SetString("type", "getUsageStatsConsent");
383 WriteMessageToInputPipe(message); 379 WriteMessageToInputPipe(message);
384 380
381 message.SetInteger("id", next_id++);
385 message.SetString("type", "stopDaemon"); 382 message.SetString("type", "stopDaemon");
386 WriteMessageToInputPipe(message); 383 WriteMessageToInputPipe(message);
387 384
385 message.SetInteger("id", next_id++);
388 message.SetString("type", "getDaemonState"); 386 message.SetString("type", "getDaemonState");
389 WriteMessageToInputPipe(message); 387 WriteMessageToInputPipe(message);
390 388
391 // Following messages require a "config" dictionary. 389 // Following messages require a "config" dictionary.
392 base::DictionaryValue config; 390 base::DictionaryValue config;
393 config.SetBoolean("update", true); 391 config.SetBoolean("update", true);
394 message.Set("config", config.DeepCopy()); 392 message.Set("config", config.DeepCopy());
393 message.SetInteger("id", next_id++);
395 message.SetString("type", "updateDaemonConfig"); 394 message.SetString("type", "updateDaemonConfig");
396 WriteMessageToInputPipe(message); 395 WriteMessageToInputPipe(message);
397 396
398 config.Clear(); 397 config.Clear();
399 config.SetBoolean("start", true); 398 config.SetBoolean("start", true);
400 message.Set("config", config.DeepCopy()); 399 message.Set("config", config.DeepCopy());
401 message.SetBoolean("consent", true); 400 message.SetBoolean("consent", true);
401 message.SetInteger("id", next_id++);
402 message.SetString("type", "startDaemon"); 402 message.SetString("type", "startDaemon");
403 WriteMessageToInputPipe(message); 403 WriteMessageToInputPipe(message);
404 404
405 Run(); 405 Run();
406 406
407 // Read from output pipe, and verify responses. 407 void (*verify_routines[])(scoped_ptr<base::DictionaryValue>) = {
408 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); 408 &VerifyHelloResponse,
409 VerifyHelloResponse(response.get()); 409 &VerifyGetHostNameResponse,
410 &VerifyGetPinHashResponse,
411 &VerifyGenerateKeyPairResponse,
412 &VerifyGetDaemonConfigResponse,
413 &VerifyGetUsageStatsConsentResponse,
414 &VerifyStopDaemonResponse,
415 &VerifyGetDaemonStateResponse,
416 &VerifyUpdateDaemonConfigResponse,
417 &VerifyStartDaemonResponse,
418 };
419 ASSERT_EQ(arraysize(verify_routines), static_cast<size_t>(next_id));
410 420
411 response = ReadMessageFromOutputPipe(); 421 // Read all responses from output pipe, and verify them.
412 VerifyGetHostNameResponse(response.get()); 422 for (int i = 0; i < next_id; ++i) {
423 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe();
413 424
414 response = ReadMessageFromOutputPipe(); 425 // Make sure that id is available and is in the range.
415 VerifyGetPinHashResponse(response.get()); 426 int id;
427 ASSERT_TRUE(response->GetInteger("id", &id));
428 ASSERT_TRUE(0 <= id && id < next_id);
416 429
417 response = ReadMessageFromOutputPipe(); 430 // Call the verification routine corresponding to the message id.
Lambros 2013/09/06 03:03:13 ASSERT_TRUE(verify_routines[id] != NULL); before t
alexeypa (please no reviews) 2013/09/06 16:14:57 Calling a routine using a NULL pointer will crash
Lambros 2013/09/06 18:55:42 We shouldn't be crashing the test binary, as this
alexeypa (please no reviews) 2013/09/06 22:19:26 Done.
418 VerifyGenerateKeyPairResponse(response.get()); 431 verify_routines[id](response.Pass());
419 432
420 response = ReadMessageFromOutputPipe(); 433 // Clear the pointer so that the routine cannot be called the second time.
421 VerifyGetDaemonConfigResponse(response.get()); 434 verify_routines[id] = NULL;
422 435 }
423 response = ReadMessageFromOutputPipe();
424 VerifyGetUsageStatsConsentResponse(response.get());
425
426 response = ReadMessageFromOutputPipe();
427 VerifyStopDaemonResponse(response.get());
428
429 response = ReadMessageFromOutputPipe();
430 VerifyGetDaemonStateResponse(response.get());
431
432 response = ReadMessageFromOutputPipe();
433 VerifyUpdateDaemonConfigResponse(response.get());
434
435 response = ReadMessageFromOutputPipe();
436 VerifyStartDaemonResponse(response.get());
437
438 // Verify that DaemonController methods were called in the correct sequence.
439 // This detects cases where NativeMessagingHost might call a wrong method
440 // that takes the same parameters and writes out the same response.
441 EXPECT_EQ("GetConfig:GetUsageStatsConsent:Stop:GetState:UpdateConfig:"
442 "SetConfigAndStart:", call_log_);
443 } 436 }
444 437
445 // Verify that response ID matches request ID. 438 // Verify that response ID matches request ID.
446 TEST_F(NativeMessagingHostTest, Id) { 439 TEST_F(NativeMessagingHostTest, Id) {
447 base::DictionaryValue message; 440 base::DictionaryValue message;
448 message.SetString("type", "hello"); 441 message.SetString("type", "hello");
449 WriteMessageToInputPipe(message); 442 WriteMessageToInputPipe(message);
450 message.SetString("id", "42"); 443 message.SetString("id", "42");
451 WriteMessageToInputPipe(message); 444 WriteMessageToInputPipe(message);
452 445
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 511
519 // Verify rejection if startDaemon request has no "consent" parameter. 512 // Verify rejection if startDaemon request has no "consent" parameter.
520 TEST_F(NativeMessagingHostTest, StartDaemonNoConsent) { 513 TEST_F(NativeMessagingHostTest, StartDaemonNoConsent) {
521 base::DictionaryValue message; 514 base::DictionaryValue message;
522 message.SetString("type", "startDaemon"); 515 message.SetString("type", "startDaemon");
523 message.Set("config", base::DictionaryValue().DeepCopy()); 516 message.Set("config", base::DictionaryValue().DeepCopy());
524 TestBadRequest(message); 517 TestBadRequest(message);
525 } 518 }
526 519
527 } // namespace remoting 520 } // namespace remoting
OLDNEW
« remoting/host/setup/native_messaging_host.cc ('K') | « remoting/host/setup/native_messaging_host.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698