diff options
Diffstat (limited to 'src/gtest')
-rw-r--r-- | src/gtest/rpc_test.cpp | 516 |
1 files changed, 432 insertions, 84 deletions
diff --git a/src/gtest/rpc_test.cpp b/src/gtest/rpc_test.cpp index 8a7e9176..168ee936 100644 --- a/src/gtest/rpc_test.cpp +++ b/src/gtest/rpc_test.cpp @@ -25,12 +25,23 @@ limitations under the License. #include <zmq.h> #include <json/json.h> #include <sstream> +#include <vector> +#include <algorithm> using namespace std; class RpcTest : public testing::Test { +protected: + + void set_verbose(bool verbose) { + m_verbose = verbose; + } + virtual void SetUp() { + + m_verbose = false; + TrexRpcServerConfig cfg = TrexRpcServerConfig(TrexRpcServerConfig::RPC_PROT_TCP, 5050); m_rpc = new TrexRpcServer(cfg); @@ -39,6 +50,7 @@ class RpcTest : public testing::Test { m_context = zmq_ctx_new (); m_socket = zmq_socket (m_context, ZMQ_REQ); zmq_connect (m_socket, "tcp://localhost:5050"); + } virtual void TearDown() { @@ -50,8 +62,41 @@ class RpcTest : public testing::Test { } public: + + void create_request(Json::Value &request, const string &method, int id = 1) { + request.clear(); + + request["jsonrpc"] = "2.0"; + request["id"] = id; + request["method"] = method; + + } + + void send_request(const Json::Value &request, Json::Value &response) { + Json::FastWriter writer; + Json::Reader reader; + + response.clear(); + + string request_str = writer.write(request); + + if (m_verbose) { + cout << "\n" << request_str << "\n"; + } + + string ret = send_msg(request_str); + + if (m_verbose) { + cout << "\n" << ret << "\n"; + } + + EXPECT_TRUE(reader.parse(ret, response, false)); + EXPECT_EQ(response["jsonrpc"], "2.0"); + EXPECT_EQ(response["id"], request["id"]); + } + string send_msg(const string &msg) { - char buffer[512]; + char buffer[1024 * 20]; zmq_send (m_socket, msg.c_str(), msg.size(), 0); int len = zmq_recv(m_socket, buffer, sizeof(buffer), 0); @@ -62,9 +107,64 @@ public: TrexRpcServer *m_rpc; void *m_context; void *m_socket; + bool m_verbose; }; -TEST_F(RpcTest, basic_rpc_test) { +class RpcTestOwned : public RpcTest { +public: + + void create_request(Json::Value &request, const string &method, int id = 1, int port_id = 1, bool owned = true) { + RpcTest::create_request(request, method, id); + if (owned) { + request["params"]["port_id"] = port_id; + request["params"]["handler"] = m_ownership_handler[port_id]; + } + } + +protected: + + virtual void SetUp() { + RpcTest::SetUp(); + + for (int i = 0 ; i < 4; i++) { + m_ownership_handler[i] = take_ownership(i); + } + } + + + string take_ownership(uint8_t port_id) { + Json::Value request; + Json::Value response; + + RpcTest::create_request(request, "acquire", 1); + + request["params"]["port_id"] = port_id; + request["params"]["user"] = "test"; + request["params"]["force"] = true; + + send_request(request, response); + + EXPECT_TRUE(response["result"] != Json::nullValue); + return response["result"].asString(); + } + + void release_ownership(uint8_t port_id) { + Json::Value request; + Json::Value response; + + RpcTest::create_request(request, "release", 1); + + request["params"]["handler"] = m_ownership_handler; + request["params"]["port_id"] = port_id; + + send_request(request, response); + EXPECT_TRUE(response["result"] == "ACK"); + } + + string m_ownership_handler[4]; +}; + +TEST_F(RpcTest, basic_rpc_negative_cases) { Json::Value request; Json::Value response; Json::Reader reader; @@ -121,55 +221,39 @@ TEST_F(RpcTest, basic_rpc_test) { TEST_F(RpcTest, test_add_command) { Json::Value request; Json::Value response; - Json::Reader reader; - string req_str; - string resp_str; - - /* simple add - missing paramters */ - req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"id\": 488}"; - resp_str = send_msg(req_str); + /* missing parameters */ + create_request(request, "test_add"); + send_request(request, response); - EXPECT_TRUE(reader.parse(resp_str, response, false)); EXPECT_EQ(response["jsonrpc"], "2.0"); - EXPECT_EQ(response["id"], 488); EXPECT_EQ(response["error"]["code"], -32602); - /* simple add that works */ - req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": 17, \"y\": -13} , \"id\": \"itay\"}"; - resp_str = send_msg(req_str); - - EXPECT_TRUE(reader.parse(resp_str, response, false)); - EXPECT_EQ(response["jsonrpc"], "2.0"); - EXPECT_EQ(response["id"], "itay"); - EXPECT_EQ(response["result"], 4); - - /* add with bad paratemers types */ - req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": \"blah\", \"y\": -13} , \"id\": 17}"; - resp_str = send_msg(req_str); + /* bad paramters */ + create_request(request, "test_add"); + request["params"]["x"] = 5; + request["params"]["y"] = "itay"; + send_request(request, response); - EXPECT_TRUE(reader.parse(resp_str, response, false)); EXPECT_EQ(response["jsonrpc"], "2.0"); - EXPECT_EQ(response["id"], 17); EXPECT_EQ(response["error"]["code"], -32602); - /* add with invalid count of parameters */ - req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"y\": -13} , \"id\": 17}"; - resp_str = send_msg(req_str); + /* simple add that works */ + create_request(request, "test_add"); + request["params"]["x"] = 5; + request["params"]["y"] = -13; + send_request(request, response); - EXPECT_TRUE(reader.parse(resp_str, response, false)); EXPECT_EQ(response["jsonrpc"], "2.0"); - EXPECT_EQ(response["id"], 17); - EXPECT_EQ(response["error"]["code"], -32602); - + EXPECT_EQ(response["result"], -8); /* big numbers */ - req_str = "{\"jsonrpc\": \"2.0\", \"method\": \"test_add\", \"params\": {\"x\": 4827371, \"y\": -39181273} , \"id\": \"itay\"}"; - resp_str = send_msg(req_str); + create_request(request, "test_add"); + request["params"]["x"] = 4827371; + request["params"]["y"] = -39181273; + send_request(request, response); - EXPECT_TRUE(reader.parse(resp_str, response, false)); EXPECT_EQ(response["jsonrpc"], "2.0"); - EXPECT_EQ(response["id"], "itay"); EXPECT_EQ(response["result"], -34353902); } @@ -225,87 +309,351 @@ TEST_F(RpcTest, batch_rpc_test) { return; } -TEST_F(RpcTest, add_stream) { +/* ping command */ +TEST_F(RpcTest, ping) { Json::Value request; Json::Value response; - Json::Reader reader; - string resp_str; + create_request(request, "ping"); + send_request(request, response); + EXPECT_TRUE(response["result"] == "ACK"); +} + +static bool +find_member_in_array(const Json::Value &array, const string &member) { + for (auto x : array) { + if (x == member) { + return true; + } + } - // check the stream does not exists - string lookup_str = "{\"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"get_stream\", \"params\":{\"port_id\":1, \"stream_id\":5}}"; - resp_str = send_msg(lookup_str); + return false; +} + +/* get registered commands */ +TEST_F(RpcTest, get_supported_cmds) { + Json::Value request; + Json::Value response; + + create_request(request, "get_supported_cmds"); + send_request(request, response); + EXPECT_TRUE(response["result"].size() > 0); + + EXPECT_TRUE(find_member_in_array(response["result"], "ping")); + EXPECT_TRUE(find_member_in_array(response["result"], "get_supported_cmds")); +} + +/* get version */ +TEST_F(RpcTest, get_version) { + Json::Value request; + Json::Value response; + + create_request(request, "get_version"); + send_request(request, response); + + EXPECT_TRUE(response["result"] != Json::nullValue); + EXPECT_TRUE(response["result"]["built_by"] == "MOCK"); + EXPECT_TRUE(response["result"]["version"] == "v0.0"); +} + +/* get system info */ +TEST_F(RpcTest, get_system_info) { + Json::Value request; + Json::Value response; + + create_request(request, "get_system_info"); + send_request(request, response); + + EXPECT_TRUE(response["result"] != Json::nullValue); + EXPECT_TRUE(response["result"]["core_type"].isString()); + EXPECT_TRUE(response["result"]["hostname"].isString()); + EXPECT_TRUE(response["result"]["uptime"].isString()); + EXPECT_TRUE(response["result"]["dp_core_count"] > 0); + EXPECT_TRUE(response["result"]["port_count"] > 0); + + EXPECT_TRUE(response["result"]["ports"].isArray()); + + const Json::Value &ports = response["result"]["ports"]; + + + for (int i = 0; i < ports.size(); i++) { + EXPECT_TRUE(ports[i]["index"] == i); + EXPECT_TRUE(ports[i]["driver"].isString()); + EXPECT_TRUE(ports[i]["speed"].isString()); + } +} + +/* get owner, acquire and release */ +TEST_F(RpcTest, get_owner_acquire_release) { + Json::Value request; + Json::Value response; + + /* no user before acquring */ + create_request(request, "get_owner"); + request["params"]["port_id"] = 1; + send_request(request, response); + EXPECT_TRUE(response["result"] != Json::nullValue); + + EXPECT_TRUE(response["result"]["owner"] == "none"); + + /* soft acquire */ + create_request(request, "acquire"); + request["params"]["port_id"] = 1; + request["params"]["user"] = "itay"; + request["params"]["force"] = false; + + send_request(request, response); + EXPECT_TRUE(response["result"] != Json::nullValue); + + create_request(request, "get_owner"); + request["params"]["port_id"] = 1; + send_request(request, response); + EXPECT_TRUE(response["result"] != Json::nullValue); + + EXPECT_TRUE(response["result"]["owner"] == "itay"); + + /* hard acquire */ + create_request(request, "acquire"); + request["params"]["port_id"] = 1; + request["params"]["user"] = "moshe"; + request["params"]["force"] = false; + + send_request(request, response); + EXPECT_TRUE(response["result"] == Json::nullValue); + + request["params"]["force"] = true; + + send_request(request, response); + EXPECT_TRUE(response["result"] != Json::nullValue); + + string handler = response["result"].asString(); + + /* make sure */ + create_request(request, "get_owner"); + request["params"]["port_id"] = 1; + send_request(request, response); + EXPECT_TRUE(response["result"] != Json::nullValue); + + EXPECT_TRUE(response["result"]["owner"] == "moshe"); + + /* release */ + create_request(request, "release"); + request["params"]["port_id"] = 1; + request["params"]["handler"] = handler; + send_request(request, response); + + EXPECT_TRUE(response["result"] == "ACK"); +} + + +static void +create_simple_stream(Json::Value &obj) { + obj["mode"]["type"] = "continuous"; + obj["mode"]["pps"] = (rand() % 1000 + 1) * 0.99; + obj["isg"] = (rand() % 100 + 1) * 0.99;; + obj["enabled"] = true; + obj["self_start"] = true; + obj["next_stream_id"] = -1; + + obj["packet"]["meta"] = "dummy"; + + int packet_size = (rand() % 1500 + 1); + for (int i = 0; i < packet_size; i++) { + obj["packet"]["binary"][i] = (rand() % 0xff); + } + + obj["vm"] = Json::arrayValue; + obj["rx_stats"]["enabled"] = false; +} + +static bool +compare_streams(const Json::Value &s1, const Json::Value &s2) { + return s1 == s2; +} + +TEST_F(RpcTestOwned, add_remove_stream) { + Json::Value request; + Json::Value response; + + /* verify no such stream */ + create_request(request, "get_stream", 1, 1); + + request["params"]["stream_id"] = 5; + + send_request(request, response); - EXPECT_TRUE(reader.parse(resp_str, response, false)); EXPECT_EQ(response["jsonrpc"], "2.0"); EXPECT_EQ(response["id"], 1); + EXPECT_EQ(response["error"]["code"], -32000); + + /* add it */ + create_request(request, "add_stream", 1, 1); + request["params"]["stream_id"] = 5; + + Json::Value stream; + create_simple_stream(stream); + + request["params"]["stream"] = stream; + send_request(request, response); + + EXPECT_EQ(response["result"], "ACK"); + + /* get it */ + create_request(request, "get_stream", 1, 1); + + request["params"]["stream_id"] = 5; + + send_request(request, response); + + EXPECT_TRUE(compare_streams(stream, response["result"]["stream"])); + + // remove it + create_request(request, "remove_stream", 1, 1); + + request["params"]["stream_id"] = 5; + + send_request(request, response); + + EXPECT_EQ(response["result"], "ACK"); + + // should not be present anymore + send_request(request, response); EXPECT_EQ(response["error"]["code"], -32000); - // add it +} - string add_str = "{\"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"add_stream\", \"params\":" - "{\"port_id\":1, \"stream_id\":5, \"stream\":{" - "\"mode\": {\"type\":\"continuous\", \"pps\":3}," - "\"isg\":4.3, \"enabled\":true, \"self_start\":true," - "\"next_stream_id\":-1," - "\"packet\":{\"binary\":[4,1,255], \"meta\":\"dummy\"}," - "\"vm\":[]," - "\"rx_stats\":{\"enabled\":false}}}}"; - resp_str = send_msg(add_str); +TEST_F(RpcTestOwned, get_stream_id_list) { + Json::Value request; + Json::Value response; + + /* add stream 1 */ + create_request(request, "add_stream", 1); + request["params"]["port_id"] = 1; - EXPECT_TRUE(reader.parse(resp_str, response, false)); - EXPECT_EQ(response["jsonrpc"], "2.0"); - EXPECT_EQ(response["id"], 1); + Json::Value stream; + create_simple_stream(stream); + + request["params"]["stream"] = stream; + request["params"]["stream_id"] = 5; + send_request(request, response); EXPECT_EQ(response["result"], "ACK"); - resp_str = send_msg(lookup_str); + request["params"]["stream_id"] = 12; + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); - EXPECT_TRUE(reader.parse(resp_str, response, false)); - EXPECT_EQ(response["jsonrpc"], "2.0"); - EXPECT_EQ(response["id"], 1); + request["params"]["stream_id"] = 19; + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); - const Json::Value &stream = response["result"]["stream"]; - EXPECT_EQ(stream["enabled"], true); - EXPECT_EQ(stream["self_start"], true); + create_request(request, "get_stream_list"); + request["params"]["port_id"] = 1; + send_request(request, response); - EXPECT_EQ(stream["packet"]["binary"][0], 4); - EXPECT_EQ(stream["packet"]["binary"][1], 1); - EXPECT_EQ(stream["packet"]["binary"][2], 255); + EXPECT_TRUE(response["result"].isArray()); + vector<int> vec; + for (auto x : response["result"]) { + vec.push_back(x.asInt()); + } - EXPECT_EQ(stream["packet"]["meta"], "dummy"); - EXPECT_EQ(stream["next_stream_id"], -1); + sort(vec.begin(), vec.end()); - double delta = stream["isg"].asDouble() - 4.3; - EXPECT_TRUE(delta < 0.0001); + EXPECT_EQ(vec[0], 5); + EXPECT_EQ(vec[1], 12); + EXPECT_EQ(vec[2], 19); - EXPECT_EQ(stream["mode"]["type"], "continuous"); - EXPECT_EQ(stream["mode"]["pps"], 3); + create_request(request, "remove_all_streams"); + request["params"]["port_id"] = 1; + send_request(request, response); - // remove it + EXPECT_TRUE(response["result"] == "ACK"); - string remove_str = "{\"jsonrpc\":\"2.0\", \"id\":1, \"method\":\"remove_stream\", \"params\":{\"port_id\":1, \"stream_id\":5}}"; - resp_str = send_msg(remove_str); + /* make sure the lights are off ... */ + create_request(request, "get_stream_list"); + request["params"]["port_id"] = 1; + send_request(request, response); - EXPECT_TRUE(reader.parse(resp_str, response, false)); - EXPECT_EQ(response["jsonrpc"], "2.0"); - EXPECT_EQ(response["id"], 1); + EXPECT_TRUE(response["result"].isArray()); + EXPECT_TRUE(response["result"].size() == 0); +} + + +TEST_F(RpcTestOwned, start_stop_traffic) { + Json::Value request; + Json::Value response; + /* add stream #1 */ + create_request(request, "add_stream", 1, 1); + request["params"]["stream_id"] = 5; + + Json::Value stream; + create_simple_stream(stream); + + request["params"]["stream"] = stream; + + send_request(request, response); EXPECT_EQ(response["result"], "ACK"); - resp_str = send_msg(remove_str); + /* add stream #1 */ + create_request(request, "add_stream", 1, 3); + request["params"]["stream_id"] = 12; + request["params"]["stream"] = stream; + + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); - // should not be present anymore + /* start port 1 */ + create_request(request, "start_traffic", 1, 1); + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); - EXPECT_TRUE(reader.parse(resp_str, response, false)); - EXPECT_EQ(response["jsonrpc"], "2.0"); - EXPECT_EQ(response["id"], 1); + /* start port 3 */ + create_request(request, "start_traffic", 1, 3); + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); + + /* start not configured port */ + create_request(request, "start_traffic", 1, 2); + send_request(request, response); EXPECT_EQ(response["error"]["code"], -32000); -} + /* stop port 1 */ + create_request(request, "stop_traffic", 1, 1); + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); + /* stop port 3 */ + create_request(request, "stop_traffic", 1, 3); + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); + + /* start 1 again */ + create_request(request, "start_traffic", 1, 1); + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); + /* start 1 twice (error) */ + create_request(request, "start_traffic", 1, 1); + send_request(request, response); + EXPECT_EQ(response["error"]["code"], -32000); + + /* make sure you cannot release while traffic is active */ + create_request(request, "release", 1, 1); + send_request(request, response); + EXPECT_EQ(response["error"]["code"], -32000); + + /* stop traffic on port #1 */ + create_request(request, "stop_traffic",1 ,1); + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); + + /* release */ + create_request(request, "release", 1, 1); + send_request(request, response); + EXPECT_EQ(response["result"], "ACK"); +} |