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 <cstring>
31 #include <iostream> // NOLINT
32 #include <string>
33 #include <vector>
34
35 #include "base/flags.h"
36 #include "base/init_mozc.h"
37 #include "base/logging.h"
38 #include "base/port.h"
39 #include "base/thread.h"
40 #include "ipc/ipc.h"
41
42 DEFINE_string(server_address, "ipc_test", "");
43 DEFINE_bool(test, false, "automatic test mode");
44 DEFINE_bool(server, false, "invoke as server mode");
45 DEFINE_bool(client, false, "invoke as client mode");
46 DEFINE_string(server_path, "", "server path");
47 DEFINE_int32(num_threads, 10, "number of threads");
48 DEFINE_int32(num_requests, 100, "number of requests");
49
50 namespace mozc {
51
52 class MultiConnections: public Thread {
53 public:
Run()54 void Run() {
55 char buf[8192];
56 for (int i = 0; i < FLAGS_num_requests; ++i) {
57 mozc::IPCClient con(FLAGS_server_address, FLAGS_server_path);
58 CHECK(con.Connected());
59 string input = "testtesttesttest";
60 size_t length = sizeof(buf);
61 ::memset(buf, 0, length);
62 CHECK(con.Call(input.data(), input.size(), buf, &length, 1000));
63 string output(buf, length);
64 CHECK_EQ(input.size(), output.size());
65 CHECK_EQ(input, output);
66 }
67 }
68 };
69
70 class EchoServer: public IPCServer {
71 public:
EchoServer(const string & path,int32 num_connections,int32 timeout)72 EchoServer(const string &path,
73 int32 num_connections,
74 int32 timeout) :
75 IPCServer(path, num_connections, timeout) {}
Process(const char * input_buffer,size_t input_length,char * output_buffer,size_t * output_length)76 virtual bool Process(const char *input_buffer,
77 size_t input_length,
78 char *output_buffer,
79 size_t *output_length) {
80 ::memcpy(output_buffer, input_buffer, input_length);
81 *output_length = input_length;
82 return ::memcmp("kill", input_buffer, 4) != 0;
83 }
84 };
85
86 class EchoServerThread: public Thread {
87 public:
EchoServerThread(EchoServer * con)88 explicit EchoServerThread(EchoServer *con): con_(con) {}
Run()89 virtual void Run() {
90 con_->Loop();
91 }
92 private:
93 EchoServer *con_;
94 };
95
96 } // namespace mozc
97
main(int argc,char ** argv)98 int main(int argc, char **argv) {
99 mozc::InitMozc(argv[0], &argc, &argv, false);
100
101 if (FLAGS_test) {
102 mozc::EchoServer con(FLAGS_server_address, 10, 1000);
103 mozc::EchoServerThread server_thread_main(&con);
104 server_thread_main.SetJoinable(true);
105 server_thread_main.Start("IpcMain");
106
107 std::vector<mozc::MultiConnections> cons(FLAGS_num_threads);
108 for (size_t i = 0; i < cons.size(); ++i) {
109 cons[i].SetJoinable(true);
110 cons[i].Start("MultiConnections");
111 }
112 for (size_t i = 0; i < cons.size(); ++i) {
113 cons[i].Join();
114 }
115
116 mozc::IPCClient kill(FLAGS_server_address, FLAGS_server_path);
117 const char kill_cmd[32] = "kill";
118 char output[32];
119 size_t output_size = sizeof(output);
120 kill.Call(kill_cmd, strlen(kill_cmd),
121 output, &output_size, 1000);
122 server_thread_main.Join();
123
124 LOG(INFO) << "Done";
125
126 } else if (FLAGS_server) {
127 mozc::EchoServer con(FLAGS_server_address,
128 10, -1);
129 CHECK(con.Connected());
130 LOG(INFO) << "Start Server at " << FLAGS_server_address;
131 con.Loop();
132 } else if (FLAGS_client) {
133 string line;
134 char response[8192];
135 while (getline(cin, line)) {
136 mozc::IPCClient con(FLAGS_server_address, FLAGS_server_path);
137 CHECK(con.Connected());
138 size_t response_size = sizeof(response);
139 CHECK(con.Call(line.data(), line.size(),
140 response, &response_size, 1000));
141 cout << "Request: " << line << endl;
142 cout << "Response: " << string(response, response_size) << endl;
143 }
144 } else {
145 LOG(INFO) << "either --server or --client or --test must be set true";
146 }
147
148 return 0;
149 }
150