1 // Copyright 2010-2018, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 #include "client/client.h"
31
32 #include <map>
33 #include <memory>
34 #include <string>
35
36 #include "base/logging.h"
37 #include "base/number_util.h"
38 #include "base/port.h"
39 #include "base/util.h"
40 #include "base/version.h"
41 #include "ipc/ipc_mock.h"
42 #include "protocol/commands.pb.h"
43 #include "testing/base/public/gunit.h"
44
45 namespace mozc {
46 namespace client {
47
48 namespace {
49 const char kPrecedingText[] = "preceding_text";
50 const char kFollowingText[] = "following_text";
51 const bool kSuppressSuggestion = true;
52
UpdateVersion(int diff)53 const string UpdateVersion(int diff) {
54 std::vector<string> tokens;
55 Util::SplitStringUsing(Version::GetMozcVersion(), ".", &tokens);
56 EXPECT_EQ(tokens.size(), 4);
57 char buf[64];
58 snprintf(buf, sizeof(buf), "%d", NumberUtil::SimpleAtoi(tokens[3]) + diff);
59 tokens[3] = buf;
60 string output;
61 Util::JoinStrings(tokens, ".", &output);
62 return output;
63 }
64 } // namespace
65
66 class TestServerLauncher : public ServerLauncherInterface {
67 public:
TestServerLauncher(IPCClientFactoryMock * factory)68 explicit TestServerLauncher(IPCClientFactoryMock *factory)
69 : factory_(factory),
70 start_server_result_(false),
71 start_server_called_(false),
72 force_terminate_server_result_(false),
73 force_terminate_server_called_(false),
74 server_protocol_version_(IPC_PROTOCOL_VERSION) {}
75
Ready()76 virtual void Ready() {}
Wait()77 virtual void Wait() {}
Error()78 virtual void Error() {}
79
StartServer(ClientInterface * client)80 virtual bool StartServer(ClientInterface *client) {
81 if (!response_.empty()) {
82 factory_->SetMockResponse(response_);
83 }
84 if (!product_version_after_start_server_.empty()) {
85 factory_->SetServerProductVersion(product_version_after_start_server_);
86 }
87 factory_->SetServerProtocolVersion(server_protocol_version_);
88 start_server_called_ = true;
89 return start_server_result_;
90 }
91
ForceTerminateServer(const string & name)92 virtual bool ForceTerminateServer(const string &name) {
93 force_terminate_server_called_ = true;
94 return force_terminate_server_result_;
95 }
96
WaitServer(uint32 pid)97 virtual bool WaitServer(uint32 pid) {
98 return true;
99 }
100
OnFatal(ServerLauncherInterface::ServerErrorType type)101 virtual void OnFatal(ServerLauncherInterface::ServerErrorType type) {
102 LOG(ERROR) << static_cast<int>(type);
103 error_map_[static_cast<int>(type)]++;
104 }
105
error_count(ServerLauncherInterface::ServerErrorType type)106 int error_count(ServerLauncherInterface::ServerErrorType type) {
107 return error_map_[static_cast<int>(type)];
108 }
109
start_server_called() const110 bool start_server_called() const {
111 return start_server_called_;
112 }
113
set_start_server_called(bool start_server_called)114 void set_start_server_called(bool start_server_called) {
115 start_server_called_ = start_server_called;
116 }
117
force_terminate_server_called() const118 bool force_terminate_server_called() const {
119 return force_terminate_server_called_;
120 }
121
set_force_terminate_server_called(bool force_terminate_server_called)122 void set_force_terminate_server_called(bool force_terminate_server_called) {
123 force_terminate_server_called_ = force_terminate_server_called;
124 }
125
set_server_program(const string & server_path)126 void set_server_program(const string &server_path) {
127 }
128
server_program() const129 virtual const string &server_program() const {
130 static const string path;
131 return path;
132 }
133
set_restricted(bool restricted)134 void set_restricted(bool restricted) {}
135
set_suppress_error_dialog(bool suppress)136 void set_suppress_error_dialog(bool suppress) {}
137
set_start_server_result(const bool result)138 void set_start_server_result(const bool result) {
139 start_server_result_ = result;
140 }
141
set_force_terminate_server_result(const bool result)142 void set_force_terminate_server_result(const bool result) {
143 force_terminate_server_result_ = result;
144 }
145
set_server_protocol_version(uint32 server_protocol_version)146 void set_server_protocol_version(uint32 server_protocol_version) {
147 server_protocol_version_ = server_protocol_version;
148 }
149
set_mock_after_start_server(const commands::Output & mock_output)150 void set_mock_after_start_server(const commands::Output &mock_output) {
151 mock_output.SerializeToString(&response_);
152 }
153
set_product_version_after_start_server(const string & version)154 void set_product_version_after_start_server(const string &version) {
155 product_version_after_start_server_ = version;
156 }
157
158 private:
159 IPCClientFactoryMock *factory_;
160 bool start_server_result_;
161 bool start_server_called_;
162 bool force_terminate_server_result_;
163 bool force_terminate_server_called_;
164 uint32 server_protocol_version_;
165 string response_;
166 string product_version_after_start_server_;
167 std::map<int, int> error_map_;
168 };
169
170 class ClientTest : public testing::Test {
171 protected:
ClientTest()172 ClientTest() : version_diff_(0) {}
173
SetUp()174 virtual void SetUp() {
175 client_factory_.reset(new IPCClientFactoryMock);
176 client_.reset(new Client);
177 client_->SetIPCClientFactory(client_factory_.get());
178
179 server_launcher_ = new TestServerLauncher(client_factory_.get());
180 client_->SetServerLauncher(server_launcher_);
181 }
182
TearDown()183 virtual void TearDown() {
184 client_.reset();
185 client_factory_.reset();
186 }
187
SetMockOutput(const commands::Output & mock_output)188 void SetMockOutput(const commands::Output &mock_output) {
189 string response;
190 mock_output.SerializeToString(&response);
191 client_factory_->SetMockResponse(response);
192 }
193
GetGeneratedInput(commands::Input * input)194 void GetGeneratedInput(commands::Input *input) {
195 input->ParseFromString(client_factory_->GetGeneratedRequest());
196 if (input->type() != commands::Input::CREATE_SESSION) {
197 ASSERT_TRUE(input->has_id());
198 }
199 }
200
SetupProductVersion(int version_diff)201 void SetupProductVersion(int version_diff) {
202 version_diff_ = version_diff;
203 }
204
SetupConnection(const int id)205 bool SetupConnection(const int id) {
206 client_factory_->SetConnection(true);
207 client_factory_->SetResult(true);
208 if (version_diff_ == 0) {
209 client_factory_->SetServerProductVersion(Version::GetMozcVersion());
210 } else {
211 client_factory_->SetServerProductVersion(UpdateVersion(version_diff_));
212 }
213 server_launcher_->set_start_server_result(true);
214
215 // TODO(komatsu): Due to the limitation of the testing mock,
216 // EnsureConnection should be explicitly called before calling
217 // SendKey. Fix the testing mock.
218 commands::Output mock_output;
219 mock_output.set_id(id);
220 SetMockOutput(mock_output);
221 return client_->EnsureConnection();
222 }
223
224 std::unique_ptr<IPCClientFactoryMock> client_factory_;
225 std::unique_ptr<Client> client_;
226 TestServerLauncher *server_launcher_;
227 int version_diff_;
228
229 private:
230 DISALLOW_COPY_AND_ASSIGN(ClientTest);
231 };
232
TEST_F(ClientTest,ConnectionError)233 TEST_F(ClientTest, ConnectionError) {
234 client_factory_->SetConnection(false);
235 server_launcher_->set_start_server_result(false);
236 EXPECT_FALSE(client_->EnsureConnection());
237
238 commands::KeyEvent key;
239 commands::Output output;
240 EXPECT_FALSE(client_->SendKey(key, &output));
241
242 key.Clear();
243 output.Clear();
244 EXPECT_FALSE(client_->TestSendKey(key, &output));
245
246 commands::SessionCommand command;
247 output.Clear();
248 EXPECT_FALSE(client_->SendCommand(command, &output));
249 }
250
TEST_F(ClientTest,SendKey)251 TEST_F(ClientTest, SendKey) {
252 const int mock_id = 123;
253 EXPECT_TRUE(SetupConnection(mock_id));
254
255 commands::KeyEvent key_event;
256 key_event.set_special_key(commands::KeyEvent::ENTER);
257
258 commands::Output mock_output;
259 mock_output.set_id(mock_id);
260 mock_output.set_consumed(true);
261 SetMockOutput(mock_output);
262
263 commands::Output output;
264 EXPECT_TRUE(client_->SendKey(key_event, &output));
265 EXPECT_EQ(mock_output.consumed(), output.consumed());
266
267 commands::Input input;
268 GetGeneratedInput(&input);
269 EXPECT_EQ(mock_id, input.id());
270 EXPECT_EQ(commands::Input::SEND_KEY, input.type());
271 }
272
TEST_F(ClientTest,SendKeyWithContext)273 TEST_F(ClientTest, SendKeyWithContext) {
274 const int mock_id = 123;
275 EXPECT_TRUE(SetupConnection(mock_id));
276
277 commands::KeyEvent key_event;
278 key_event.set_special_key(commands::KeyEvent::ENTER);
279
280 commands::Context context;
281 context.set_preceding_text(kPrecedingText);
282 context.set_following_text(kFollowingText);
283 context.set_suppress_suggestion(kSuppressSuggestion);
284
285 commands::Output mock_output;
286 mock_output.set_id(mock_id);
287 mock_output.set_consumed(true);
288 SetMockOutput(mock_output);
289
290 commands::Output output;
291 EXPECT_TRUE(client_->SendKeyWithContext(key_event, context, &output));
292 EXPECT_EQ(mock_output.consumed(), output.consumed());
293
294 commands::Input input;
295 GetGeneratedInput(&input);
296 EXPECT_EQ(mock_id, input.id());
297 EXPECT_EQ(commands::Input::SEND_KEY, input.type());
298 EXPECT_EQ(kPrecedingText, input.context().preceding_text());
299 EXPECT_EQ(kFollowingText, input.context().following_text());
300 EXPECT_EQ(kSuppressSuggestion, input.context().suppress_suggestion());
301 }
302
TEST_F(ClientTest,TestSendKey)303 TEST_F(ClientTest, TestSendKey) {
304 const int mock_id = 512;
305 EXPECT_TRUE(SetupConnection(mock_id));
306
307 commands::KeyEvent key_event;
308 key_event.set_special_key(commands::KeyEvent::ENTER);
309
310 commands::Output mock_output;
311 mock_output.Clear();
312 mock_output.set_id(mock_id);
313 mock_output.set_consumed(true);
314 SetMockOutput(mock_output);
315
316 commands::Output output;
317 EXPECT_TRUE(client_->TestSendKey(key_event, &output));
318 EXPECT_EQ(mock_output.consumed(), output.consumed());
319
320 commands::Input input;
321 GetGeneratedInput(&input);
322 EXPECT_EQ(mock_id, input.id());
323 EXPECT_EQ(commands::Input::TEST_SEND_KEY, input.type());
324 }
325
326
TEST_F(ClientTest,TestSendKeyWithContext)327 TEST_F(ClientTest, TestSendKeyWithContext) {
328 const int mock_id = 512;
329 EXPECT_TRUE(SetupConnection(mock_id));
330
331 commands::KeyEvent key_event;
332 key_event.set_special_key(commands::KeyEvent::ENTER);
333
334 commands::Context context;
335 context.set_preceding_text(kPrecedingText);
336 context.set_following_text(kFollowingText);
337 context.set_suppress_suggestion(kSuppressSuggestion);
338
339 commands::Output mock_output;
340 mock_output.Clear();
341 mock_output.set_id(mock_id);
342 mock_output.set_consumed(true);
343 SetMockOutput(mock_output);
344
345 commands::Output output;
346 EXPECT_TRUE(client_->TestSendKeyWithContext(key_event, context, &output));
347 EXPECT_EQ(mock_output.consumed(), output.consumed());
348
349 commands::Input input;
350 GetGeneratedInput(&input);
351 EXPECT_EQ(mock_id, input.id());
352 EXPECT_EQ(commands::Input::TEST_SEND_KEY, input.type());
353 EXPECT_EQ(kPrecedingText, input.context().preceding_text());
354 EXPECT_EQ(kFollowingText, input.context().following_text());
355 EXPECT_EQ(kSuppressSuggestion, input.context().suppress_suggestion());
356 }
357
TEST_F(ClientTest,SendCommand)358 TEST_F(ClientTest, SendCommand) {
359 const int mock_id = 123;
360 EXPECT_TRUE(SetupConnection(mock_id));
361
362 commands::SessionCommand session_command;
363 session_command.set_type(commands::SessionCommand::SUBMIT);
364
365 commands::Output mock_output;
366 mock_output.Clear();
367 mock_output.set_id(mock_id);
368 SetMockOutput(mock_output);
369
370 commands::Output output;
371 EXPECT_TRUE(client_->SendCommand(session_command, &output));
372
373 commands::Input input;
374 GetGeneratedInput(&input);
375 EXPECT_EQ(mock_id, input.id());
376 EXPECT_EQ(commands::Input::SEND_COMMAND, input.type());
377 }
378
TEST_F(ClientTest,SendCommandWithContext)379 TEST_F(ClientTest, SendCommandWithContext) {
380 const int mock_id = 123;
381 EXPECT_TRUE(SetupConnection(mock_id));
382
383 commands::SessionCommand session_command;
384 session_command.set_type(commands::SessionCommand::SUBMIT);
385
386 commands::Context context;
387 context.set_preceding_text(kPrecedingText);
388 context.set_following_text(kFollowingText);
389 context.set_suppress_suggestion(kSuppressSuggestion);
390
391 commands::Output mock_output;
392 mock_output.Clear();
393 mock_output.set_id(mock_id);
394 SetMockOutput(mock_output);
395
396 commands::Output output;
397 EXPECT_TRUE(client_->SendCommandWithContext(session_command,
398 context,
399 &output));
400
401 commands::Input input;
402 GetGeneratedInput(&input);
403 EXPECT_EQ(mock_id, input.id());
404 EXPECT_EQ(commands::Input::SEND_COMMAND, input.type());
405 EXPECT_EQ(kPrecedingText, input.context().preceding_text());
406 EXPECT_EQ(kFollowingText, input.context().following_text());
407 EXPECT_EQ(kSuppressSuggestion, input.context().suppress_suggestion());
408 }
409
TEST_F(ClientTest,SetConfig)410 TEST_F(ClientTest, SetConfig) {
411 const int mock_id = 0;
412 EXPECT_TRUE(SetupConnection(mock_id));
413
414 config::Config config;
415 EXPECT_TRUE(client_->SetConfig(config));
416 }
417
TEST_F(ClientTest,GetConfig)418 TEST_F(ClientTest, GetConfig) {
419 const int mock_id = 0;
420 EXPECT_TRUE(SetupConnection(mock_id));
421
422 commands::Output mock_output;
423 mock_output.set_id(mock_id);
424 mock_output.mutable_config()->set_verbose_level(2);
425 mock_output.mutable_config()->set_incognito_mode(true);
426 SetMockOutput(mock_output);
427
428 config::Config config;
429 EXPECT_TRUE(client_->GetConfig(&config));
430
431 EXPECT_EQ(2, config.verbose_level());
432 EXPECT_EQ(true, config.incognito_mode());
433 }
434
TEST_F(ClientTest,EnableCascadingWindow)435 TEST_F(ClientTest, EnableCascadingWindow) {
436 const int mock_id = 0;
437 EXPECT_TRUE(SetupConnection(mock_id));
438
439 commands::Output mock_output;
440 mock_output.set_id(mock_id);
441 SetMockOutput(mock_output);
442 EXPECT_TRUE(client_->EnsureConnection());
443
444 client_->NoOperation();
445 commands::Input input;
446 GetGeneratedInput(&input);
447 EXPECT_FALSE(input.has_config());
448
449 client_->EnableCascadingWindow(false);
450 client_->NoOperation();
451 GetGeneratedInput(&input);
452 ASSERT_TRUE(input.has_config());
453 ASSERT_TRUE(input.config().has_use_cascading_window());
454 EXPECT_FALSE(input.config().use_cascading_window());
455
456 client_->EnableCascadingWindow(true);
457 client_->NoOperation();
458 GetGeneratedInput(&input);
459 ASSERT_TRUE(input.has_config());
460 ASSERT_TRUE(input.config().has_use_cascading_window());
461 EXPECT_TRUE(input.config().use_cascading_window());
462
463 client_->NoOperation();
464 GetGeneratedInput(&input);
465 ASSERT_TRUE(input.has_config());
466 EXPECT_TRUE(input.config().has_use_cascading_window());
467 }
468
TEST_F(ClientTest,VersionMismatch)469 TEST_F(ClientTest, VersionMismatch) {
470 const int mock_id = 123;
471 EXPECT_TRUE(SetupConnection(mock_id));
472
473 commands::KeyEvent key_event;
474 key_event.set_special_key(commands::KeyEvent::ENTER);
475
476 commands::Output mock_output;
477 mock_output.set_id(mock_id);
478 mock_output.set_consumed(true);
479 SetMockOutput(mock_output);
480
481 // Suddenly, connects to a different server
482 client_factory_->SetServerProtocolVersion(IPC_PROTOCOL_VERSION + 1);
483 commands::Output output;
484 EXPECT_FALSE(client_->SendKey(key_event, &output));
485 EXPECT_FALSE(client_->EnsureConnection());
486 EXPECT_EQ(1, server_launcher_->error_count
487 (ServerLauncherInterface::SERVER_VERSION_MISMATCH));
488 }
489
TEST_F(ClientTest,ProtocolUpdate)490 TEST_F(ClientTest, ProtocolUpdate) {
491 server_launcher_->set_start_server_result(true);
492
493 const int mock_id = 0;
494 EXPECT_TRUE(SetupConnection(mock_id));
495
496 commands::Output mock_output;
497 mock_output.set_id(mock_id);
498 SetMockOutput(mock_output);
499 EXPECT_TRUE(client_->EnsureConnection());
500
501 server_launcher_->set_force_terminate_server_called(false);
502 server_launcher_->set_force_terminate_server_result(true);
503 server_launcher_->set_start_server_called(false);
504
505 // Now connecting to an old server
506 client_factory_->SetServerProtocolVersion(IPC_PROTOCOL_VERSION - 1);
507 // after start server, protocol version becomes the same
508 server_launcher_->set_server_protocol_version(IPC_PROTOCOL_VERSION);
509
510 EXPECT_TRUE(client_->EnsureSession());
511 EXPECT_TRUE(server_launcher_->start_server_called());
512 EXPECT_TRUE(server_launcher_->force_terminate_server_called());
513 }
514
TEST_F(ClientTest,ProtocolUpdateFailSameBinary)515 TEST_F(ClientTest, ProtocolUpdateFailSameBinary) {
516 server_launcher_->set_start_server_result(true);
517
518 const int mock_id = 0;
519 EXPECT_TRUE(SetupConnection(mock_id));
520
521 commands::Output mock_output;
522 mock_output.set_id(mock_id);
523 SetMockOutput(mock_output);
524 EXPECT_TRUE(client_->EnsureConnection());
525
526 server_launcher_->set_force_terminate_server_called(false);
527 server_launcher_->set_force_terminate_server_result(true);
528 server_launcher_->set_start_server_called(false);
529
530 EXPECT_FALSE(server_launcher_->start_server_called());
531
532 // version is updated after restart the server
533 client_factory_->SetServerProtocolVersion(IPC_PROTOCOL_VERSION - 1);
534 // even after server reboot, protocol version is old
535 server_launcher_->set_server_protocol_version(IPC_PROTOCOL_VERSION - 1);
536 server_launcher_->set_mock_after_start_server(mock_output);
537 EXPECT_FALSE(client_->EnsureSession());
538 EXPECT_TRUE(server_launcher_->start_server_called());
539 EXPECT_TRUE(server_launcher_->force_terminate_server_called());
540 EXPECT_FALSE(client_->EnsureConnection());
541 EXPECT_EQ(1, server_launcher_->error_count
542 (ServerLauncherInterface::SERVER_BROKEN_MESSAGE));
543 }
544
TEST_F(ClientTest,ProtocolUpdateFailOnTerminate)545 TEST_F(ClientTest, ProtocolUpdateFailOnTerminate) {
546 server_launcher_->set_start_server_result(true);
547
548 const int mock_id = 0;
549 EXPECT_TRUE(SetupConnection(mock_id));
550
551 commands::Output mock_output;
552 mock_output.set_id(mock_id);
553 SetMockOutput(mock_output);
554 EXPECT_TRUE(client_->EnsureConnection());
555
556 server_launcher_->set_force_terminate_server_called(false);
557 server_launcher_->set_force_terminate_server_result(false);
558 server_launcher_->set_start_server_called(false);
559
560 EXPECT_FALSE(server_launcher_->start_server_called());
561
562 // version is updated after restart the server
563 client_factory_->SetServerProtocolVersion(IPC_PROTOCOL_VERSION - 1);
564 // even after server reboot, protocol version is old
565 server_launcher_->set_server_protocol_version(IPC_PROTOCOL_VERSION);
566 server_launcher_->set_mock_after_start_server(mock_output);
567 EXPECT_FALSE(client_->EnsureSession());
568 EXPECT_FALSE(server_launcher_->start_server_called());
569 EXPECT_TRUE(server_launcher_->force_terminate_server_called());
570 EXPECT_FALSE(client_->EnsureConnection());
571 EXPECT_EQ(1, server_launcher_->error_count
572 (ServerLauncherInterface::SERVER_BROKEN_MESSAGE));
573 }
574
TEST_F(ClientTest,ServerUpdate)575 TEST_F(ClientTest, ServerUpdate) {
576 SetupProductVersion(-1); // old version
577 server_launcher_->set_start_server_result(true);
578
579 const int mock_id = 0;
580 EXPECT_TRUE(SetupConnection(mock_id));
581
582 LOG(ERROR) << Version::GetMozcVersion();
583
584 commands::Output mock_output;
585 mock_output.set_id(mock_id);
586 SetMockOutput(mock_output);
587 EXPECT_TRUE(client_->EnsureConnection());
588
589 server_launcher_->set_start_server_called(false);
590 EXPECT_FALSE(server_launcher_->start_server_called());
591
592 // version is updated after restart the server
593 server_launcher_->set_product_version_after_start_server(
594 Version::GetMozcVersion());
595 EXPECT_TRUE(client_->EnsureSession());
596 EXPECT_TRUE(server_launcher_->start_server_called());
597 }
598
TEST_F(ClientTest,ServerUpdateToNewer)599 TEST_F(ClientTest, ServerUpdateToNewer) {
600 SetupProductVersion(1); // new version
601 server_launcher_->set_start_server_result(true);
602
603 const int mock_id = 0;
604 EXPECT_TRUE(SetupConnection(mock_id));
605
606 LOG(ERROR) << Version::GetMozcVersion();
607
608 commands::Output mock_output;
609 mock_output.set_id(mock_id);
610 SetMockOutput(mock_output);
611 EXPECT_TRUE(client_->EnsureConnection());
612 server_launcher_->set_start_server_called(false);
613 EXPECT_TRUE(client_->EnsureSession());
614 EXPECT_FALSE(server_launcher_->start_server_called());
615 }
616
TEST_F(ClientTest,ServerUpdateFail)617 TEST_F(ClientTest, ServerUpdateFail) {
618 SetupProductVersion(-1); // old
619 server_launcher_->set_start_server_result(true);
620
621 const int mock_id = 0;
622 EXPECT_TRUE(SetupConnection(mock_id));
623
624 commands::Output mock_output;
625 mock_output.set_id(mock_id);
626 SetMockOutput(mock_output);
627 EXPECT_TRUE(client_->EnsureConnection());
628
629 server_launcher_->set_start_server_called(false);
630 EXPECT_FALSE(server_launcher_->start_server_called());
631
632 // version is not updated after restart the server
633 server_launcher_->set_mock_after_start_server(mock_output);
634 EXPECT_FALSE(client_->EnsureSession());
635 EXPECT_TRUE(server_launcher_->start_server_called());
636 EXPECT_FALSE(client_->EnsureConnection());
637 EXPECT_EQ(1, server_launcher_->error_count
638 (ServerLauncherInterface::SERVER_BROKEN_MESSAGE));
639 }
640
TEST_F(ClientTest,TranslateProtoBufToMozcToolArgTest)641 TEST_F(ClientTest, TranslateProtoBufToMozcToolArgTest) {
642 commands::Output output;
643 string mode = "";
644
645 // If no value is set, we expect to return false
646 EXPECT_FALSE(client::Client::TranslateProtoBufToMozcToolArg(output, &mode));
647 EXPECT_EQ("", mode);
648
649 // If NO_TOOL is set, we expect to return false
650 output.set_launch_tool_mode(commands::Output::NO_TOOL);
651 EXPECT_FALSE(client::Client::TranslateProtoBufToMozcToolArg(output, &mode));
652 EXPECT_EQ("", mode);
653
654 output.set_launch_tool_mode(commands::Output::CONFIG_DIALOG);
655 EXPECT_TRUE(client::Client::TranslateProtoBufToMozcToolArg(output, &mode));
656 EXPECT_EQ("config_dialog", mode);
657
658 output.set_launch_tool_mode(commands::Output::DICTIONARY_TOOL);
659 EXPECT_TRUE(client::Client::TranslateProtoBufToMozcToolArg(output, &mode));
660 EXPECT_EQ("dictionary_tool", mode);
661
662 output.set_launch_tool_mode(commands::Output::WORD_REGISTER_DIALOG);
663 EXPECT_TRUE(client::Client::TranslateProtoBufToMozcToolArg(output, &mode));
664 EXPECT_EQ("word_register_dialog", mode);
665 }
666
667 class SessionPlaybackTestServerLauncher : public ServerLauncherInterface {
668 public:
SessionPlaybackTestServerLauncher(IPCClientFactoryMock * factory)669 explicit SessionPlaybackTestServerLauncher(IPCClientFactoryMock *factory)
670 : factory_(factory),
671 start_server_result_(false),
672 start_server_called_(false),
673 force_terminate_server_result_(false),
674 force_terminate_server_called_(false),
675 server_protocol_version_(IPC_PROTOCOL_VERSION) {}
676
Ready()677 virtual void Ready() {}
Wait()678 virtual void Wait() {}
Error()679 virtual void Error() {}
680
StartServer(ClientInterface * client)681 virtual bool StartServer(ClientInterface *client) {
682 if (!response_.empty()) {
683 factory_->SetMockResponse(response_);
684 }
685 if (!product_version_after_start_server_.empty()) {
686 factory_->SetServerProductVersion(product_version_after_start_server_);
687 }
688 factory_->SetServerProtocolVersion(server_protocol_version_);
689 start_server_called_ = true;
690 return start_server_result_;
691 }
692
ForceTerminateServer(const string & name)693 virtual bool ForceTerminateServer(const string &name) {
694 force_terminate_server_called_ = true;
695 return force_terminate_server_result_;
696 }
697
WaitServer(uint32 pid)698 virtual bool WaitServer(uint32 pid) {
699 return true;
700 }
701
OnFatal(ServerLauncherInterface::ServerErrorType type)702 virtual void OnFatal(ServerLauncherInterface::ServerErrorType type) {
703 }
704
set_server_program(const string & server_path)705 void set_server_program(const string &server_path) {}
706
set_restricted(bool restricted)707 void set_restricted(bool restricted) {}
708
set_suppress_error_dialog(bool suppress)709 void set_suppress_error_dialog(bool suppress) {}
710
set_start_server_result(const bool result)711 void set_start_server_result(const bool result) {
712 start_server_result_ = result;
713 }
714
715
server_program() const716 virtual const string &server_program() const {
717 static const string path;
718 return path;
719 }
720
721 private:
722 IPCClientFactoryMock *factory_;
723 bool start_server_result_;
724 bool start_server_called_;
725 bool force_terminate_server_result_;
726 bool force_terminate_server_called_;
727 uint32 server_protocol_version_;
728 string response_;
729 string product_version_after_start_server_;
730 std::map<int, int> error_map_;
731 };
732
733 class SessionPlaybackTest : public testing::Test {
734 protected:
SessionPlaybackTest()735 SessionPlaybackTest() {}
~SessionPlaybackTest()736 virtual ~SessionPlaybackTest() {}
737
SetUp()738 virtual void SetUp() {
739 ipc_client_factory_.reset(new IPCClientFactoryMock);
740 ipc_client_.reset(reinterpret_cast<IPCClientMock *>(
741 ipc_client_factory_->NewClient("")));
742 client_.reset(new Client);
743 client_->SetIPCClientFactory(ipc_client_factory_.get());
744 server_launcher_ = new SessionPlaybackTestServerLauncher(
745 ipc_client_factory_.get());
746 client_->SetServerLauncher(server_launcher_);
747 }
748
TearDown()749 virtual void TearDown() {
750 client_.reset();
751 ipc_client_factory_.reset();
752 }
753
SetupConnection(const int id)754 bool SetupConnection(const int id) {
755 ipc_client_factory_->SetConnection(true);
756 ipc_client_factory_->SetResult(true);
757 ipc_client_factory_->SetServerProductVersion(Version::GetMozcVersion());
758 server_launcher_->set_start_server_result(true);
759
760 // TODO(komatsu): Due to the limitation of the testing mock,
761 // EnsureConnection should be explicitly called before calling
762 // SendKey. Fix the testing mock.
763 commands::Output mock_output;
764 mock_output.set_id(id);
765 SetMockOutput(mock_output);
766 return client_->EnsureConnection();
767 }
768
SetMockOutput(const commands::Output & mock_output)769 void SetMockOutput(const commands::Output &mock_output) {
770 string response;
771 mock_output.SerializeToString(&response);
772 ipc_client_factory_->SetMockResponse(response);
773 }
774
775 std::unique_ptr<IPCClientFactoryMock> ipc_client_factory_;
776 std::unique_ptr<IPCClientMock> ipc_client_;
777 std::unique_ptr<Client> client_;
778 SessionPlaybackTestServerLauncher *server_launcher_;
779
780 private:
781 DISALLOW_COPY_AND_ASSIGN(SessionPlaybackTest);
782 };
783
784 // b/2797557
TEST_F(SessionPlaybackTest,PushAndResetHistoryWithNoModeTest)785 TEST_F(SessionPlaybackTest, PushAndResetHistoryWithNoModeTest) {
786 const int mock_id = 123;
787 EXPECT_TRUE(SetupConnection(mock_id));
788
789 commands::KeyEvent key_event;
790 key_event.set_special_key(commands::KeyEvent::ENTER);
791
792 commands::Output mock_output;
793 mock_output.set_id(mock_id);
794 mock_output.set_consumed(true);
795 SetMockOutput(mock_output);
796
797 commands::Output output;
798 EXPECT_TRUE(client_->SendKey(key_event, &output));
799 EXPECT_EQ(mock_output.consumed(), output.consumed());
800
801 std::vector<commands::Input> history;
802 client_->GetHistoryInputs(&history);
803 EXPECT_EQ(1, history.size());
804
805 mock_output.Clear();
806 mock_output.set_id(mock_id);
807 mock_output.set_consumed(true);
808 mock_output.mutable_result()->set_type(commands::Result::STRING);
809 mock_output.mutable_result()->set_value("output");
810 EXPECT_FALSE(mock_output.has_mode());
811 SetMockOutput(mock_output);
812 EXPECT_TRUE(client_->SendKey(key_event, &output));
813 EXPECT_EQ(mock_output.consumed(), output.consumed());
814
815 // history should be reset.
816 client_->GetHistoryInputs(&history);
817 EXPECT_EQ(0, history.size());
818 }
819
820 // b/2797557
TEST_F(SessionPlaybackTest,PushAndResetHistoryWithModeTest)821 TEST_F(SessionPlaybackTest, PushAndResetHistoryWithModeTest) {
822 const int mock_id = 123;
823 EXPECT_TRUE(SetupConnection(mock_id));
824
825 commands::KeyEvent key_event;
826 key_event.set_special_key(commands::KeyEvent::ENTER);
827 key_event.set_mode(commands::HIRAGANA);
828 key_event.set_activated(true);
829
830 commands::Output mock_output;
831 mock_output.set_id(mock_id);
832 mock_output.set_consumed(true);
833 mock_output.set_mode(commands::HIRAGANA);
834 SetMockOutput(mock_output);
835
836 commands::Output output;
837 EXPECT_TRUE(client_->SendKey(key_event, &output));
838 EXPECT_EQ(mock_output.consumed(), output.consumed());
839 EXPECT_TRUE(output.has_mode());
840 EXPECT_EQ(commands::HIRAGANA, output.mode());
841
842 EXPECT_TRUE(client_->SendKey(key_event, &output));
843 EXPECT_EQ(mock_output.consumed(), output.consumed());
844 EXPECT_TRUE(output.has_mode());
845 EXPECT_EQ(commands::HIRAGANA, output.mode());
846
847 std::vector<commands::Input> history;
848 client_->GetHistoryInputs(&history);
849 EXPECT_EQ(2, history.size());
850
851 mock_output.Clear();
852 mock_output.set_id(mock_id);
853 mock_output.set_consumed(true);
854 mock_output.mutable_result()->set_type(commands::Result::STRING);
855 mock_output.mutable_result()->set_value("output");
856 SetMockOutput(mock_output);
857 EXPECT_TRUE(client_->SendKey(key_event, &output));
858 EXPECT_EQ(mock_output.consumed(), output.consumed());
859 client_->GetHistoryInputs(&history);
860 #ifdef OS_MACOSX
861 // history is reset, but initializer should be added because the last mode
862 // is not DIRECT.
863 // TODO(team): fix b/10250883 to remove this special treatment.
864 EXPECT_EQ(1, history.size());
865 // Implicit IMEOn key must be added. See b/2797557 and b/>10250883.
866 EXPECT_EQ(commands::Input::SEND_KEY, history[0].type());
867 EXPECT_EQ(commands::KeyEvent::ON, history[0].key().special_key());
868 EXPECT_EQ(commands::HIRAGANA, history[0].key().mode());
869 #else
870 // history is reset, but initializer is not required.
871 EXPECT_EQ(0, history.size());
872 #endif
873 }
874
875 // b/2797557
TEST_F(SessionPlaybackTest,PushAndResetHistoryWithDirectTest)876 TEST_F(SessionPlaybackTest, PushAndResetHistoryWithDirectTest) {
877 const int mock_id = 123;
878 EXPECT_TRUE(SetupConnection(mock_id));
879
880 commands::KeyEvent key_event;
881 key_event.set_special_key(commands::KeyEvent::ENTER);
882
883 commands::Output mock_output;
884 mock_output.set_id(mock_id);
885 mock_output.set_consumed(true);
886 mock_output.set_mode(commands::DIRECT);
887 SetMockOutput(mock_output);
888
889 commands::Output output;
890 // Send key twice
891 EXPECT_TRUE(client_->SendKey(key_event, &output));
892 EXPECT_EQ(mock_output.consumed(), output.consumed());
893 EXPECT_TRUE(output.has_mode());
894 EXPECT_EQ(commands::DIRECT, output.mode());
895
896 EXPECT_TRUE(client_->SendKey(key_event, &output));
897 EXPECT_EQ(mock_output.consumed(), output.consumed());
898 EXPECT_TRUE(output.has_mode());
899 EXPECT_EQ(commands::DIRECT, output.mode());
900
901 std::vector<commands::Input> history;
902 client_->GetHistoryInputs(&history);
903 EXPECT_EQ(2, history.size());
904
905 mock_output.Clear();
906 mock_output.set_id(mock_id);
907 mock_output.set_consumed(true);
908 mock_output.mutable_result()->set_type(commands::Result::STRING);
909 mock_output.mutable_result()->set_value("output");
910 SetMockOutput(mock_output);
911 EXPECT_TRUE(client_->SendKey(key_event, &output));
912 EXPECT_EQ(mock_output.consumed(), output.consumed());
913
914 // history is reset, and initializer should not be added.
915 client_->GetHistoryInputs(&history);
916 EXPECT_EQ(0, history.size());
917 }
918
TEST_F(SessionPlaybackTest,PlaybackHistoryTest)919 TEST_F(SessionPlaybackTest, PlaybackHistoryTest) {
920 const int mock_id = 123;
921 EXPECT_TRUE(SetupConnection(mock_id));
922
923 commands::KeyEvent key_event;
924 key_event.set_special_key(commands::KeyEvent::ENTER);
925
926 // On Windows, mode initializer should be added if the output contains mode.
927 commands::Output mock_output;
928 mock_output.set_id(mock_id);
929 mock_output.set_consumed(true);
930 SetMockOutput(mock_output);
931
932 commands::Output output;
933 EXPECT_TRUE(client_->SendKey(key_event, &output));
934 EXPECT_EQ(mock_output.consumed(), output.consumed());
935
936 EXPECT_TRUE(client_->SendKey(key_event, &output));
937 EXPECT_EQ(mock_output.consumed(), output.consumed());
938
939 std::vector<commands::Input> history;
940 client_->GetHistoryInputs(&history);
941 EXPECT_EQ(2, history.size());
942
943 // Invalid id
944 const int new_id = 456;
945 mock_output.set_id(new_id);
946 SetMockOutput(mock_output);
947 EXPECT_TRUE(client_->SendKey(key_event, &output));
948
949 #ifndef DEBUG
950 // PlaybackHistory and push history
951 client_->GetHistoryInputs(&history);
952 EXPECT_EQ(3, history.size());
953 #else
954 // PlaybackHistory, dump history(including reset), and add last input
955 client_->GetHistoryInputs(&history);
956 EXPECT_EQ(1, history.size());
957 #endif
958 }
959
960 // b/2797557
TEST_F(SessionPlaybackTest,SetModeInitializerTest)961 TEST_F(SessionPlaybackTest, SetModeInitializerTest) {
962 const int mock_id = 123;
963 EXPECT_TRUE(SetupConnection(mock_id));
964
965 commands::KeyEvent key_event;
966 key_event.set_special_key(commands::KeyEvent::ENTER);
967
968 commands::Output mock_output;
969 mock_output.set_id(mock_id);
970 mock_output.set_consumed(true);
971 mock_output.set_mode(commands::HIRAGANA);
972 SetMockOutput(mock_output);
973
974 commands::Output output;
975 EXPECT_TRUE(client_->SendKey(key_event, &output));
976 EXPECT_EQ(mock_output.consumed(), output.consumed());
977
978 mock_output.set_mode(commands::DIRECT);
979 SetMockOutput(mock_output);
980
981 EXPECT_TRUE(client_->SendKey(key_event, &output));
982 EXPECT_EQ(mock_output.consumed(), output.consumed());
983 EXPECT_TRUE(output.has_mode());
984 EXPECT_EQ(commands::DIRECT, output.mode());
985
986 mock_output.set_mode(commands::FULL_KATAKANA);
987 SetMockOutput(mock_output);
988
989 EXPECT_TRUE(client_->SendKey(key_event, &output));
990 EXPECT_EQ(mock_output.consumed(), output.consumed());
991 EXPECT_TRUE(output.has_mode());
992 EXPECT_EQ(commands::FULL_KATAKANA, output.mode());
993
994 std::vector<commands::Input> history;
995 client_->GetHistoryInputs(&history);
996 EXPECT_EQ(3, history.size());
997
998 mock_output.Clear();
999 mock_output.set_id(mock_id);
1000 mock_output.set_consumed(true);
1001 mock_output.mutable_result()->set_type(commands::Result::STRING);
1002 mock_output.mutable_result()->set_value("output");
1003 SetMockOutput(mock_output);
1004 EXPECT_TRUE(client_->SendKey(key_event, &output));
1005 EXPECT_EQ(mock_output.consumed(), output.consumed());
1006 client_->GetHistoryInputs(&history);
1007 #ifdef OS_MACOSX
1008 // history is reset, but initializer should be added.
1009 // TODO(team): fix b/10250883 to remove this special treatment.
1010 EXPECT_EQ(1, history.size());
1011 EXPECT_EQ(commands::Input::SEND_KEY, history[0].type());
1012 EXPECT_EQ(commands::KeyEvent::ON, history[0].key().special_key());
1013 EXPECT_EQ(commands::FULL_KATAKANA, history[0].key().mode());
1014 #else
1015 // history is reset, but initializer is not required.
1016 EXPECT_EQ(0, history.size());
1017 #endif
1018 }
1019
TEST_F(SessionPlaybackTest,ConsumedTest)1020 TEST_F(SessionPlaybackTest, ConsumedTest) {
1021 const int mock_id = 123;
1022 EXPECT_TRUE(SetupConnection(mock_id));
1023
1024 commands::KeyEvent key_event;
1025 key_event.set_special_key(commands::KeyEvent::ENTER);
1026
1027 commands::Output mock_output;
1028 mock_output.set_id(mock_id);
1029 mock_output.set_consumed(true);
1030 SetMockOutput(mock_output);
1031
1032 commands::Output output;
1033 EXPECT_TRUE(client_->SendKey(key_event, &output));
1034 EXPECT_EQ(mock_output.consumed(), output.consumed());
1035
1036 EXPECT_TRUE(client_->SendKey(key_event, &output));
1037 EXPECT_EQ(mock_output.consumed(), output.consumed());
1038
1039 std::vector<commands::Input> history;
1040 client_->GetHistoryInputs(&history);
1041 EXPECT_EQ(2, history.size());
1042
1043 mock_output.set_consumed(false);
1044 SetMockOutput(mock_output);
1045
1046 EXPECT_TRUE(client_->SendKey(key_event, &output));
1047 EXPECT_EQ(mock_output.consumed(), output.consumed());
1048
1049 // Do not push unconsumed input
1050 client_->GetHistoryInputs(&history);
1051 EXPECT_EQ(2, history.size());
1052 }
1053 } // namespace client
1054 } // namespace mozc
1055