draft
authorimarom <[email protected]>
Wed, 19 Aug 2015 10:12:10 +0000 (13:12 +0300)
committerimarom <[email protected]>
Wed, 19 Aug 2015 10:12:10 +0000 (13:12 +0300)
.gitignore
linux/ws_main.py
src/console/trex_console.py
src/console/trex_rpc_client.py
src/console/trex_status.py
src/main.cpp
src/rpc-server/src/trex_rpc_server_mock.cpp [new file with mode: 0644]

index 2666873..71cce64 100644 (file)
@@ -11,6 +11,7 @@ linux_dpdk*
 linux*
 scripts/_t-rex-*
 scripts/bp-sim-*
+scripts/mock-*
 
 *.pyc
 
index b6e4fcc..37051eb 100755 (executable)
@@ -111,6 +111,7 @@ main_src = SrcGroup(dir='src',
              'msg_manager.cpp',
              'gtest/tuple_gen_test.cpp',
              'gtest/nat_test.cpp',
+             'gtest/rpc_test.cpp',
 
              'pal/linux/pal_utl.cpp',
              'pal/linux/mbuf.cpp'
@@ -138,11 +139,35 @@ net_src = SrcGroup(dir='src/common/Network/Packet',
            'MacAddress.cpp',
            'VLANHeader.cpp']);
 
