blob: 64ddba343850ea94e0bfa6f1f2a97dfb5b96a22a [file] [log] [blame]
// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "ipc/ipc.h"
#include <cstring>
#include <iostream> // NOLINT
#include <string>
#include <vector>
#include "base/flags.h"
#include "base/logging.h"
#include "base/port.h"
#include "base/thread.h"
DEFINE_string(server_address, "ipc_test", "");
DEFINE_bool(test, false, "automatic test mode");
DEFINE_bool(server, false, "invoke as server mode");
DEFINE_bool(client, false, "invoke as client mode");
DEFINE_string(server_path, "", "server path");
DEFINE_int32(num_threads, 10, "number of threads");
DEFINE_int32(num_requests, 100, "number of requests");
namespace mozc {
class MultiConnections: public Thread {
public:
void Run() {
char buf[8192];
for (int i = 0; i < FLAGS_num_requests; ++i) {
mozc::IPCClient con(FLAGS_server_address, FLAGS_server_path);
CHECK(con.Connected());
string input = "testtesttesttest";
size_t length = sizeof(buf);
::memset(buf, 0, length);
CHECK(con.Call(input.data(), input.size(), buf, &length, 1000));
string output(buf, length);
CHECK_EQ(input.size(), output.size());
CHECK_EQ(input, output);
}
}
};
class EchoServer: public IPCServer {
public:
EchoServer(const string &path,
int32 num_connections,
int32 timeout) :
IPCServer(path, num_connections, timeout) {}
virtual bool Process(const char *input_buffer,
size_t input_length,
char *output_buffer,
size_t *output_length) {
::memcpy(output_buffer, input_buffer, input_length);
*output_length = input_length;
return ::memcmp("kill", input_buffer, 4) != 0;
}
};
class EchoServerThread: public Thread {
public:
explicit EchoServerThread(EchoServer *con): con_(con) {}
virtual void Run() {
con_->Loop();
}
private:
EchoServer *con_;
};
} // namespace mozc
int main(int argc, char **argv) {
InitGoogle(argv[0], &argc, &argv, false);
if (FLAGS_test) {
mozc::EchoServer con(FLAGS_server_address, 10, 1000);
mozc::EchoServerThread server_thread_main(&con);
server_thread_main.SetJoinable(true);
server_thread_main.Start();
vector<mozc::MultiConnections> cons(FLAGS_num_threads);
for (size_t i = 0; i < cons.size(); ++i) {
cons[i].SetJoinable(true);
cons[i].Start();
}
for (size_t i = 0; i < cons.size(); ++i) {
cons[i].Join();
}
mozc::IPCClient kill(FLAGS_server_address, FLAGS_server_path);
const char kill_cmd[32] = "kill";
char output[32];
size_t output_size = sizeof(output);
kill.Call(kill_cmd, strlen(kill_cmd),
output, &output_size, 1000);
server_thread_main.Join();
LOG(INFO) << "Done";
} else if (FLAGS_server) {
mozc::EchoServer con(FLAGS_server_address,
10, -1);
CHECK(con.Connected());
LOG(INFO) << "Start Server at " << FLAGS_server_address;
con.Loop();
} else if (FLAGS_client) {
string line;
char response[8192];
while (getline(cin, line)) {
mozc::IPCClient con(FLAGS_server_address, FLAGS_server_path);
CHECK(con.Connected());
size_t response_size = sizeof(response);
CHECK(con.Call(line.data(), line.size(),
response, &response_size, 1000));
cout << "Request: " << line << endl;
cout << "Response: " << string(response, response_size) << endl;
}
} else {
LOG(INFO) << "either --server or --client or --test must be set true";
}
return 0;
}