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

Side by Side Diff: chrome/browser/extensions/api/messaging/native_message_process_host_unittest.cc

Issue 591463003: Remote Assistance on Chrome OS Part III - NativeMessageHost (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@native_messaging
Patch Set: Fix NativeMessagingBasic test on Release builds Created 6 years, 2 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "base/bind.h" 5 #include "base/bind.h"
6 #include "base/files/file.h" 6 #include "base/files/file.h"
7 #include "base/files/file_path.h" 7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h" 8 #include "base/files/file_util.h"
9 #include "base/files/scoped_file.h" 9 #include "base/files/scoped_file.h"
10 #include "base/files/scoped_temp_dir.h" 10 #include "base/files/scoped_temp_dir.h"
11 #include "base/json/json_reader.h" 11 #include "base/json/json_reader.h"
12 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
15 #include "base/rand_util.h" 14 #include "base/rand_util.h"
16 #include "base/run_loop.h" 15 #include "base/run_loop.h"
17 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
18 #include "base/test/test_timeouts.h" 17 #include "base/test/test_timeouts.h"
19 #include "base/threading/platform_thread.h" 18 #include "base/threading/platform_thread.h"
20 #include "base/threading/sequenced_worker_pool.h" 19 #include "base/threading/sequenced_worker_pool.h"
21 #include "base/time/time.h" 20 #include "base/time/time.h"
22 #include "chrome/browser/extensions/api/messaging/native_message_process_host.h" 21 #include "chrome/browser/extensions/api/messaging/native_message_process_host.h"
23 #include "chrome/browser/extensions/api/messaging/native_messaging_test_util.h" 22 #include "chrome/browser/extensions/api/messaging/native_messaging_test_util.h"
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 base::kNullProcessHandle, 85 base::kNullProcessHandle,
87 read_file_.Pass(), write_file_.Pass()); 86 read_file_.Pass(), write_file_.Pass());
88 } 87 }
89 88
90 private: 89 private:
91 mutable base::File read_file_; 90 mutable base::File read_file_;
92 mutable base::File write_file_; 91 mutable base::File write_file_;
93 }; 92 };
94 93
95 class NativeMessagingTest : public ::testing::Test, 94 class NativeMessagingTest : public ::testing::Test,
96 public NativeMessageProcessHost::Client, 95 public NativeMessageHost::Client,
97 public base::SupportsWeakPtr<NativeMessagingTest> { 96 public base::SupportsWeakPtr<NativeMessagingTest> {
98 protected: 97 protected:
99 NativeMessagingTest() 98 NativeMessagingTest()
100 : current_channel_(chrome::VersionInfo::CHANNEL_DEV), 99 : current_channel_(chrome::VersionInfo::CHANNEL_DEV),
101 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP), 100 thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
102 channel_closed_(false) {} 101 channel_closed_(false) {}
103 102
104 virtual void SetUp() override { 103 virtual void SetUp() override {
105 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 104 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
106 } 105 }
107 106
108 virtual void TearDown() override { 107 virtual void TearDown() override {
109 if (native_message_process_host_.get()) { 108 if (native_message_host_.get()) {
110 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, 109 BrowserThread::DeleteSoon(
111 native_message_process_host_.release()); 110 BrowserThread::IO, FROM_HERE, native_message_host_.release());
112 } 111 }
113 base::RunLoop().RunUntilIdle(); 112 base::RunLoop().RunUntilIdle();
114 } 113 }
115 114
116 virtual void PostMessageFromNativeProcess( 115 virtual void PostMessageFromNativeHost(const std::string& message) override {
117 int port_id,
118 const std::string& message) override {
119 last_message_ = message; 116 last_message_ = message;
120 117
121 // Parse the message. 118 // Parse the message.
122 base::Value* parsed = base::JSONReader::Read(message); 119 base::Value* parsed = base::JSONReader::Read(message);
123 base::DictionaryValue* dict_value; 120 base::DictionaryValue* dict_value;
124 if (parsed && parsed->GetAsDictionary(&dict_value)) { 121 if (parsed && parsed->GetAsDictionary(&dict_value)) {
125 last_message_parsed_.reset(dict_value); 122 last_message_parsed_.reset(dict_value);
126 } else { 123 } else {
127 LOG(ERROR) << "Failed to parse " << message; 124 LOG(ERROR) << "Failed to parse " << message;
128 last_message_parsed_.reset(); 125 last_message_parsed_.reset();
129 delete parsed; 126 delete parsed;
130 } 127 }
131 128
132 if (run_loop_) 129 if (run_loop_)
133 run_loop_->Quit(); 130 run_loop_->Quit();
134 } 131 }
135 132
136 virtual void CloseChannel(int port_id, 133 virtual void CloseChannel(const std::string& error_message) override {
137 const std::string& error_message) override {
138 channel_closed_ = true; 134 channel_closed_ = true;
139 if (run_loop_) 135 if (run_loop_)
140 run_loop_->Quit(); 136 run_loop_->Quit();
141 } 137 }
142 138
143 protected: 139 protected:
144 std::string FormatMessage(const std::string& message) { 140 std::string FormatMessage(const std::string& message) {
145 uint32_t length = message.length(); 141 uint32_t length = message.length();
146 return std::string(reinterpret_cast<char*>(&length), 4).append(message); 142 return std::string(reinterpret_cast<char*>(&length), 4).append(message);
147 } 143 }
148 144
149 base::FilePath CreateTempFileWithMessage(const std::string& message) { 145 base::FilePath CreateTempFileWithMessage(const std::string& message) {
150 base::FilePath filename; 146 base::FilePath filename;
151 if (!base::CreateTemporaryFileInDir(temp_dir_.path(), &filename)) 147 if (!base::CreateTemporaryFileInDir(temp_dir_.path(), &filename))
152 return base::FilePath(); 148 return base::FilePath();
153 149
154 std::string message_with_header = FormatMessage(message); 150 std::string message_with_header = FormatMessage(message);
155 int bytes_written = base::WriteFile( 151 int bytes_written = base::WriteFile(
156 filename, message_with_header.data(), message_with_header.size()); 152 filename, message_with_header.data(), message_with_header.size());
157 if (bytes_written < 0 || 153 if (bytes_written < 0 ||
158 (message_with_header.size() != static_cast<size_t>(bytes_written))) { 154 (message_with_header.size() != static_cast<size_t>(bytes_written))) {
159 return base::FilePath(); 155 return base::FilePath();
160 } 156 }
161 return filename; 157 return filename;
162 } 158 }
163 159
164 base::ScopedTempDir temp_dir_; 160 base::ScopedTempDir temp_dir_;
165 // Force the channel to be dev. 161 // Force the channel to be dev.
166 ScopedCurrentChannel current_channel_; 162 ScopedCurrentChannel current_channel_;
167 scoped_ptr<NativeMessageProcessHost> native_message_process_host_; 163 scoped_ptr<NativeMessageHost> native_message_host_;
168 scoped_ptr<base::RunLoop> run_loop_; 164 scoped_ptr<base::RunLoop> run_loop_;
169 content::TestBrowserThreadBundle thread_bundle_; 165 content::TestBrowserThreadBundle thread_bundle_;
170 std::string last_message_; 166 std::string last_message_;
171 scoped_ptr<base::DictionaryValue> last_message_parsed_; 167 scoped_ptr<base::DictionaryValue> last_message_parsed_;
172 bool channel_closed_; 168 bool channel_closed_;
173 }; 169 };
174 170
175 // Read a single message from a local file. 171 // Read a single message from a local file.
176 TEST_F(NativeMessagingTest, SingleSendMessageRead) { 172 TEST_F(NativeMessagingTest, SingleSendMessageRead) {
177 base::FilePath temp_output_file = temp_dir_.path().AppendASCII("output"); 173 base::FilePath temp_output_file = temp_dir_.path().AppendASCII("output");
178 base::FilePath temp_input_file = CreateTempFileWithMessage(kTestMessage); 174 base::FilePath temp_input_file = CreateTempFileWithMessage(kTestMessage);
179 ASSERT_FALSE(temp_input_file.empty()); 175 ASSERT_FALSE(temp_input_file.empty());
180 176
181 scoped_ptr<NativeProcessLauncher> launcher = 177 scoped_ptr<NativeProcessLauncher> launcher =
182 FakeLauncher::Create(temp_input_file, temp_output_file).Pass(); 178 FakeLauncher::Create(temp_input_file, temp_output_file).Pass();
183 native_message_process_host_ = NativeMessageProcessHost::CreateWithLauncher( 179 native_message_host_ = NativeMessageProcessHost::CreateWithLauncher(
184 AsWeakPtr(), ScopedTestNativeMessagingHost::kExtensionId, "empty_app.py", 180 ScopedTestNativeMessagingHost::kExtensionId,
185 0, launcher.Pass()); 181 "empty_app.py",
186 ASSERT_TRUE(native_message_process_host_.get()); 182 launcher.Pass());
183 native_message_host_->Start(this);
184 ASSERT_TRUE(native_message_host_.get());
187 run_loop_.reset(new base::RunLoop()); 185 run_loop_.reset(new base::RunLoop());
188 run_loop_->RunUntilIdle(); 186 run_loop_->RunUntilIdle();
189 187
190 if (last_message_.empty()) { 188 if (last_message_.empty()) {
191 run_loop_.reset(new base::RunLoop()); 189 run_loop_.reset(new base::RunLoop());
190 scoped_ptr<NativeMessageProcessHost> native_message_process_host_(
191 static_cast<NativeMessageProcessHost*>(native_message_host_.release()));
192 native_message_process_host_->ReadNowForTesting(); 192 native_message_process_host_->ReadNowForTesting();
193 run_loop_->Run(); 193 run_loop_->Run();
194 } 194 }
195 EXPECT_EQ(kTestMessage, last_message_); 195 EXPECT_EQ(kTestMessage, last_message_);
196 } 196 }
197 197
198 // Tests sending a single message. The message should get written to 198 // Tests sending a single message. The message should get written to
199 // |temp_file| and should match the contents of single_message_request.msg. 199 // |temp_file| and should match the contents of single_message_request.msg.
200 TEST_F(NativeMessagingTest, SingleSendMessageWrite) { 200 TEST_F(NativeMessagingTest, SingleSendMessageWrite) {
201 base::FilePath temp_output_file = temp_dir_.path().AppendASCII("output"); 201 base::FilePath temp_output_file = temp_dir_.path().AppendASCII("output");
(...skipping 17 matching lines...) Expand all
219 #else // defined(OS_WIN) 219 #else // defined(OS_WIN)
220 base::PlatformFile pipe_handles[2]; 220 base::PlatformFile pipe_handles[2];
221 ASSERT_EQ(0, pipe(pipe_handles)); 221 ASSERT_EQ(0, pipe(pipe_handles));
222 read_file = base::File(pipe_handles[0]); 222 read_file = base::File(pipe_handles[0]);
223 base::File write_file(pipe_handles[1]); 223 base::File write_file(pipe_handles[1]);
224 #endif // !defined(OS_WIN) 224 #endif // !defined(OS_WIN)
225 225
226 scoped_ptr<NativeProcessLauncher> launcher = 226 scoped_ptr<NativeProcessLauncher> launcher =
227 FakeLauncher::CreateWithPipeInput(read_file.Pass(), 227 FakeLauncher::CreateWithPipeInput(read_file.Pass(),
228 temp_output_file).Pass(); 228 temp_output_file).Pass();
229 native_message_process_host_ = NativeMessageProcessHost::CreateWithLauncher( 229 native_message_host_ = NativeMessageProcessHost::CreateWithLauncher(
230 AsWeakPtr(), ScopedTestNativeMessagingHost::kExtensionId, "empty_app.py", 230 ScopedTestNativeMessagingHost::kExtensionId,
231 0, launcher.Pass()); 231 "empty_app.py",
232 ASSERT_TRUE(native_message_process_host_.get()); 232 launcher.Pass());
233 native_message_host_->Start(this);
234 ASSERT_TRUE(native_message_host_.get());
233 base::RunLoop().RunUntilIdle(); 235 base::RunLoop().RunUntilIdle();
234 236
235 native_message_process_host_->Send(kTestMessage); 237 native_message_host_->OnMessage(kTestMessage);
236 base::RunLoop().RunUntilIdle(); 238 base::RunLoop().RunUntilIdle();
237 239
238 std::string output; 240 std::string output;
239 base::TimeTicks start_time = base::TimeTicks::Now(); 241 base::TimeTicks start_time = base::TimeTicks::Now();
240 while (base::TimeTicks::Now() - start_time < TestTimeouts::action_timeout()) { 242 while (base::TimeTicks::Now() - start_time < TestTimeouts::action_timeout()) {
241 ASSERT_TRUE(base::ReadFileToString(temp_output_file, &output)); 243 ASSERT_TRUE(base::ReadFileToString(temp_output_file, &output));
242 if (!output.empty()) 244 if (!output.empty())
243 break; 245 break;
244 base::PlatformThread::YieldCurrentThread(); 246 base::PlatformThread::YieldCurrentThread();
245 } 247 }
246 248
247 EXPECT_EQ(FormatMessage(kTestMessage), output); 249 EXPECT_EQ(FormatMessage(kTestMessage), output);
248 } 250 }
249 251
250 // Test send message with a real client. The client just echo's back the text 252 // Test send message with a real client. The client just echo's back the text
251 // it received. 253 // it received.
252 TEST_F(NativeMessagingTest, EchoConnect) { 254 TEST_F(NativeMessagingTest, EchoConnect) {
253 ScopedTestNativeMessagingHost test_host; 255 ScopedTestNativeMessagingHost test_host;
254 ASSERT_NO_FATAL_FAILURE(test_host.RegisterTestHost(false)); 256 ASSERT_NO_FATAL_FAILURE(test_host.RegisterTestHost(false));
257 std::string error_message;
258 native_message_host_ = NativeMessageProcessHost::Create(
259 NULL,
260 ScopedTestNativeMessagingHost::kExtensionId,
261 ScopedTestNativeMessagingHost::kHostName,
262 false,
263 &error_message);
264 native_message_host_->Start(this);
265 ASSERT_TRUE(native_message_host_.get());
255 266
256 native_message_process_host_ = NativeMessageProcessHost::Create( 267 native_message_host_->OnMessage("{\"text\": \"Hello.\"}");
257 NULL, AsWeakPtr(), ScopedTestNativeMessagingHost::kExtensionId,
258 ScopedTestNativeMessagingHost::kHostName, 0, false);
259 ASSERT_TRUE(native_message_process_host_.get());
260
261 native_message_process_host_->Send("{\"text\": \"Hello.\"}");
262 run_loop_.reset(new base::RunLoop()); 268 run_loop_.reset(new base::RunLoop());
263 run_loop_->Run(); 269 run_loop_->Run();
264 ASSERT_FALSE(last_message_.empty()); 270 ASSERT_FALSE(last_message_.empty());
265 ASSERT_TRUE(last_message_parsed_); 271 ASSERT_TRUE(last_message_parsed_);
266 272
267 std::string expected_url = std::string("chrome-extension://") + 273 std::string expected_url = std::string("chrome-extension://") +
268 ScopedTestNativeMessagingHost::kExtensionId + "/"; 274 ScopedTestNativeMessagingHost::kExtensionId + "/";
269 int id; 275 int id;
270 EXPECT_TRUE(last_message_parsed_->GetInteger("id", &id)); 276 EXPECT_TRUE(last_message_parsed_->GetInteger("id", &id));
271 EXPECT_EQ(1, id); 277 EXPECT_EQ(1, id);
272 std::string text; 278 std::string text;
273 EXPECT_TRUE(last_message_parsed_->GetString("echo.text", &text)); 279 EXPECT_TRUE(last_message_parsed_->GetString("echo.text", &text));
274 EXPECT_EQ("Hello.", text); 280 EXPECT_EQ("Hello.", text);
275 std::string url; 281 std::string url;
276 EXPECT_TRUE(last_message_parsed_->GetString("caller_url", &url)); 282 EXPECT_TRUE(last_message_parsed_->GetString("caller_url", &url));
277 EXPECT_EQ(expected_url, url); 283 EXPECT_EQ(expected_url, url);
278 284
279 native_message_process_host_->Send("{\"foo\": \"bar\"}"); 285 native_message_host_->OnMessage("{\"foo\": \"bar\"}");
280 run_loop_.reset(new base::RunLoop()); 286 run_loop_.reset(new base::RunLoop());
281 run_loop_->Run(); 287 run_loop_->Run();
282 EXPECT_TRUE(last_message_parsed_->GetInteger("id", &id)); 288 EXPECT_TRUE(last_message_parsed_->GetInteger("id", &id));
283 EXPECT_EQ(2, id); 289 EXPECT_EQ(2, id);
284 EXPECT_TRUE(last_message_parsed_->GetString("echo.foo", &text)); 290 EXPECT_TRUE(last_message_parsed_->GetString("echo.foo", &text));
285 EXPECT_EQ("bar", text); 291 EXPECT_EQ("bar", text);
286 EXPECT_TRUE(last_message_parsed_->GetString("caller_url", &url)); 292 EXPECT_TRUE(last_message_parsed_->GetString("caller_url", &url));
287 EXPECT_EQ(expected_url, url); 293 EXPECT_EQ(expected_url, url);
288 } 294 }
289 295
290 TEST_F(NativeMessagingTest, UserLevel) { 296 TEST_F(NativeMessagingTest, UserLevel) {
291 ScopedTestNativeMessagingHost test_host; 297 ScopedTestNativeMessagingHost test_host;
292 ASSERT_NO_FATAL_FAILURE(test_host.RegisterTestHost(true)); 298 ASSERT_NO_FATAL_FAILURE(test_host.RegisterTestHost(true));
293 299
294 native_message_process_host_ = NativeMessageProcessHost::Create( 300 std::string error_message;
295 NULL, AsWeakPtr(), ScopedTestNativeMessagingHost::kExtensionId, 301 native_message_host_ = NativeMessageProcessHost::Create(
296 ScopedTestNativeMessagingHost::kHostName, 0, true); 302 NULL,
297 ASSERT_TRUE(native_message_process_host_.get()); 303 ScopedTestNativeMessagingHost::kExtensionId,
304 ScopedTestNativeMessagingHost::kHostName,
305 true,
306 &error_message);
307 native_message_host_->Start(this);
308 ASSERT_TRUE(native_message_host_.get());
298 309
299 native_message_process_host_->Send("{\"text\": \"Hello.\"}"); 310 native_message_host_->OnMessage("{\"text\": \"Hello.\"}");
300 run_loop_.reset(new base::RunLoop()); 311 run_loop_.reset(new base::RunLoop());
301 run_loop_->Run(); 312 run_loop_->Run();
302 ASSERT_FALSE(last_message_.empty()); 313 ASSERT_FALSE(last_message_.empty());
303 ASSERT_TRUE(last_message_parsed_); 314 ASSERT_TRUE(last_message_parsed_);
304 } 315 }
305 316
306 TEST_F(NativeMessagingTest, DisallowUserLevel) { 317 TEST_F(NativeMessagingTest, DisallowUserLevel) {
307 ScopedTestNativeMessagingHost test_host; 318 ScopedTestNativeMessagingHost test_host;
308 ASSERT_NO_FATAL_FAILURE(test_host.RegisterTestHost(true)); 319 ASSERT_NO_FATAL_FAILURE(test_host.RegisterTestHost(true));
309 320
310 native_message_process_host_ = NativeMessageProcessHost::Create( 321 std::string error_message;
311 NULL, AsWeakPtr(), ScopedTestNativeMessagingHost::kExtensionId, 322 native_message_host_ = NativeMessageProcessHost::Create(
312 ScopedTestNativeMessagingHost::kHostName, 0, false); 323 NULL,
313 ASSERT_TRUE(native_message_process_host_.get()); 324 ScopedTestNativeMessagingHost::kExtensionId,
325 ScopedTestNativeMessagingHost::kHostName,
326 false,
327 &error_message);
328 native_message_host_->Start(this);
329 ASSERT_TRUE(native_message_host_.get());
314 run_loop_.reset(new base::RunLoop()); 330 run_loop_.reset(new base::RunLoop());
315 run_loop_->Run(); 331 run_loop_->Run();
316 332
317 // The host should fail to start. 333 // The host should fail to start.
318 ASSERT_TRUE(channel_closed_); 334 ASSERT_TRUE(channel_closed_);
319 } 335 }
320 336
321 } // namespace extensions 337 } // namespace extensions
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/messaging/native_message_process_host.cc ('k') | chrome/browser/policy/policy_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698