X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/eb3d5c6416c0f0d1cad35e52af3231de7866fea8..refs/heads/iannucci:/rpc/rpctest.cc diff --git a/rpc/rpctest.cc b/rpc/rpctest.cc index f2e8c7d..968fc22 100644 --- a/rpc/rpctest.cc +++ b/rpc/rpctest.cc @@ -1,35 +1,28 @@ // RPC test and pseudo-documentation. // generates print statements on failures, but eventually says "rpctest OK" -#include "types.h" -#include "rpc.h" +#include "include/types.h" +#include "include/rpc/rpc.h" #include #include #include #include +#include "include/debug.h" #define NUM_CL 2 -char log_thread_prefix = 'r'; - static rpcs *server; // server rpc object static rpcc *clients[NUM_CL]; // client rpc object -static string dst; //server's ip address +static string * dst; //server's ip address static in_port_t port; -// server-side handlers. they must be methods of some class -// to simplify rpcs::reg(). a server process can have handlers -// from multiple classes. -class srv { - public: - int handle_22(string & r, const string a, const string b); - int handle_fast(int & r, const int a); - int handle_slow(int & r, const int a); - int handle_bigrep(string & r, const size_t a); -}; +using std::cout; +using std::endl; +using namespace std::chrono; +using std::vector; namespace srv_protocol { - using status = rpc_protocol::status; + enum status : rpc_protocol::status {OK}; REMOTE_PROCEDURE_BASE(0); REMOTE_PROCEDURE(22, _22, (string &, string, string)); REMOTE_PROCEDURE(23, fast, (int &, int)); @@ -37,6 +30,17 @@ namespace srv_protocol { REMOTE_PROCEDURE(25, bigrep, (string &, size_t)); } +// server-side handlers. they must be methods of some class +// to simplify rpcs::reg(). a server process can have handlers +// from multiple classes. +class srv { + public: + srv_protocol::status handle_22(string & r, const string a, const string b); + srv_protocol::status handle_fast(int & r, const int a); + srv_protocol::status handle_slow(int & r, const int a); + srv_protocol::status handle_bigrep(string & r, const size_t a); +}; + // a handler. a and b are arguments, r is the result. // there can be multiple arguments but only one result. // the caller also gets to see the int return value @@ -44,25 +48,26 @@ namespace srv_protocol { // rpcs::reg() decides how to unmarshall by looking // at these argument types, so this function definition // does what a .x file does in SunRPC. -int srv::handle_22(string & r, const string a, string b) { +srv_protocol::status srv::handle_22(string & r, const string a, string b) { r = a + b; - return 0; + return srv_protocol::OK; } -int srv::handle_fast(int & r, const int a) { +srv_protocol::status srv::handle_fast(int & r, const int a) { r = a + 1; - return 0; + return srv_protocol::OK; } -int srv::handle_slow(int & r, const int a) { - usleep(random() % 500); +srv_protocol::status srv::handle_slow(int & r, const int a) { + auto duration = std::uniform_int_distribution<>(0,500)(global->random_generator) * 1us; + std::this_thread::sleep_for(duration); r = a + 2; - return 0; + return srv_protocol::OK; } -int srv::handle_bigrep(string & r, const size_t len) { +srv_protocol::status srv::handle_bigrep(string & r, const size_t len) { r = string(len, 'x'); - return 0; + return srv_protocol::OK; } static srv service; @@ -79,8 +84,7 @@ static void startserver() { static void testmarshall() { marshall m; rpc_protocol::request_header rh{1,2,3,4,5}; - m.pack_header(rh); - VERIFY(((string)m).size()==rpc_protocol::RPC_HEADER_SZ); + VERIFY(marshall::datagram(rh, m).size()==rpc_protocol::RPC_HEADER_SZ); int i = 12345; unsigned long long l = 1223344455L; size_t sz = 101010101; @@ -92,12 +96,11 @@ static void testmarshall() { m << sz; m << bin; - string b = m; - VERIFY(b.size() == rpc_protocol::RPC_HEADER_SZ+sizeof(i)+sizeof(l)+sizeof(uint32_t)+s.size()+sizeof(uint32_t)+sizeof(uint32_t)+bin.size()); + string b = marshall::datagram(rh, m); + VERIFY(b.size() == rpc_protocol::RPC_HEADER_SZ+sizeof(i)+sizeof(l)+sizeof(uint32_t)+s.size()+sizeof(uint64_t)+sizeof(uint32_t)+bin.size()); - unmarshall un(b, true); rpc_protocol::request_header rh1; - un.unpack_header(rh1); + auto un = unmarshall::datagram(b, rh1); VERIFY(memcmp(&rh,&rh1,sizeof(rh))==0); int i1; unsigned long long l1; @@ -118,7 +121,7 @@ static void client1(size_t cl) { size_t which_cl = cl % NUM_CL; for(int i = 0; i < 100; i++){ - unsigned long arg = (random() % 2000); + auto arg = std::uniform_int_distribution(0,2000)(global->random_generator); string rep; int ret = clients[which_cl]->call(srv_protocol::bigrep, rep, arg); VERIFY(ret == 0); @@ -130,15 +133,15 @@ static void client1(size_t cl) { // test rpc replies coming back not in the order of // the original calls -- i.e. does xid reply dispatch work. for(int i = 0; i < 100; i++){ - int which = (random() % 2); - int arg = (random() % 1000); - int rep; + bool which = std::bernoulli_distribution()(global->random_generator); + int arg = std::uniform_int_distribution<>(0,1000)(global->random_generator); + int rep = -1; auto start = steady_clock::now(); int ret = clients[which_cl]->call(which ? srv_protocol::fast : srv_protocol::slow, rep, arg); auto end = steady_clock::now(); - auto diff = duration_cast(end - start).count(); + auto diff = (end - start) / 1ms; if (ret != 0) cout << diff << " ms have elapsed!!!" << endl; VERIFY(ret == 0); @@ -153,7 +156,7 @@ static void client2(size_t cl) { time(&t1); while(time(0) - t1 < 10){ - unsigned long arg = (random() % 2000); + auto arg = std::uniform_int_distribution(0,2000)(global->random_generator); string rep; int ret = clients[which_cl]->call(srv_protocol::bigrep, rep, arg); if ((unsigned long)rep.size()!=arg) @@ -167,7 +170,7 @@ static void client3(void *xx) { for(int i = 0; i < 4; i++){ int rep = 0; - int ret = c->call_timeout(srv_protocol::slow, milliseconds(300), rep, i); + int ret = c->call_timeout(srv_protocol::slow, 300ms, rep, i); VERIFY(ret == rpc_protocol::timeout_failure || rep == i+2); } } @@ -185,14 +188,14 @@ static void simple_tests(rpcc *c) { cout << " -- string concat RPC .. ok" << endl; // small request, big reply (perhaps req via UDP, reply via TCP) - intret = c->call_timeout(srv_protocol::bigrep, milliseconds(20000), rep, 70000ul); + intret = c->call_timeout(srv_protocol::bigrep, 20000ms, rep, 70000ul); VERIFY(intret == 0); VERIFY(rep.size() == 70000); cout << " -- small request, big reply .. ok" << endl; // specify a timeout value to an RPC that should succeed (udp) int xx = 0; - intret = c->call_timeout(srv_protocol::fast, milliseconds(300), xx, 77); + intret = c->call_timeout(srv_protocol::fast, 300ms, xx, 77); VERIFY(intret == 0 && xx == 78); cout << " -- no spurious timeout .. ok" << endl; @@ -200,7 +203,7 @@ static void simple_tests(rpcc *c) { { string arg(1000, 'x'); string rep2; - c->call_timeout(srv_protocol::_22, milliseconds(300), rep2, arg, (string)"x"); + c->call_timeout(srv_protocol::_22, 300ms, rep2, arg, (string)"x"); VERIFY(rep2.size() == 1001); cout << " -- no spurious timeout .. ok" << endl; } @@ -216,7 +219,7 @@ static void simple_tests(rpcc *c) { string non_existent = "127.0.0.1:7661"; rpcc *c1 = new rpcc(non_existent); time_t t0 = time(0); - intret = c1->bind(milliseconds(300)); + intret = c1->bind(300ms); time_t t1 = time(0); VERIFY(intret < 0 && (t1 - t0) <= 4); cout << " -- rpc timeout .. ok" << endl; @@ -251,7 +254,7 @@ static void lossy_test() { for (int i = 0; i < NUM_CL; i++) { delete clients[i]; - clients[i] = new rpcc(dst); + clients[i] = new rpcc(*dst); VERIFY(clients[i]->bind()==0); } @@ -277,8 +280,8 @@ static void failure_test() { delete server; - client1 = new rpcc(dst); - VERIFY (client1->bind(milliseconds(3000)) < 0); + client1 = new rpcc(*dst); + VERIFY (client1->bind(3000ms) < 0); cout << " -- create new client and try to bind to failed server .. failed ok" << endl; delete client1; @@ -292,7 +295,7 @@ static void failure_test() { delete client; - clients[0] = client = new rpcc(dst); + clients[0] = client = new rpcc(*dst); VERIFY (client->bind() >= 0); VERIFY (client->bind() < 0); @@ -320,7 +323,7 @@ static void failure_test() { delete client; startserver(); - clients[0] = client = new rpcc(dst); + clients[0] = client = new rpcc(*dst); VERIFY (client->bind() >= 0); cout << " -- delete existing rpc client and server, create replacements.. ok" << endl; @@ -338,6 +341,7 @@ static void failure_test() { } int main(int argc, char *argv[]) { + global = new t4_state('r'); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); @@ -346,7 +350,6 @@ int main(int argc, char *argv[]) { bool isclient = false; bool isserver = false; - srandom((uint32_t)getpid()); port = 20000 + (getpid() % 10000); int ch = 0; @@ -377,7 +380,7 @@ int main(int argc, char *argv[]) { } if (debug_level > 0) { - DEBUG_LEVEL = debug_level; + global->DEBUG_LEVEL = debug_level; IF_LEVEL(1) LOG_NONMEMBER << "DEBUG LEVEL: " << debug_level; } @@ -390,7 +393,7 @@ int main(int argc, char *argv[]) { if (isclient) { // server's address. - dst = "127.0.0.1:" + to_string(port); + dst = new string("127.0.0.1:" + std::to_string(port)); // start the client. bind it to the server. @@ -399,7 +402,7 @@ int main(int argc, char *argv[]) { // be only one rpcc per process. you probably need one // rpcc per server. for (int i = 0; i < NUM_CL; i++) { - clients[i] = new rpcc(dst); + clients[i] = new rpcc(*dst); VERIFY (clients[i]->bind() == 0); } @@ -416,5 +419,5 @@ int main(int argc, char *argv[]) { } while (1) - usleep(100000); + std::this_thread::sleep_for(100ms); }