summaryrefslogtreecommitdiffstats
path: root/scripts/automation
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-05-03 14:57:34 +0300
committerimarom <imarom@cisco.com>2016-05-09 16:48:14 +0300
commit8691f4019dc2123c1aa7413cf3666138756c2f66 (patch)
tree4b09f137d266471b51a4e5270e8d113806c97c93 /scripts/automation
parent64847bb6d182c73f7489a821ea5724687dab1bc1 (diff)
first remote PCAP push - draft
Diffstat (limited to 'scripts/automation')
-rwxr-xr-xscripts/automation/trex_control_plane/stl/console/trex_console.py6
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py81
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py23
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py7
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py6
5 files changed, 114 insertions, 9 deletions
diff --git a/scripts/automation/trex_control_plane/stl/console/trex_console.py b/scripts/automation/trex_control_plane/stl/console/trex_console.py
index f8161dcb..ab70d357 100755
--- a/scripts/automation/trex_control_plane/stl/console/trex_console.py
+++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py
@@ -319,9 +319,13 @@ class TRexConsole(TRexGeneralCmd):
return self.do_history(line)
def do_push (self, line):
- '''Push a PCAP file\n'''
+ '''Push a local PCAP file\n'''
return self.stateless_client.push_line(line)
+ #def do_push_remote (self, line):
+ # '''Push a remote accessible PCAP file\n'''
+ # return self.stateless_client.push_remote_line(line)
+
def help_push (self):
return self.do_push("-h")
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py
index 862a9979..c7d59690 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py
@@ -313,6 +313,10 @@ class EventsHandler(object):
if session_id != self.client.session_id:
self.__async_event_port_released(port_id)
+ elif (type == 7):
+ port_id = int(data['port_id'])
+ ev = "port {0} job failed".format(port_id)
+ show_event = True
# server stopped
elif (type == 100):
@@ -711,6 +715,17 @@ class STLClient(object):
return rc
+ def __push_remote (self, pcap_filename, port_id_list, ipg_usec, speedup, count):
+
+ port_id_list = self.__ports(port_id_list)
+ rc = RC()
+
+ for port_id in port_id_list:
+ rc.add(self.ports[port_id].push_remote(pcap_filename, ipg_usec, speedup, count))
+
+ return rc
+
+
def __validate (self, port_id_list = None):
port_id_list = self.__ports(port_id_list)
@@ -1852,6 +1867,49 @@ class STLClient(object):
@__api_check(True)
+ def push_remote (self, pcap_filename, ports = None, ipg_usec = None, speedup = 1.0, count = 1):
+ """
+ Push a remote reachable PCAP file
+ the path must be fullpath accessible to the server
+
+ :parameters:
+ pcap_filename : str
+ PCAP file name in full path and accessible to the server
+
+ ports : list
+ Ports on which to execute the command
+
+ ipg_usec : float
+ Inter-packet gap in microseconds
+
+ speedup : float
+ A factor to adjust IPG. effectively IPG = IPG / speedup
+
+ count: int
+ How many times to transmit the cap
+
+
+ :raises:
+ + :exc:`STLError`
+
+ """
+ ports = ports if ports is not None else self.get_acquired_ports()
+ ports = self._validate_port_list(ports)
+
+ validate_type('pcap_filename', pcap_filename, str)
+ validate_type('ipg_usec', ipg_usec, (float, int, type(None)))
+ validate_type('speedup', speedup, float)
+ validate_type('count', count, int)
+
+ self.logger.pre_cmd("Pushing remote pcap on port(s) {0}:".format(ports))
+ rc = self.__push_remote(pcap_filename, ports, ipg_usec, speedup, count)
+ self.logger.post_cmd(rc)
+
+ if not rc:
+ raise STLError(rc)
+
+
+ @__api_check(True)
def validate (self, ports = None, mult = "1", duration = "-1", total = False):
"""
Validate port(s) configuration
@@ -2519,6 +2577,7 @@ class STLClient(object):
"push",
self.push_line.__doc__,
parsing_opts.FILE_PATH,
+ parsing_opts.REMOTE_FILE,
parsing_opts.PORT_LIST_WITH_ALL,
parsing_opts.COUNT,
parsing_opts.DURATION,
@@ -2541,15 +2600,23 @@ class STLClient(object):
self.stop(active_ports)
# pcap injection removes all previous streams from the ports
- self.remove_all_streams(ports = opts.ports)
+ if opts.remote:
+ self.push_remote(opts.file[0],
+ ports = opts.ports,
+ ipg_usec = opts.ipg_usec,
+ speedup = opts.speedup,
+ count = opts.count)
+
+ else:
+ self.remove_all_streams(ports = opts.ports)
- profile = STLProfile.load_pcap(opts.file[0],
- opts.ipg_usec,
- opts.speedup,
- opts.count)
+ profile = STLProfile.load_pcap(opts.file[0],
+ opts.ipg_usec,
+ opts.speedup,
+ opts.count)
- id_list = self.add_streams(profile.get_streams(), opts.ports)
- self.start(ports = opts.ports, duration = opts.duration, force = opts.force)
+ id_list = self.add_streams(profile.get_streams(), opts.ports)
+ self.start(ports = opts.ports, duration = opts.duration, force = opts.force)
return True
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py
index e8f89b27..986cb3c6 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py
@@ -148,6 +148,7 @@ class Port(object):
return self.owner
def sync(self):
+
params = {"port_id": self.port_id}
rc = self.transmit("get_port_status", params)
@@ -553,6 +554,28 @@ class Port(object):
return self.ok()
+ def push_remote (self, pcap_filename, ipg_usec, speedup, count):
+ if not self.is_acquired():
+ return self.err("port is not owned")
+
+ if (self.state == self.STATE_DOWN):
+ return self.err("port is down")
+
+ params = {"handler": self.handler,
+ "port_id": self.port_id,
+ "pcap_filename": pcap_filename,
+ "ipg_usec": ipg_usec if ipg_usec is not None else -1,
+ "speedup": speedup,
+ "count": count}
+
+ rc = self.transmit("push_remote", params)
+ if rc.bad():
+ return self.err(rc.err())
+
+ self.state = self.STATE_TX
+ return self.ok()
+
+
def get_profile (self):
return self.profile
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py
index 165942d8..6ee587c3 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py
@@ -7,6 +7,7 @@ from .trex_stl_packet_builder_scapy import STLPktBuilder, Ether, IP, UDP, TCP, R
from collections import OrderedDict, namedtuple
from scapy.utils import ltoa
+from scapy.error import Scapy_Exception
import random
import yaml
import base64
@@ -967,7 +968,11 @@ class STLProfile(object):
streams = []
last_ts_usec = 0
- pkts = RawPcapReader(pcap_file).read_all()
+ try:
+ pkts = RawPcapReader(pcap_file).read_all()
+ except Scapy_Exception as e:
+ raise STLError("failed to open PCAP file '{0}'".format(pcap_file))
+
for i, (cap, meta) in enumerate(pkts, start = 1):
# IPG - if not provided, take from cap
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
index ad46625b..98e3ca6a 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py
@@ -32,6 +32,7 @@ PROMISCUOUS = 19
NO_PROMISCUOUS = 20
PROMISCUOUS_SWITCH = 21
TUNABLES = 22
+REMOTE_FILE = 23
GLOBAL_STATS = 50
PORT_STATS = 51
@@ -290,6 +291,11 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'default': False,
'help': "Set if you want to stop active ports before appyling command."}),
+ REMOTE_FILE: ArgumentPack(['-r', '--remote'],
+ {"action": "store_true",
+ 'default': False,
+ 'help': "file path should be interpeted by the server (remote file)"}),
+
FILE_PATH: ArgumentPack(['-f'],
{'metavar': 'FILE',
'dest': 'file',