X-Git-Url: http://xvm.mit.edu/gitweb/invirt/third/libt4.git/blobdiff_plain/4e881433f37417ccbda89c09ffdf936855d462d4..c06ef44e7af1571710fd31dd0ab068dd77b1eb2d:/rpc/rpctest.cc diff --git a/rpc/rpctest.cc b/rpc/rpctest.cc index 4dd2af2..051e564 100644 --- a/rpc/rpctest.cc +++ b/rpc/rpctest.cc @@ -7,25 +7,29 @@ #include #include #include +#include "threaded_log.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; +using std::cout; +using std::endl; +using namespace std::chrono; +using std::vector; + // 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); + 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); }; namespace srv_protocol { @@ -35,7 +39,7 @@ namespace srv_protocol { REMOTE_PROCEDURE(23, fast, (int &, int)); REMOTE_PROCEDURE(24, slow, (int &, int)); REMOTE_PROCEDURE(25, bigrep, (string &, size_t)); -}; +} // a handler. a and b are arguments, r is the result. // there can be multiple arguments but only one result. @@ -44,30 +48,30 @@ 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) { +int srv::handle_22(string & r, const string a, string b) { r = a + b; return 0; } -int srv::handle_fast(int &r, const int a) { +int srv::handle_fast(int & r, const int a) { r = a + 1; return 0; } -int srv::handle_slow(int &r, const int a) { - usleep(random() % 500); +int srv::handle_slow(int & r, const int a) { + usleep(std::uniform_int_distribution(0,500)(global->random_generator)); r = a + 2; return 0; } -int srv::handle_bigrep(string &r, const size_t len) { +int srv::handle_bigrep(string & r, const size_t len) { r = string(len, 'x'); return 0; } static srv service; -void startserver() { +static void startserver() { server = new rpcs(port); server->reg(srv_protocol::_22, &srv::handle_22, &service); server->reg(srv_protocol::fast, &srv::handle_fast, &service); @@ -76,45 +80,49 @@ void startserver() { server->start(); } -void testmarshall() { +static void testmarshall() { marshall m; rpc_protocol::request_header rh{1,2,3,4,5}; - m.pack_header(rh); + m.write_header(rh); VERIFY(((string)m).size()==rpc_protocol::RPC_HEADER_SZ); int i = 12345; unsigned long long l = 1223344455L; size_t sz = 101010101; string s = "hallo...."; + string bin("\x00\x00\x00\x00\x00\x00\x00\x40\x00\x00\x7f\xe5", 12); m << i; m << l; m << s; m << sz; + m << bin; string b = m; - VERIFY(b.size() == rpc_protocol::RPC_HEADER_SZ+sizeof(i)+sizeof(l)+s.size()+sizeof(int)+sizeof(uint32_t)); + 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()); unmarshall un(b, true); rpc_protocol::request_header rh1; - un.unpack_header(rh1); + un.read_header(rh1); VERIFY(memcmp(&rh,&rh1,sizeof(rh))==0); int i1; unsigned long long l1; string s1; + string bin1; size_t sz1; un >> i1; un >> l1; un >> s1; un >> sz1; + un >> bin1; VERIFY(un.okdone()); - VERIFY(i1==i && l1==l && s1==s && sz1==sz); + VERIFY(i1==i && l1==l && s1==s && sz1==sz && bin1==bin); } -void client1(size_t cl) { +static void client1(size_t cl) { // test concurrency. 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); @@ -126,9 +134,9 @@ 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(); @@ -142,14 +150,14 @@ void client1(size_t cl) { } } -void client2(size_t cl) { +static void client2(size_t cl) { size_t which_cl = cl % NUM_CL; time_t t1; 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) @@ -158,7 +166,7 @@ void client2(size_t cl) { } } -void client3(void *xx) { +static void client3(void *xx) { rpcc *c = (rpcc *) xx; for(int i = 0; i < 4; i++){ @@ -168,7 +176,7 @@ void client3(void *xx) { } } -void simple_tests(rpcc *c) { +static void simple_tests(rpcc *c) { cout << "simple_tests" << endl; // an RPC call to procedure #22. // rpcc::call() looks at the argument types to decide how @@ -219,7 +227,7 @@ void simple_tests(rpcc *c) { cout << "simple_tests OK" << endl; } -void concurrent_test(size_t nt) { +static void concurrent_test(size_t nt) { // create threads that make lots of calls in parallel, // to test thread synchronization for concurrent calls // and dispatches. @@ -236,7 +244,7 @@ void concurrent_test(size_t nt) { cout << " OK" << endl; } -void lossy_test() { +static void lossy_test() { cout << "start lossy_test ..."; VERIFY(setenv("RPC_LOSSY", "5", 1) == 0); @@ -247,7 +255,7 @@ 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); } @@ -265,7 +273,7 @@ void lossy_test() { VERIFY(setenv("RPC_LOSSY", "0", 1) == 0); } -void failure_test() { +static void failure_test() { rpcc *client1; rpcc *client = clients[0]; @@ -273,7 +281,7 @@ void failure_test() { delete server; - client1 = new rpcc(dst); + client1 = new rpcc(*dst); VERIFY (client1->bind(milliseconds(3000)) < 0); cout << " -- create new client and try to bind to failed server .. failed ok" << endl; @@ -288,7 +296,7 @@ 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); @@ -316,7 +324,7 @@ 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; @@ -334,6 +342,7 @@ void failure_test() { } int main(int argc, char *argv[]) { + global = new t4_state('r'); setvbuf(stdout, NULL, _IONBF, 0); setvbuf(stderr, NULL, _IONBF, 0); @@ -342,7 +351,6 @@ int main(int argc, char *argv[]) { bool isclient = false; bool isserver = false; - srandom((uint32_t)getpid()); port = 20000 + (getpid() % 10000); int ch = 0; @@ -373,8 +381,8 @@ int main(int argc, char *argv[]) { } if (debug_level > 0) { - DEBUG_LEVEL = debug_level; - IF_LEVEL(1) LOG_NONMEMBER("DEBUG LEVEL: " << debug_level); + global->DEBUG_LEVEL = debug_level; + IF_LEVEL(1) LOG_NONMEMBER << "DEBUG LEVEL: " << debug_level; } testmarshall(); @@ -386,7 +394,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. @@ -395,7 +403,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); }