diff options
Diffstat (limited to 'scripts/automation/trex_control_plane/console/trex_console.py')
-rwxr-xr-x[-rw-r--r--] | scripts/automation/trex_control_plane/console/trex_console.py | 248 |
1 files changed, 240 insertions, 8 deletions
diff --git a/scripts/automation/trex_control_plane/console/trex_console.py b/scripts/automation/trex_control_plane/console/trex_console.py index 3aeab901..a9ac040b 100644..100755 --- a/scripts/automation/trex_control_plane/console/trex_console.py +++ b/scripts/automation/trex_control_plane/console/trex_console.py @@ -1,18 +1,124 @@ #!/usr/bin/env python -# -*- coding: utf-8 -*- +# -*- coding: utf-8 -*- + +""" +Dan Klein, 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. +""" + import cmd import json import ast import argparse import random import string - +import os import sys +import tty, termios import trex_root_path +from common.trex_streams import * + from client_utils.jsonrpc_client import TrexStatelessClient import trex_status +from collections import namedtuple + +LoadedStreamList = namedtuple('LoadedStreamList', ['loaded', 'compiled']) + +# + +def readch (choices = []): + + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + try: + tty.setraw(sys.stdin.fileno()) + while True: + ch = sys.stdin.read(1) + if (ord(ch) == 3) or (ord(ch) == 4): + return None + if ch in choices: + return ch + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + + return None + +class YesNoMenu(object): + def __init__ (self, caption): + self.caption = caption + + def show (self): + print "{0}".format(self.caption) + sys.stdout.write("[Y/y/N/n] : ") + ch = readch(choices = ['y', 'Y', 'n', 'N']) + if ch == None: + return None + + print "\n" + if ch == 'y' or ch == 'Y': + return True + else: + return False + +# multi level cmd menu +class CmdMenu(object): + def __init__ (self): + self.menus = [] + + + def add_menu (self, caption, options): + menu = {} + menu['caption'] = caption + menu['options'] = options + self.menus.append(menu) + + def show (self): + cur_level = 0 + print "\n" + + selected_path = [] + for menu in self.menus: + # show all the options + print "{0}\n".format(menu['caption']) + for i, option in enumerate(menu['options']): + print "{0}. {1}".format(i + 1, option) + + #print "\nPlease select an option: " + choices = range(0, len(menu['options'])) + choices = [ chr(x + 48) for x in choices] + + print "" + ch = readch(choices) + print "" + + if ch == None: + return None + + selected_path.append(int(ch) - 1) + + return selected_path + + +class AddStreamMenu(CmdMenu): + def __init__ (self): + super(AddStreamMenu, self).__init__() + self.add_menu('Please select type of stream', ['a', 'b', 'c']) + self.add_menu('Please select ISG', ['d', 'e', 'f']) + +# main console object class TrexConsole(cmd.Cmd): """Trex Console""" @@ -29,6 +135,8 @@ class TrexConsole(cmd.Cmd): self.verbose = False self.postcmd(False, "") + + self.user_streams = {} # a cool hack - i stole this function and added space @@ -108,6 +216,13 @@ class TrexConsole(cmd.Cmd): def do_acquire (self, line, force = False): '''Acquire ports\n''' + # make sure that the user wants to acquire all + if line == "": + ask = YesNoMenu('Do you want to acquire all ports ? ') + rc = ask.show() + if rc == False: + return + port_list = self.parse_ports_from_line(line) if not port_list: return @@ -312,25 +427,142 @@ class TrexConsole(cmd.Cmd): print "{:<30} {:<30}".format(cmd + " - ", help) + def do_load_stream_list(self, line): + '''Loads a YAML stream list serialization into user console \n''' + args = line.split() + if args >= 2: + name = args[0] + yaml_path = args[1] + try: + multiplier = args[2] + except IndexError: + multiplier = 1 + stream_list = CStreamList() + loaded_obj = stream_list.load_yaml(yaml_path, multiplier) + # print self.rpc_client.pretty_json(json.dumps(loaded_obj)) + if name in self.user_streams: + print "Picked name already exist. Please pick another name." + else: + try: + compiled_streams = stream_list.compile_streams() + self.user_streams[name] = LoadedStreamList(loaded_obj, + [StreamPack(v.stream_id, v.stream.dump_compiled()) + for k, v in compiled_streams.items()]) + + print "Stream '{0}' loaded successfully".format(name) + except Exception as e: + raise + return + else: + print "please provide load name and YAML path, separated by space.\n" \ + "Optionally, you may provide a third argument to specify multiplier." + + @staticmethod + def tree_autocomplete(text): + dir = os.path.dirname(text) + if dir: + path = dir + else: + path = "." + start_string = os.path.basename(text) + return [x + for x in os.listdir(path) + if x.startswith(start_string)] + + + def complete_load_stream_list(self, text, line, begidx, endidx): + arg_num = len(line.split()) - 1 + if arg_num == 2: + return TrexConsole.tree_autocomplete(line.split()[-1]) + else: + return [text] + + def do_show_stream_list(self, line): + '''Shows the loaded stream list named [name] \n''' + args = line.split() + if args: + list_name = args[0] + try: + stream = self.user_streams[list_name] + if len(args) >= 2 and args[1] == "full": + print self.rpc_client.pretty_json(json.dumps(stream.compiled)) + else: + print self.rpc_client.pretty_json(json.dumps(stream.loaded)) + except KeyError as e: + print "Unknown stream list name provided" + else: + print "\nAvailable stream lists:\n{0}".format(', '.join([x + for x in self.user_streams.keys()])) + + def complete_show_stream_list(self, text, line, begidx, endidx): + return [x + for x in self.user_streams.keys() + if x.startswith(text)] + + def do_attach(self, line): + args = line.split() + if len(args) >= 1: + try: + stream_list = self.user_streams[args[0]] + port_list = self.parse_ports_from_line(' '.join(args[1:])) + owned = set(self.rpc_client.get_owned_ports()) + if set(port_list).issubset(owned): + rc, resp_list = self.rpc_client.add_stream(port_list, stream_list.compiled) + if not rc: + print "\n*** " + resp_list + "\n" + return + else: + print "Not all desired ports are aquired.\n" \ + "Acquired ports are: {acq}\n" \ + "Requested ports: {req}\n" \ + "Missing ports: {miss}".format(acq=list(owned), + req=port_list, + miss=list(set(port_list).difference(owned))) + except KeyError as e: + cause = e.args[0] + print "Provided stream list name '{0}' doesn't exists.".format(cause) + else: + print "Please provide list name and ports to attach to, or leave empty to attach to all ports." + - # do - #def do_snapshot (self, line): - #for key, value in self.rpc_client.snapshot()[1]['streams'].iteritems(): - #print str(key) + " " + str(value) + + + + + + + # adds a very simple stream + def do_add_simple_stream (self, line): + if line == "": + add_stream = AddStreamMenu() + add_stream.show() + return + + params = line.split() + port_id = int(params[0]) + stream_id = int(params[1]) + + packet = [0xFF,0xFF,0xFF] + rc, msg = self.rpc_client.add_stream(port_id = port_id, stream_id = stream_id, isg = 1.1, next_stream_id = -1, packet = packet) + if rc: + print "\nServer Response:\n\n" + self.rpc_client.pretty_json(json.dumps(msg)) + "\n" + else: + print "\n*** " + msg + "\n" + # aliasing do_exit = do_EOF = do_q = do_quit def setParserOptions (): parser = argparse.ArgumentParser(prog="trex_console.py") - parser.add_argument("-s", "--server", help = "T-Rex Server [default is localhost]", + parser.add_argument("-s", "--server", help = "TRex Server [default is localhost]", default = "localhost", type = str) - parser.add_argument("-p", "--port", help = "T-Rex Server Port [default is 5050]\n", + parser.add_argument("-p", "--port", help = "TRex Server Port [default is 5050]\n", default = 5050, type = int) |