| OLD | NEW |
| 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/it2me/it2me_native_messaging_host.h" | 5 #include "remoting/host/it2me/it2me_native_messaging_host.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 12 #include "base/json/json_reader.h" | 12 #include "base/json/json_reader.h" |
| 13 #include "base/json/json_writer.h" | 13 #include "base/json/json_writer.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" |
| 15 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 16 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
| 17 #include "base/stl_util.h" | 18 #include "base/stl_util.h" |
| 18 #include "base/strings/stringize_macros.h" | 19 #include "base/strings/stringize_macros.h" |
| 19 #include "base/values.h" | 20 #include "base/values.h" |
| 20 #include "net/base/file_stream.h" | 21 #include "net/base/file_stream.h" |
| 21 #include "remoting/base/auto_thread_task_runner.h" | 22 #include "remoting/base/auto_thread_task_runner.h" |
| 22 #include "remoting/host/chromoting_host_context.h" | 23 #include "remoting/host/chromoting_host_context.h" |
| 23 #include "remoting/host/native_messaging/log_message_handler.h" | 24 #include "remoting/host/native_messaging/log_message_handler.h" |
| 24 #include "remoting/host/native_messaging/native_messaging_pipe.h" | 25 #include "remoting/host/native_messaging/native_messaging_pipe.h" |
| 25 #include "remoting/host/native_messaging/pipe_messaging_channel.h" | 26 #include "remoting/host/native_messaging/pipe_messaging_channel.h" |
| 26 #include "remoting/host/policy_watcher.h" | 27 #include "remoting/host/policy_watcher.h" |
| 27 #include "remoting/host/setup/test_util.h" | 28 #include "remoting/host/setup/test_util.h" |
| 28 #include "testing/gtest/include/gtest/gtest.h" | 29 #include "testing/gtest/include/gtest/gtest.h" |
| 29 | 30 |
| 30 namespace remoting { | 31 namespace remoting { |
| 31 | 32 |
| 32 namespace { | 33 namespace { |
| 33 | 34 |
| 34 const char kTestAccessCode[] = "888888"; | 35 const char kTestAccessCode[] = "888888"; |
| 35 const int kTestAccessCodeLifetimeInSeconds = 666; | 36 const int kTestAccessCodeLifetimeInSeconds = 666; |
| 36 const char kTestClientUsername[] = "some_user@gmail.com"; | 37 const char kTestClientUsername[] = "some_user@gmail.com"; |
| 37 | 38 |
| 38 void VerifyId(scoped_ptr<base::DictionaryValue> response, int expected_value) { | 39 void VerifyId(std::unique_ptr<base::DictionaryValue> response, |
| 40 int expected_value) { |
| 39 ASSERT_TRUE(response); | 41 ASSERT_TRUE(response); |
| 40 | 42 |
| 41 int value; | 43 int value; |
| 42 EXPECT_TRUE(response->GetInteger("id", &value)); | 44 EXPECT_TRUE(response->GetInteger("id", &value)); |
| 43 EXPECT_EQ(expected_value, value); | 45 EXPECT_EQ(expected_value, value); |
| 44 } | 46 } |
| 45 | 47 |
| 46 void VerifyStringProperty(scoped_ptr<base::DictionaryValue> response, | 48 void VerifyStringProperty(std::unique_ptr<base::DictionaryValue> response, |
| 47 const std::string& name, | 49 const std::string& name, |
| 48 const std::string& expected_value) { | 50 const std::string& expected_value) { |
| 49 ASSERT_TRUE(response); | 51 ASSERT_TRUE(response); |
| 50 | 52 |
| 51 std::string value; | 53 std::string value; |
| 52 EXPECT_TRUE(response->GetString(name, &value)); | 54 EXPECT_TRUE(response->GetString(name, &value)); |
| 53 EXPECT_EQ(expected_value, value); | 55 EXPECT_EQ(expected_value, value); |
| 54 } | 56 } |
| 55 | 57 |
| 56 // Verity the values of the "type" and "id" properties | 58 // Verity the values of the "type" and "id" properties |
| 57 void VerifyCommonProperties(scoped_ptr<base::DictionaryValue> response, | 59 void VerifyCommonProperties(std::unique_ptr<base::DictionaryValue> response, |
| 58 const std::string& type, | 60 const std::string& type, |
| 59 int id) { | 61 int id) { |
| 60 ASSERT_TRUE(response); | 62 ASSERT_TRUE(response); |
| 61 | 63 |
| 62 std::string string_value; | 64 std::string string_value; |
| 63 EXPECT_TRUE(response->GetString("type", &string_value)); | 65 EXPECT_TRUE(response->GetString("type", &string_value)); |
| 64 EXPECT_EQ(type, string_value); | 66 EXPECT_EQ(type, string_value); |
| 65 | 67 |
| 66 int int_value; | 68 int int_value; |
| 67 EXPECT_TRUE(response->GetInteger("id", &int_value)); | 69 EXPECT_TRUE(response->GetInteger("id", &int_value)); |
| 68 EXPECT_EQ(id, int_value); | 70 EXPECT_EQ(id, int_value); |
| 69 } | 71 } |
| 70 | 72 |
| 71 } // namespace | 73 } // namespace |
| 72 | 74 |
| 73 class MockIt2MeHost : public It2MeHost { | 75 class MockIt2MeHost : public It2MeHost { |
| 74 public: | 76 public: |
| 75 MockIt2MeHost(scoped_ptr<ChromotingHostContext> context, | 77 MockIt2MeHost(std::unique_ptr<ChromotingHostContext> context, |
| 76 scoped_ptr<PolicyWatcher> policy_watcher, | 78 std::unique_ptr<PolicyWatcher> policy_watcher, |
| 77 base::WeakPtr<It2MeHost::Observer> observer, | 79 base::WeakPtr<It2MeHost::Observer> observer, |
| 78 const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, | 80 const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, |
| 79 const std::string& directory_bot_jid) | 81 const std::string& directory_bot_jid) |
| 80 : It2MeHost(std::move(context), | 82 : It2MeHost(std::move(context), |
| 81 std::move(policy_watcher), | 83 std::move(policy_watcher), |
| 82 nullptr, | 84 nullptr, |
| 83 observer, | 85 observer, |
| 84 xmpp_server_config, | 86 xmpp_server_config, |
| 85 directory_bot_jid) {} | 87 directory_bot_jid) {} |
| 86 | 88 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 FROM_HERE, base::Bind(&It2MeHost::SetStateForTesting, this, state, "")); | 150 FROM_HERE, base::Bind(&It2MeHost::SetStateForTesting, this, state, "")); |
| 149 } else { | 151 } else { |
| 150 SetStateForTesting(state, ""); | 152 SetStateForTesting(state, ""); |
| 151 } | 153 } |
| 152 } | 154 } |
| 153 | 155 |
| 154 class MockIt2MeHostFactory : public It2MeHostFactory { | 156 class MockIt2MeHostFactory : public It2MeHostFactory { |
| 155 public: | 157 public: |
| 156 MockIt2MeHostFactory() : It2MeHostFactory() {} | 158 MockIt2MeHostFactory() : It2MeHostFactory() {} |
| 157 scoped_refptr<It2MeHost> CreateIt2MeHost( | 159 scoped_refptr<It2MeHost> CreateIt2MeHost( |
| 158 scoped_ptr<ChromotingHostContext> context, | 160 std::unique_ptr<ChromotingHostContext> context, |
| 159 base::WeakPtr<It2MeHost::Observer> observer, | 161 base::WeakPtr<It2MeHost::Observer> observer, |
| 160 const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, | 162 const XmppSignalStrategy::XmppServerConfig& xmpp_server_config, |
| 161 const std::string& directory_bot_jid) override { | 163 const std::string& directory_bot_jid) override { |
| 162 return new MockIt2MeHost(std::move(context), nullptr, observer, | 164 return new MockIt2MeHost(std::move(context), nullptr, observer, |
| 163 xmpp_server_config, directory_bot_jid); | 165 xmpp_server_config, directory_bot_jid); |
| 164 } | 166 } |
| 165 | 167 |
| 166 private: | 168 private: |
| 167 DISALLOW_COPY_AND_ASSIGN(MockIt2MeHostFactory); | 169 DISALLOW_COPY_AND_ASSIGN(MockIt2MeHostFactory); |
| 168 }; // MockIt2MeHostFactory | 170 }; // MockIt2MeHostFactory |
| 169 | 171 |
| 170 class It2MeNativeMessagingHostTest : public testing::Test { | 172 class It2MeNativeMessagingHostTest : public testing::Test { |
| 171 public: | 173 public: |
| 172 It2MeNativeMessagingHostTest() {} | 174 It2MeNativeMessagingHostTest() {} |
| 173 ~It2MeNativeMessagingHostTest() override {} | 175 ~It2MeNativeMessagingHostTest() override {} |
| 174 | 176 |
| 175 void SetUp() override; | 177 void SetUp() override; |
| 176 void TearDown() override; | 178 void TearDown() override; |
| 177 | 179 |
| 178 protected: | 180 protected: |
| 179 scoped_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); | 181 std::unique_ptr<base::DictionaryValue> ReadMessageFromOutputPipe(); |
| 180 void WriteMessageToInputPipe(const base::Value& message); | 182 void WriteMessageToInputPipe(const base::Value& message); |
| 181 | 183 |
| 182 void VerifyHelloResponse(int request_id); | 184 void VerifyHelloResponse(int request_id); |
| 183 void VerifyErrorResponse(); | 185 void VerifyErrorResponse(); |
| 184 void VerifyConnectResponses(int request_id); | 186 void VerifyConnectResponses(int request_id); |
| 185 void VerifyDisconnectResponses(int request_id); | 187 void VerifyDisconnectResponses(int request_id); |
| 186 | 188 |
| 187 // The Host process should shut down when it receives a malformed request. | 189 // The Host process should shut down when it receives a malformed request. |
| 188 // This is tested by sending a known-good request, followed by |message|, | 190 // This is tested by sending a known-good request, followed by |message|, |
| 189 // followed by the known-good request again. The response file should only | 191 // followed by the known-good request again. The response file should only |
| 190 // contain a single response from the first good request. | 192 // contain a single response from the first good request. |
| 191 void TestBadRequest(const base::Value& message, bool expect_error_response); | 193 void TestBadRequest(const base::Value& message, bool expect_error_response); |
| 192 void TestConnect(); | 194 void TestConnect(); |
| 193 | 195 |
| 194 private: | 196 private: |
| 195 void StartHost(); | 197 void StartHost(); |
| 196 void ExitTest(); | 198 void ExitTest(); |
| 197 | 199 |
| 198 // Each test creates two unidirectional pipes: "input" and "output". | 200 // Each test creates two unidirectional pipes: "input" and "output". |
| 199 // It2MeNativeMessagingHost reads from input_read_file and writes to | 201 // It2MeNativeMessagingHost reads from input_read_file and writes to |
| 200 // output_write_file. The unittest supplies data to input_write_handle, and | 202 // output_write_file. The unittest supplies data to input_write_handle, and |
| 201 // verifies output from output_read_handle. | 203 // verifies output from output_read_handle. |
| 202 // | 204 // |
| 203 // unittest -> [input] -> It2MeNativeMessagingHost -> [output] -> unittest | 205 // unittest -> [input] -> It2MeNativeMessagingHost -> [output] -> unittest |
| 204 base::File input_write_file_; | 206 base::File input_write_file_; |
| 205 base::File output_read_file_; | 207 base::File output_read_file_; |
| 206 | 208 |
| 207 // Message loop of the test thread. | 209 // Message loop of the test thread. |
| 208 scoped_ptr<base::MessageLoop> test_message_loop_; | 210 std::unique_ptr<base::MessageLoop> test_message_loop_; |
| 209 scoped_ptr<base::RunLoop> test_run_loop_; | 211 std::unique_ptr<base::RunLoop> test_run_loop_; |
| 210 | 212 |
| 211 scoped_ptr<base::Thread> host_thread_; | 213 std::unique_ptr<base::Thread> host_thread_; |
| 212 scoped_ptr<base::RunLoop> host_run_loop_; | 214 std::unique_ptr<base::RunLoop> host_run_loop_; |
| 213 | 215 |
| 214 // Task runner of the host thread. | 216 // Task runner of the host thread. |
| 215 scoped_refptr<AutoThreadTaskRunner> host_task_runner_; | 217 scoped_refptr<AutoThreadTaskRunner> host_task_runner_; |
| 216 scoped_ptr<remoting::NativeMessagingPipe> pipe_; | 218 std::unique_ptr<remoting::NativeMessagingPipe> pipe_; |
| 217 | 219 |
| 218 DISALLOW_COPY_AND_ASSIGN(It2MeNativeMessagingHostTest); | 220 DISALLOW_COPY_AND_ASSIGN(It2MeNativeMessagingHostTest); |
| 219 }; | 221 }; |
| 220 | 222 |
| 221 void It2MeNativeMessagingHostTest::SetUp() { | 223 void It2MeNativeMessagingHostTest::SetUp() { |
| 222 test_message_loop_.reset(new base::MessageLoop()); | 224 test_message_loop_.reset(new base::MessageLoop()); |
| 223 test_run_loop_.reset(new base::RunLoop()); | 225 test_run_loop_.reset(new base::RunLoop()); |
| 224 | 226 |
| 225 // Run the host on a dedicated thread. | 227 // Run the host on a dedicated thread. |
| 226 host_thread_.reset(new base::Thread("host_thread")); | 228 host_thread_.reset(new base::Thread("host_thread")); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 247 | 249 |
| 248 // Closing the write-end of the input will send an EOF to the native | 250 // Closing the write-end of the input will send an EOF to the native |
| 249 // messaging reader. This will trigger a host shutdown. | 251 // messaging reader. This will trigger a host shutdown. |
| 250 input_write_file_.Close(); | 252 input_write_file_.Close(); |
| 251 | 253 |
| 252 // Start a new RunLoop and Wait until the host finishes shutting down. | 254 // Start a new RunLoop and Wait until the host finishes shutting down. |
| 253 test_run_loop_.reset(new base::RunLoop()); | 255 test_run_loop_.reset(new base::RunLoop()); |
| 254 test_run_loop_->Run(); | 256 test_run_loop_->Run(); |
| 255 | 257 |
| 256 // Verify there are no more message in the output pipe. | 258 // Verify there are no more message in the output pipe. |
| 257 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); | 259 std::unique_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); |
| 258 EXPECT_FALSE(response); | 260 EXPECT_FALSE(response); |
| 259 | 261 |
| 260 // The It2MeNativeMessagingHost dtor closes the handles that are passed to it. | 262 // The It2MeNativeMessagingHost dtor closes the handles that are passed to it. |
| 261 // So the only handle left to close is |output_read_file_|. | 263 // So the only handle left to close is |output_read_file_|. |
| 262 output_read_file_.Close(); | 264 output_read_file_.Close(); |
| 263 } | 265 } |
| 264 | 266 |
| 265 scoped_ptr<base::DictionaryValue> | 267 std::unique_ptr<base::DictionaryValue> |
| 266 It2MeNativeMessagingHostTest::ReadMessageFromOutputPipe() { | 268 It2MeNativeMessagingHostTest::ReadMessageFromOutputPipe() { |
| 267 while (true) { | 269 while (true) { |
| 268 uint32_t length; | 270 uint32_t length; |
| 269 int read_result = output_read_file_.ReadAtCurrentPos( | 271 int read_result = output_read_file_.ReadAtCurrentPos( |
| 270 reinterpret_cast<char*>(&length), sizeof(length)); | 272 reinterpret_cast<char*>(&length), sizeof(length)); |
| 271 if (read_result != sizeof(length)) { | 273 if (read_result != sizeof(length)) { |
| 272 // The output pipe has been closed, return an empty message. | 274 // The output pipe has been closed, return an empty message. |
| 273 return nullptr; | 275 return nullptr; |
| 274 } | 276 } |
| 275 | 277 |
| 276 std::string message_json(length, '\0'); | 278 std::string message_json(length, '\0'); |
| 277 read_result = output_read_file_.ReadAtCurrentPos( | 279 read_result = output_read_file_.ReadAtCurrentPos( |
| 278 string_as_array(&message_json), length); | 280 string_as_array(&message_json), length); |
| 279 if (read_result != static_cast<int>(length)) { | 281 if (read_result != static_cast<int>(length)) { |
| 280 LOG(ERROR) << "Message size (" << read_result | 282 LOG(ERROR) << "Message size (" << read_result |
| 281 << ") doesn't match the header (" << length << ")."; | 283 << ") doesn't match the header (" << length << ")."; |
| 282 return nullptr; | 284 return nullptr; |
| 283 } | 285 } |
| 284 | 286 |
| 285 scoped_ptr<base::Value> message = base::JSONReader::Read(message_json); | 287 std::unique_ptr<base::Value> message = base::JSONReader::Read(message_json); |
| 286 if (!message || !message->IsType(base::Value::TYPE_DICTIONARY)) { | 288 if (!message || !message->IsType(base::Value::TYPE_DICTIONARY)) { |
| 287 LOG(ERROR) << "Malformed message:" << message_json; | 289 LOG(ERROR) << "Malformed message:" << message_json; |
| 288 return nullptr; | 290 return nullptr; |
| 289 } | 291 } |
| 290 | 292 |
| 291 scoped_ptr<base::DictionaryValue> result = make_scoped_ptr( | 293 std::unique_ptr<base::DictionaryValue> result = base::WrapUnique( |
| 292 static_cast<base::DictionaryValue*>(message.release())); | 294 static_cast<base::DictionaryValue*>(message.release())); |
| 293 std::string type; | 295 std::string type; |
| 294 // If this is a debug message log, ignore it, otherwise return it. | 296 // If this is a debug message log, ignore it, otherwise return it. |
| 295 if (!result->GetString("type", &type) || | 297 if (!result->GetString("type", &type) || |
| 296 type != LogMessageHandler::kDebugMessageTypeName) { | 298 type != LogMessageHandler::kDebugMessageTypeName) { |
| 297 return result; | 299 return result; |
| 298 } | 300 } |
| 299 } | 301 } |
| 300 } | 302 } |
| 301 | 303 |
| 302 void It2MeNativeMessagingHostTest::WriteMessageToInputPipe( | 304 void It2MeNativeMessagingHostTest::WriteMessageToInputPipe( |
| 303 const base::Value& message) { | 305 const base::Value& message) { |
| 304 std::string message_json; | 306 std::string message_json; |
| 305 base::JSONWriter::Write(message, &message_json); | 307 base::JSONWriter::Write(message, &message_json); |
| 306 | 308 |
| 307 uint32_t length = message_json.length(); | 309 uint32_t length = message_json.length(); |
| 308 input_write_file_.WriteAtCurrentPos(reinterpret_cast<char*>(&length), | 310 input_write_file_.WriteAtCurrentPos(reinterpret_cast<char*>(&length), |
| 309 sizeof(length)); | 311 sizeof(length)); |
| 310 input_write_file_.WriteAtCurrentPos(message_json.data(), length); | 312 input_write_file_.WriteAtCurrentPos(message_json.data(), length); |
| 311 } | 313 } |
| 312 | 314 |
| 313 void It2MeNativeMessagingHostTest::VerifyHelloResponse(int request_id) { | 315 void It2MeNativeMessagingHostTest::VerifyHelloResponse(int request_id) { |
| 314 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); | 316 std::unique_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); |
| 315 VerifyCommonProperties(std::move(response), "helloResponse", request_id); | 317 VerifyCommonProperties(std::move(response), "helloResponse", request_id); |
| 316 } | 318 } |
| 317 | 319 |
| 318 void It2MeNativeMessagingHostTest::VerifyErrorResponse() { | 320 void It2MeNativeMessagingHostTest::VerifyErrorResponse() { |
| 319 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); | 321 std::unique_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); |
| 320 VerifyStringProperty(std::move(response), "type", "error"); | 322 VerifyStringProperty(std::move(response), "type", "error"); |
| 321 } | 323 } |
| 322 | 324 |
| 323 void It2MeNativeMessagingHostTest::VerifyConnectResponses(int request_id) { | 325 void It2MeNativeMessagingHostTest::VerifyConnectResponses(int request_id) { |
| 324 bool connect_response_received = false; | 326 bool connect_response_received = false; |
| 325 bool starting_received = false; | 327 bool starting_received = false; |
| 326 bool requestedAccessCode_received = false; | 328 bool requestedAccessCode_received = false; |
| 327 bool receivedAccessCode_received = false; | 329 bool receivedAccessCode_received = false; |
| 328 bool connected_received = false; | 330 bool connected_received = false; |
| 329 | 331 |
| 330 // We expect a total of 5 messages: 1 connectResponse and 4 hostStateChanged. | 332 // We expect a total of 5 messages: 1 connectResponse and 4 hostStateChanged. |
| 331 for (int i = 0; i < 5; ++i) { | 333 for (int i = 0; i < 5; ++i) { |
| 332 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); | 334 std::unique_ptr<base::DictionaryValue> response = |
| 335 ReadMessageFromOutputPipe(); |
| 333 ASSERT_TRUE(response); | 336 ASSERT_TRUE(response); |
| 334 | 337 |
| 335 std::string type; | 338 std::string type; |
| 336 ASSERT_TRUE(response->GetString("type", &type)); | 339 ASSERT_TRUE(response->GetString("type", &type)); |
| 337 | 340 |
| 338 if (type == "connectResponse") { | 341 if (type == "connectResponse") { |
| 339 EXPECT_FALSE(connect_response_received); | 342 EXPECT_FALSE(connect_response_received); |
| 340 connect_response_received = true; | 343 connect_response_received = true; |
| 341 VerifyId(std::move(response), request_id); | 344 VerifyId(std::move(response), request_id); |
| 342 } else if (type == "hostStateChanged") { | 345 } else if (type == "hostStateChanged") { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 378 } | 381 } |
| 379 } | 382 } |
| 380 } | 383 } |
| 381 | 384 |
| 382 void It2MeNativeMessagingHostTest::VerifyDisconnectResponses(int request_id) { | 385 void It2MeNativeMessagingHostTest::VerifyDisconnectResponses(int request_id) { |
| 383 bool disconnect_response_received = false; | 386 bool disconnect_response_received = false; |
| 384 bool disconnected_received = false; | 387 bool disconnected_received = false; |
| 385 | 388 |
| 386 // We expect a total of 3 messages: 1 connectResponse and 1 hostStateChanged. | 389 // We expect a total of 3 messages: 1 connectResponse and 1 hostStateChanged. |
| 387 for (int i = 0; i < 2; ++i) { | 390 for (int i = 0; i < 2; ++i) { |
| 388 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); | 391 std::unique_ptr<base::DictionaryValue> response = |
| 392 ReadMessageFromOutputPipe(); |
| 389 ASSERT_TRUE(response); | 393 ASSERT_TRUE(response); |
| 390 | 394 |
| 391 std::string type; | 395 std::string type; |
| 392 ASSERT_TRUE(response->GetString("type", &type)); | 396 ASSERT_TRUE(response->GetString("type", &type)); |
| 393 | 397 |
| 394 if (type == "disconnectResponse") { | 398 if (type == "disconnectResponse") { |
| 395 EXPECT_FALSE(disconnect_response_received); | 399 EXPECT_FALSE(disconnect_response_received); |
| 396 disconnect_response_received = true; | 400 disconnect_response_received = true; |
| 397 VerifyId(std::move(response), request_id); | 401 VerifyId(std::move(response), request_id); |
| 398 } else if (type == "hostStateChanged") { | 402 } else if (type == "hostStateChanged") { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 418 | 422 |
| 419 WriteMessageToInputPipe(good_message); | 423 WriteMessageToInputPipe(good_message); |
| 420 WriteMessageToInputPipe(message); | 424 WriteMessageToInputPipe(message); |
| 421 WriteMessageToInputPipe(good_message); | 425 WriteMessageToInputPipe(good_message); |
| 422 | 426 |
| 423 VerifyHelloResponse(1); | 427 VerifyHelloResponse(1); |
| 424 | 428 |
| 425 if (expect_error_response) | 429 if (expect_error_response) |
| 426 VerifyErrorResponse(); | 430 VerifyErrorResponse(); |
| 427 | 431 |
| 428 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); | 432 std::unique_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); |
| 429 EXPECT_FALSE(response); | 433 EXPECT_FALSE(response); |
| 430 } | 434 } |
| 431 | 435 |
| 432 void It2MeNativeMessagingHostTest::StartHost() { | 436 void It2MeNativeMessagingHostTest::StartHost() { |
| 433 DCHECK(host_task_runner_->RunsTasksOnCurrentThread()); | 437 DCHECK(host_task_runner_->RunsTasksOnCurrentThread()); |
| 434 | 438 |
| 435 base::File input_read_file; | 439 base::File input_read_file; |
| 436 base::File output_write_file; | 440 base::File output_write_file; |
| 437 | 441 |
| 438 ASSERT_TRUE(MakePipe(&input_read_file, &input_write_file_)); | 442 ASSERT_TRUE(MakePipe(&input_read_file, &input_write_file_)); |
| 439 ASSERT_TRUE(MakePipe(&output_read_file_, &output_write_file)); | 443 ASSERT_TRUE(MakePipe(&output_read_file_, &output_write_file)); |
| 440 | 444 |
| 441 pipe_.reset(new NativeMessagingPipe()); | 445 pipe_.reset(new NativeMessagingPipe()); |
| 442 | 446 |
| 443 scoped_ptr<extensions::NativeMessagingChannel> channel( | 447 std::unique_ptr<extensions::NativeMessagingChannel> channel( |
| 444 new PipeMessagingChannel(std::move(input_read_file), | 448 new PipeMessagingChannel(std::move(input_read_file), |
| 445 std::move(output_write_file))); | 449 std::move(output_write_file))); |
| 446 | 450 |
| 447 // Creating a native messaging host with a mock It2MeHostFactory. | 451 // Creating a native messaging host with a mock It2MeHostFactory. |
| 448 scoped_ptr<extensions::NativeMessageHost> it2me_host( | 452 std::unique_ptr<extensions::NativeMessageHost> it2me_host( |
| 449 new It2MeNativeMessagingHost( | 453 new It2MeNativeMessagingHost( |
| 450 ChromotingHostContext::Create(host_task_runner_), | 454 ChromotingHostContext::Create(host_task_runner_), |
| 451 make_scoped_ptr(new MockIt2MeHostFactory()))); | 455 base::WrapUnique(new MockIt2MeHostFactory()))); |
| 452 it2me_host->Start(pipe_.get()); | 456 it2me_host->Start(pipe_.get()); |
| 453 | 457 |
| 454 pipe_->Start(std::move(it2me_host), std::move(channel)); | 458 pipe_->Start(std::move(it2me_host), std::move(channel)); |
| 455 | 459 |
| 456 // Notify the test that the host has finished starting up. | 460 // Notify the test that the host has finished starting up. |
| 457 test_message_loop_->task_runner()->PostTask( | 461 test_message_loop_->task_runner()->PostTask( |
| 458 FROM_HERE, test_run_loop_->QuitClosure()); | 462 FROM_HERE, test_run_loop_->QuitClosure()); |
| 459 } | 463 } |
| 460 | 464 |
| 461 void It2MeNativeMessagingHostTest::ExitTest() { | 465 void It2MeNativeMessagingHostTest::ExitTest() { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 505 } | 509 } |
| 506 | 510 |
| 507 // Verify that response ID matches request ID. | 511 // Verify that response ID matches request ID. |
| 508 TEST_F(It2MeNativeMessagingHostTest, Id) { | 512 TEST_F(It2MeNativeMessagingHostTest, Id) { |
| 509 base::DictionaryValue message; | 513 base::DictionaryValue message; |
| 510 message.SetString("type", "hello"); | 514 message.SetString("type", "hello"); |
| 511 WriteMessageToInputPipe(message); | 515 WriteMessageToInputPipe(message); |
| 512 message.SetString("id", "42"); | 516 message.SetString("id", "42"); |
| 513 WriteMessageToInputPipe(message); | 517 WriteMessageToInputPipe(message); |
| 514 | 518 |
| 515 scoped_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); | 519 std::unique_ptr<base::DictionaryValue> response = ReadMessageFromOutputPipe(); |
| 516 EXPECT_TRUE(response); | 520 EXPECT_TRUE(response); |
| 517 std::string value; | 521 std::string value; |
| 518 EXPECT_FALSE(response->GetString("id", &value)); | 522 EXPECT_FALSE(response->GetString("id", &value)); |
| 519 | 523 |
| 520 response = ReadMessageFromOutputPipe(); | 524 response = ReadMessageFromOutputPipe(); |
| 521 EXPECT_TRUE(response); | 525 EXPECT_TRUE(response); |
| 522 EXPECT_TRUE(response->GetString("id", &value)); | 526 EXPECT_TRUE(response->GetString("id", &value)); |
| 523 EXPECT_EQ("42", value); | 527 EXPECT_EQ("42", value); |
| 524 } | 528 } |
| 525 | 529 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 545 } | 549 } |
| 546 | 550 |
| 547 // Verify rejection if type is unrecognized. | 551 // Verify rejection if type is unrecognized. |
| 548 TEST_F(It2MeNativeMessagingHostTest, InvalidType) { | 552 TEST_F(It2MeNativeMessagingHostTest, InvalidType) { |
| 549 base::DictionaryValue message; | 553 base::DictionaryValue message; |
| 550 message.SetString("type", "xxx"); | 554 message.SetString("type", "xxx"); |
| 551 TestBadRequest(message, true); | 555 TestBadRequest(message, true); |
| 552 } | 556 } |
| 553 | 557 |
| 554 } // namespace remoting | 558 } // namespace remoting |
| OLD | NEW |