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