+# RPC code
+rpc_server_src = SrcGroup(dir='src/rpc-server/src',
+                          src_list=[
+                              'trex_rpc_server.cpp',
+                              'trex_rpc_req_resp_server.cpp',
+                              'trex_rpc_jsonrpc_v2_parser.cpp',
+                              'trex_rpc_cmds_table.cpp',
+
+                              'commands/trex_rpc_cmd_test.cpp',
+                              'commands/trex_rpc_cmd_general.cpp',
+
+                          ])
+
+# RPC mock server (test)
+rpc_server_mock_src = SrcGroup(dir='src/rpc-server/src',
+                          src_list=[
+                              'trex_rpc_server_mock.cpp'
+                          ])
+
 # JSON package
 json_src = SrcGroup(dir='external_libs/json',
-        src_list=[
-            'jsoncpp.cpp'
-           ])
+                    src_list=[
+                        'jsoncpp.cpp'
+                        ])
+
+rpc_server_mock = SrcGroups([rpc_server_src,
+                            rpc_server_mock_src,
+                            json_src
+                            ])
 
 yaml_src = SrcGroup(dir='yaml-cpp/src/',
         src_list=[
@@ -178,6 +203,7 @@ bp =SrcGroups([
                 main_src, 
                 cmn_src ,
                 net_src ,
+                rpc_server_src,
                 yaml_src,
                 json_src
                 ]);
@@ -196,7 +222,10 @@ cxxflags_base =['-DWIN_UCODE_SIM',
 
 
 includes_path =''' ../src/pal/linux/
+                   ../src/zmq/include/
                    ../src/
+                   ../src/rpc-server/include
+                   ../external_libs/json/
                    ../yaml-cpp/include/
               ''';
 
@@ -212,10 +241,12 @@ PLATFORM_32 = "32"
 
 class build_option:
 
-    def __init__(self,platform,debug_mode,is_pie):
+    def __init__(self, name, src, platform, debug_mode, is_pie):
       self.mode     = debug_mode;   ##debug,release
       self.platform = platform; #['32','64'] 
       self.is_pie = is_pie
+      self.name = name
+      self.src = src
 
     def __str__(self):
        s=self.mode+","+self.platform;
@@ -283,11 +314,14 @@ class build_option:
         return result;
 
     def get_target (self):
-        return self.update_executable_name("bp-sim");
+        return self.update_executable_name(self.name);
 
     def get_flags (self):
         return self.cxxcomp_flags(cxxflags_base);
 
+    def get_src (self):
+        return self.src.file_list(top)
+
     def get_link_flags(self):
         # add here basic flags
         base_flags = ['-lpthread'];
@@ -307,25 +341,28 @@ class build_option:
 
         return base_flags;
 
-    def get_exe (self,full_path = True):
-        return self.toExe(self.get_target(),full_path);
-
 
 build_types = [
-               build_option(debug_mode= DEBUG_, platform = PLATFORM_32, is_pie = False),
-               build_option(debug_mode= DEBUG_, platform = PLATFORM_64, is_pie = False),
-               build_option(debug_mode= RELEASE_,platform = PLATFORM_32, is_pie = False),
-               build_option(debug_mode= RELEASE_,platform = PLATFORM_64, is_pie = False),
+               build_option(name = "bp-sim", src = bp, debug_mode= DEBUG_, platform = PLATFORM_32, is_pie = False),
+               build_option(name = "bp-sim", src = bp, debug_mode= DEBUG_, platform = PLATFORM_64, is_pie = False),
+               build_option(name = "bp-sim", src = bp, debug_mode= RELEASE_,platform = PLATFORM_32, is_pie = False),
+               build_option(name = "bp-sim", src = bp, debug_mode= RELEASE_,platform = PLATFORM_64, is_pie = False),
+
+               build_option(name = "mock-rpc-server", src = rpc_server_mock, debug_mode= DEBUG_,platform = PLATFORM_64, is_pie = False),
               ]
 
 
 
 def build_prog (bld, build_obj):
+    zmq_lib_path='src/zmq/'
+    bld.read_shlib( name='zmq' , paths=[top + zmq_lib_path] )
+
     bld.program(features='cxx cxxprogram', 
                 includes =includes_path,
                 cxxflags =build_obj.get_flags(),
                 linkflags = build_obj.get_link_flags(),
-                source = bp.file_list(top),
+                source = build_obj.get_src(),
+                use = ['zmq'],
                 rpath  = bld.env.RPATH,
                 target = build_obj.get_target())
 
@@ -336,15 +373,19 @@ def build_type(bld,build_obj):
 
 def post_build(bld):
     print "copy objects"
+
     exec_p ="../scripts/"
+
     for obj in build_types:
         install_single_system(bld, exec_p, obj);
 
 def build(bld):
+
     bld.add_post_fun(post_build);
     for obj in build_types:
         build_type(bld,obj);
 
+    
 
 def build_info(bld):
     pass;
index 15022e0..584089a 100755 (executable)
@@ -12,10 +12,14 @@ class TrexConsole(cmd.Cmd):
     def __init__(self, rpc_client):
         cmd.Cmd.__init__(self)
         self.prompt = "TRex > "
-        self.intro  = "\n-=TRex Console V1.0=-\n" 
+
+        self.intro  = "\n-=TRex Console V1.0=-\n"
+        self.intro += "\nType 'help' or '?' for supported actions\n" 
+
         self.rpc_client = rpc_client
         self.verbose = False
         
+        # before starting query the RPC server and add the methods
         rc, msg = self.rpc_client.query_rpc_server()
 
         if rc:
@@ -29,20 +33,22 @@ class TrexConsole(cmd.Cmd):
 
     # set verbose on / off
     def do_verbose (self, line):
-        '''shows or set verbose mode\nusage: verbose [on/off]\n'''
+        '''\nshows or set verbose mode\nusage: verbose [on/off]\n'''
         if line == "":
-            print "verbose is " + ("on" if self.verbose else "off")
+            print "\nverbose is " + ("on\n" if self.verbose else "off\n")
+
         elif line == "on":
             self.verbose = True
             self.rpc_client.set_verbose(True)
-            print "verbose set to on\n"
+            print "\nverbose set to on\n"
 
         elif line == "off":
             self.verbose = False
             self.rpc_client.set_verbose(False)
-            print "verbose set to off\n"
+            print "\nverbose set to off\n"
+
         else:
-            print "please specify 'on' or 'off'\n"
+            print "\nplease specify 'on' or 'off'\n"
 
     # query the server for registered commands
     def do_query_server(self, line):
@@ -51,11 +57,11 @@ class TrexConsole(cmd.Cmd):
         if not rc:
             print "\n*** Failed to query RPC server: " + str(msg)
 
-        print "RPC server supports the following commands: \n\n" + msg
+        print "\nRPC server supports the following commands: \n\n" + msg
 
     def do_ping (self, line):
-        '''pings the RPC server\n'''
-        print "Pinging RPC server"
+        '''\npings the RPC server\n'''
+        print "\n-> Pinging RPC server"
 
         rc, msg = self.rpc_client.ping_rpc_server()
         if rc:
@@ -64,9 +70,9 @@ class TrexConsole(cmd.Cmd):
             print "[FAILED]\n"
 
     def do_rpc (self, line):
-        '''Launches a RPC on the server\n'''
+        '''\nLaunches a RPC on the server\n'''
         if line == "":
-            print "Please provide method name\n"
+            print "\nUsage: [method name] [param 1] ...\n"
             return
 
         rc, msg = self.rpc_client.invoke_rpc_method(line)
@@ -81,7 +87,9 @@ class TrexConsole(cmd.Cmd):
         return [x for x in self.supported_rpc if x.startswith(text)]
 
     def do_status (self, line):
-        '''Shows a graphical console\n'''
+        '''\nShows a graphical console\n'''
+
+        self.do_verbose('off')
         trex_status.show_trex_status(self.rpc_client)
 
     def do_quit(self, line):
@@ -89,10 +97,10 @@ class TrexConsole(cmd.Cmd):
         return True
 
     def default(self, line):
-        print "'{0}' is an unrecognized command\n".format(line)
+        print "'{0}' is an unrecognized command. type 'help' or '?' for a list\n".format(line)
 
     # aliasing
-    do_EOF = do_q = do_quit 
+    do_exit = do_EOF = do_q = do_quit
 
 def main ():
     # RPC client
index 4562cf2..fe8f69a 100644 (file)
@@ -39,7 +39,7 @@ class RpcClient():
         msg = self.create_jsonrpc_v2(method_name, params, id = 1)\r
 \r
         if self.verbose:\r
-            print "\nSending Request To Server: " + str(msg) + "\n"\r
+            print "\n[verbose] Sending Request To Server: " + str(msg) + "\n"\r
 \r
         if block:\r
             self.socket.send(msg)\r
@@ -67,7 +67,7 @@ class RpcClient():
             return False, "Failed To Get Server Response"\r
 \r
         if self.verbose:\r
-            print "Server Response: " + str(response) + "\n"\r
+            print "[verbose] Server Response: " + str(response)\r
 \r
         # decode\r
         response_json = json.loads(response)\r
index 20d7053..8ee669b 100755 (executable)
@@ -85,6 +85,7 @@ class TrexStatus():
 
          return win, panel1
 
+    # static info panel
     def update_info (self):
         if self.server_status == None:
             return
@@ -99,106 +100,12 @@ class TrexStatus():
                                                                     self.server_status["general"]["build_date"] + " @ " + self.server_status["general"]["build_time"] + " by " + self.server_status["general"]["version_user"]))
 
         self.info_panel.getwin().addstr(6, 2, "{:<30} {:30}".format("Server Uptime:", self.server_status["general"]["uptime"]))
-        #self.ft_panel.clear()
-
-        #ft_section_y  = 3
-        #self.ft_panel.getwin().addstr(ft_section_y, 2,"General Info:", curses.A_UNDERLINE)
-
-        #self.ft_panel.getwin().addstr(ft_section_y, 2, "{:<30} {:<30,}".format("Total Flows Opened:", ft_stats["total-opened-flows"]))
-        #ft_section_y = ft_section_y + 1
-        #self.ft_panel.getwin().addstr(ft_section_y, 2, "{:<30} {:<30,}".format("Total Flows Closed:", ft_stats["total-closed-flows"]))
-        #ft_section_y = ft_section_y + 1
-        #self.ft_panel.getwin().addstr(ft_section_y, 2, "{:<30} {:<30,}".format("Current Active Flows:", ft_stats["active-flows"]))
-        #ft_section_y = ft_section_y + 1
-        #self.ft_panel.getwin().addstr(ft_section_y, 2, "{:<30} {:<30,}".format("Flow Allocation Errors:", ft_stats["allocation_err"]))
 
+    # general stats
     def update_general (self, gen_stats):
+        pass
 
-        if not gen_stats:
-            return
-
-        transport_info_section_y  = 3
-        general_info_section_y    = int(self.cls_panel.h * 0.5)
-
-        self.general_panel.clear()
-
-        # transport layer info
-        self.general_panel.getwin().addstr(transport_info_section_y, 2, "{:<30} {:^10} {:^5} {:^10}".format("Total Tx Rate:", 
-                                                                                                            float_to_human_readable(gen_stats["total-rx-bps"]),
-                                                                                                            "/",
-                                                                                                            float_to_human_readable(gen_stats["total-rx-pps"], suffix = "pps")))
-        transport_info_section_y += 2
-
-
-        self.general_panel.getwin().addstr(transport_info_section_y, 2, "{:<30} {:^6.2f} %".format("DP Core Util.:", gen_stats["cpu-util"]));
-
-        transport_info_section_y += 2
-
-        for i in range(1, 3):
-            self.general_panel.getwin().addstr(transport_info_section_y, 2, "{:<30} {:^10} {:^5} {:^10}".format("Port {0} Rx:".format(i), 
-                                                                                                          float_to_human_readable(gen_stats["port " + str(i)]["total-rx-bps"]),
-                                                                                                          "/",
-                                                                                                          float_to_human_readable(gen_stats["port " + str(i)]["total-rx-pps"], suffix = "pps")))
-            transport_info_section_y += 1
-
-
-        self.general_panel.getwin().addstr(general_info_section_y, 2,"General Info:", curses.A_UNDERLINE)
-        general_info_section_y = general_info_section_y + 2
-
-        self.general_panel.getwin().addstr(general_info_section_y, 2, "{:<30} {:<30}".format("VNBAR Main Process PID:", os.getppid()))
-        general_info_section_y = general_info_section_y + 1
-        self.general_panel.getwin().addstr(general_info_section_y, 2, "{:<30} {:<30}".format("ZMQ client online at:", vnbar_ipc.VnbarIpc.get_zmq_transport_name()))
-        
-
-    # v2
-    def update_cls (self, pd_stats):
-        if not pd_stats:
-            return
-
-        self.cls_panel.clear()
-
-        section_start = 3
-        section_size  = (self.cls_panel.h / 2) - 5
-
-        for port_name, pd in sorted(pd_stats.iteritems()):
-            if pd == None:
-                continue
-
-            # sort by bandwidth
-            pd = collections.OrderedDict(sorted(pd.items(), key=operator.itemgetter(1), reverse = True))
-
-            # restart the line index
-            line_index = 0
-
-            # headline
-            self.cls_panel.getwin().addstr(section_start + line_index, 2, "{0}:".format(port_name), curses.A_BOLD | curses.A_UNDERLINE)
-            line_index += 1
-
-            cls_str = "{:^45} {:^20} {:^20} {:^20}".format("Protocol Name", "Byte Count", "Packet Count", "B/W Perc.")
-            self.cls_panel.getwin().addstr(section_start + line_index, 2, cls_str)
-            line_index += 2
-
-            # protocols
-            proto_index = 0
-            proto_count = len(pd)
-
-            total_bandwidth = sum([i['bytes'] for i in pd.values()])
-
-            for proto_name, cnts in pd.iteritems():
-                proto_str = "{:<45} {:^20,} {:^20,} {:^20}".format(proto_name, cnts['bytes'], cnts['pkts'], percentage(cnts['bytes'], total_bandwidth) )
-                proto_index = proto_index + 1
-
-                if line_index > section_size:
-                    self.cls_panel.getwin().addstr(section_start + line_index, 2, "<...{0} More...>".format(proto_count - proto_index), (curses.A_DIM if ((line_index % 2) == 0) else curses.A_BOLD))
-                    break
-
-                self.cls_panel.getwin().addstr(section_start + line_index, 2, proto_str, (curses.A_DIM if ((line_index % 2) == 0) else curses.A_BOLD))
-
-                line_index += 1
-
-            section_start = section_start + section_size + 3
-   
-
+    # control panel
     def update_control (self):
         self.control_panel.clear()
 
@@ -214,17 +121,7 @@ class TrexStatus():
             self.control_panel.getwin().addstr(index, 2, l)
             index += 1
 
-    def run (self):
-        try:
-            curses.curs_set(0)
-        except:
-            pass
-
-        curses.use_default_colors()        
-        self.stdscr.nodelay(1)
-        curses.nonl()
-        curses.noecho()
-
+    def generate_layout (self):
         self.max_y = self.stdscr.getmaxyx()[0]
         self.max_x = self.stdscr.getmaxyx()[1]
 
@@ -239,32 +136,54 @@ class TrexStatus():
 
         panel.update_panels(); self.stdscr.refresh()
 
+    def wait_for_key_input (self):
+        ch = self.stdscr.getch()
+
+        if (ch != curses.ERR):
+            # stop/start status
+            if (ch == ord('f')):
+                self.update_active = not self.update_active
+                self.add_log_event("Update continued" if self.update_active else "Update stopped")
+
+            elif (ch == ord('p')):
+                self.add_log_event("Pinging RPC server")
+                rc, msg = self.rpc_client.ping_rpc_server()
+                if rc:
+                    self.add_log_event("Server replied: '{0}'".format(msg))
+                else:
+                    self.add_log_event("Failed to get reply")
+
+            # c - clear stats
+            elif (ch == ord('c')):
+                self.add_log_event("Statistics cleared")
+
+            elif (ch == ord('q')):
+                return False
+            else:
+                self.add_log_event("Unknown key pressed {0}".format("'" + chr(ch) + "'" if chr(ch).isalpha() else ""))
+
+        return True
+
+    # main run entry point
+    def run (self):
+        try:
+            curses.curs_set(0)
+        except:
+            pass
+
+        curses.use_default_colors()        
+        self.stdscr.nodelay(1)
+        curses.nonl()
+        curses.noecho()
+     
+        self.generate_layout()
+
         self.update_active = True
         while (True):
-            ch = self.stdscr.getch()
-
-            if (ch != curses.ERR):
-                # stop/start status
-                if (ch == ord('f')):
-                    self.update_active = not self.update_active
-                    self.add_log_event("Update continued" if self.update_active else "Update stopped")
-
-                elif (ch == ord('p')):
-                    self.add_log_event("Pinging RPC server")
-                    rc, msg = self.rpc_client.ping_rpc_server()
-                    if rc:
-                        self.add_log_event("Server replied: '{0}'".format(msg))
-                    else:
-                        self.add_log_event("Failed to get reply")
-                    
-                # c - clear stats
-                elif (ch == ord('c')):
-                    self.add_log_event("Statistics cleared")
-
-                elif (ch == ord('q')):
-                    break
-                else:
-                    self.add_log_event("Unknown key pressed {0}".format("'" + chr(ch) + "'" if chr(ch).isalpha() else ""))
+
+            rc = self.wait_for_key_input()
+            if not rc:
+                break
 
             self.update_control()
             self.update_info()
index e3176be..ddcf81e 100755 (executable)
@@ -32,11 +32,11 @@ limitations under the License.
  * (improved stub) 
  * 
  */
-extern "C" char * get_build_date(void){ 
+extern "C" const char * get_build_date(void){ 
     return (__DATE__);
 }      
  
-extern "C" char * get_build_time(void){ 
+extern "C" const char * get_build_time(void){ 
     return (__TIME__ );
 } 
 
diff --git a/src/rpc-server/src/trex_rpc_server_mock.cpp b/src/rpc-server/src/trex_rpc_server_mock.cpp
new file mode 100644 (file)
index 0000000..3c63f74
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ Itay Marom
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include <trex_rpc_server_api.h>
+#include <iostream>
+#include <unistd.h>
+
+using namespace std;
+
+/**
+ * on simulation this is not rebuild every version 
+ * (improved stub) 
+ * 
+ */
+extern "C" const char * get_build_date(void){ 
+    return (__DATE__);
+}      
+extern "C" const char * get_build_time(void){ 
+    return (__TIME__ );
+} 
+
+int main() {
+    cout << "\n-= Starting RPC Server Mock =-\n\n";
+    cout << "Listening on tcp://localhost:5050 [ZMQ]\n\n";
+
+    TrexRpcServerConfig rpc_cfg(TrexRpcServerConfig::RPC_PROT_TCP, 5050);
+    TrexRpcServer rpc(rpc_cfg);
+
+    /* init the RPC server */
+    rpc.start();
+
+    cout << "Server Started\n\n";
+
+    while (true) {
+        sleep(1);
+    }
+
+    rpc.stop();
+
+
+}