Usage Examples¶
Full-featured interactive shell¶
The client_interactive_example.py extends and uses the Cmd built in python class to create a Full-featured shell using which one can interact with TRex server and get instant results.
The help menu of this application is:
usage: client_interactive_example [options]
Run TRex client API demos and scenarios.
optional arguments:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-t HOST, --trex-host HOST
Specify the hostname or ip to connect with TRex
server.
-p PORT, --trex-port PORT
Select port on which the TRex server listens. Default
port is 8090.
-m SIZE, --maxhist SIZE
Specify maximum history size saved at client side.
Default size is 100.
--verbose Switch ON verbose option at TRex client. Default is:
OFF.
Code Excerpt
1#!/router/bin/python-2.7.4
2
3import trex_root_path
4from client.trex_client import *
5from common.trex_exceptions import *
6import cmd
7import termstyle
8import os
9from argparse import ArgumentParser
10from pprint import pprint
11import json
12import time
13import socket
14import errno
15
16class InteractiveTRexClient(cmd.Cmd):
17
18 intro = termstyle.green("\nInteractive shell to play with Cisco's TRex API.\nType help to view available pre-defined scenarios\n(c) All rights reserved.\n")
19 prompt = '> '
20
21 def __init__(self, trex_host, max_history_size = 100, trex_port = 8090, verbose_mode = False ):
22 cmd.Cmd.__init__(self)
23 self.verbose = verbose_mode
24 self.trex = CTRexClient(trex_host, max_history_size, trex_daemon_port = trex_port, verbose = verbose_mode)
25 self.DEFAULT_RUN_PARAMS = dict( m = 1.5,
26 nc = True,
27 p = True,
28 d = 100,
29 f = 'avl/sfr_delay_10_1g.yaml',
30 l = 1000)
31 self.run_params = dict(self.DEFAULT_RUN_PARAMS)
32 self.decoder = json.JSONDecoder()
33
34
35 def do_push_files (self, filepaths):
36 """Pushes a custom file to be stored locally on TRex server.\nPush multiple files by spefiying their path separated by ' ' (space)."""
37 try:
38 filepaths = filepaths.split(' ')
39 print termstyle.green("*** Starting pushing files ({trex_files}) to TRex. ***".format (trex_files = ', '.join(filepaths)) )
40 ret_val = self.trex.push_files(filepaths)
41 if ret_val:
42 print termstyle.green("*** End of TRex push_files method (success) ***")
43 else:
44 print termstyle.magenta("*** End of TRex push_files method (failed) ***")
45
46 except IOError as inst:
47 print termstyle.magenta(inst)
48
49 def do_show_default_run_params(self,line):
50 """Outputs the default TRex running parameters"""
51 pprint(self.DEFAULT_RUN_PARAMS)
52 print termstyle.green("*** End of default TRex running parameters ***")
53
54 def do_show_run_params(self,line):
55 """Outputs the currently configured TRex running parameters"""
56 pprint(self.run_params)
57 print termstyle.green("*** End of TRex running parameters ***")
58
59 def do_update_run_params(self, json_str):
60 """Updates provided parameters on TRex running configuration. Provide using JSON string"""
61 if json_str:
62 try:
63 upd_params = self.decoder.decode(json_str)
64 self.run_params.update(upd_params)
65 print termstyle.green("*** End of TRex parameters update ***")
66 except ValueError as inst:
67 print termstyle.magenta("Provided illegal JSON string. Please try again.\n[", inst,"]")
68 else:
69 print termstyle.magenta("JSON configuration string is missing. Please try again.")
70
71 def do_show_status (self, line):
72 """Prompts TRex current status"""
73 print self.trex.get_running_status()
74 print termstyle.green("*** End of TRex status prompt ***")
75
76 def do_show_trex_files_path (self, line):
77 """Prompts the local path in which files are stored when pushed to trex server from client"""
78 print self.trex.get_trex_files_path()
79 print termstyle.green("*** End of trex_files_path prompt ***")
80
81 def do_show_reservation_status (self, line):
82 """Prompts if TRex is currently reserved or not"""
83 if self.trex.is_reserved():
84 print "TRex is reserved"
85 else:
86 print "TRex is NOT reserved"
87 print termstyle.green("*** End of reservation status prompt ***")
88
89 def do_reserve_trex (self, user):
90 """Reserves the usage of TRex to a certain user"""
91 try:
92 if not user:
93 ret = self.trex.reserve_trex()
94 else:
95 ret = self.trex.reserve_trex(user.split(' ')[0])
96 print termstyle.green("*** TRex reserved successfully ***")
97 except TRexException as inst:
98 print termstyle.red(inst)
99
100 def do_cancel_reservation (self, user):
101 """Cancels a current reservation of TRex to a certain user"""
102 try:
103 if not user:
104 ret = self.trex.cancel_reservation()
105 else:
106 ret = self.trex.cancel_reservation(user.split(' ')[0])
107 print termstyle.green("*** TRex reservation canceled successfully ***")
108 except TRexException as inst:
109 print termstyle.red(inst)
110
111 def do_restore_run_default (self, line):
112 """Restores original TRex running configuration"""
113 self.run_params = dict(self.DEFAULT_RUN_PARAMS)
114 print termstyle.green("*** End of restoring default run parameters ***")
115
116 def do_run_until_finish (self, sample_rate):
117 """Starts TRex and sample server until run is done."""
118 print termstyle.green("*** Starting TRex run_until_finish scenario ***")
119
120 if not sample_rate: # use default sample rate if not passed
121 sample_rate = 5
122 try:
123 sample_rate = int(sample_rate)
124 ret = self.trex.start_trex(**self.run_params)
125 self.trex.sample_until_finish(sample_rate)
126 print termstyle.green("*** End of TRex run ***")
127 except ValueError as inst:
128 print termstyle.magenta("Provided illegal sample rate value. Please try again.\n[", inst,"]")
129 except TRexException as inst:
130 print termstyle.red(inst)
131
132 def do_run_and_poll (self, sample_rate):
133 """Starts TRex and sample server manually until run is done."""
134 print termstyle.green("*** Starting TRex run and manually poll scenario ***")
135 if not sample_rate: # use default sample rate if not passed
136 sample_rate = 5
137 try:
138 sample_rate = int(sample_rate)
139 ret = self.trex.start_trex(**self.run_params)
140 last_res = dict()
141 while self.trex.is_running(dump_out = last_res):
142 obj = self.trex.get_result_obj()
143 if (self.verbose):
144 print obj
145 # do WHATEVER here
146 time.sleep(sample_rate)
147
148 print termstyle.green("*** End of TRex run ***")
149 except ValueError as inst:
150 print termstyle.magenta("Provided illegal sample rate value. Please try again.\n[", inst,"]")
151 except TRexException as inst:
152 print termstyle.red(inst)
153
154
155 def do_run_until_condition (self, sample_rate):
156 """Starts TRex and sample server until condition is satisfied."""
157 print termstyle.green("*** Starting TRex run until condition is satisfied scenario ***")
158
159 def condition (result_obj):
160 return result_obj.get_current_tx_rate()['m_tx_pps'] > 200000
161
162 if not sample_rate: # use default sample rate if not passed
163 sample_rate = 5
164 try:
165 sample_rate = int(sample_rate)
166 ret = self.trex.start_trex(**self.run_params)
167 ret_val = self.trex.sample_until_condition(condition, sample_rate)
168 print ret_val
169 print termstyle.green("*** End of TRex run ***")
170 except ValueError as inst:
171 print termstyle.magenta("Provided illegal sample rate value. Please try again.\n[", inst,"]")
172 except TRexException as inst:
173 print termstyle.red(inst)
174
175 def do_start_and_return (self, line):
176 """Start TRex run and once in 'Running' mode, return to cmd prompt"""
177 print termstyle.green("*** Starting TRex run, wait until in 'Running' state ***")
178 try:
179 ret = self.trex.start_trex(**self.run_params)
180 print termstyle.green("*** End of scenario (TRex is probably still running!) ***")
181 except TRexException as inst:
182 print termstyle.red(inst)
183
184 def do_poll_once (self, line):
185 """Performs a single poll of TRex current data dump (if TRex is running) and prompts and short version of latest result_obj"""
186 print termstyle.green("*** Trying TRex single poll ***")
187 try:
188 last_res = dict()
189 if self.trex.is_running(dump_out = last_res):
190 obj = self.trex.get_result_obj()
191 print obj
192 else:
193 print termstyle.magenta("TRex isn't currently running.")
194 print termstyle.green("*** End of scenario (TRex is posssibly still running!) ***")
195 except TRexException as inst:
196 print termstyle.red(inst)
197
198
199 def do_stop_trex (self, line):
200 """Try to stop TRex run (if TRex is currently running)"""
201 print termstyle.green("*** Starting TRex termination ***")
202 try:
203 ret = self.trex.stop_trex()
204 print termstyle.green("*** End of scenario (TRex is not running now) ***")
205 except TRexException as inst:
206 print termstyle.red(inst)
207
208 def do_kill_indiscriminately (self, line):
209 """Force killing of running TRex process (if exists) on the server."""
210 print termstyle.green("*** Starting TRex termination ***")
211 ret = self.trex.force_kill()
212 if ret:
213 print termstyle.green("*** End of scenario (TRex is not running now) ***")
214 elif ret is None:
215 print termstyle.magenta("*** End of scenario (TRex termination aborted) ***")
216 else:
217 print termstyle.red("*** End of scenario (TRex termination failed) ***")
218
219 def do_exit(self, arg):
220 """Quits the application"""
221 print termstyle.cyan('Bye Bye!')
222 return True
223
224
225if __name__ == "__main__":
226 parser = ArgumentParser(description = termstyle.cyan('Run TRex client API demos and scenarios.'),
227 usage = """client_interactive_example [options]""" )
228
229 parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0 \t (C) Cisco Systems Inc.\n')
230
231 parser.add_argument("-t", "--trex-host", required = True, dest="trex_host",
232 action="store", help="Specify the hostname or ip to connect with TRex server.",
233 metavar="HOST" )
234 parser.add_argument("-p", "--trex-port", type=int, default = 8090, metavar="PORT", dest="trex_port",
235 help="Select port on which the TRex server listens. Default port is 8090.", action="store")
236 parser.add_argument("-m", "--maxhist", type=int, default = 100, metavar="SIZE", dest="hist_size",
237 help="Specify maximum history size saved at client side. Default size is 100.", action="store")
238 parser.add_argument("--verbose", dest="verbose",
239 action="store_true", help="Switch ON verbose option at TRex client. Default is: OFF.",
240 default = False )
241 args = parser.parse_args()
242
243 try:
244 InteractiveTRexClient(args.trex_host, args.hist_size, args.trex_port, args.verbose).cmdloop()
245
246 except KeyboardInterrupt:
247 print termstyle.cyan('Bye Bye!')
248 exit(-1)
249 except socket.error, e:
250 if e.errno == errno.ECONNREFUSED:
251 raise socket.error(errno.ECONNREFUSED, "Connection from TRex server was terminated. Please make sure the server is up.")
252
253
254
End-to-End cycle¶
This example (pkt_generation_for_trex.py) demonstrates a full cycle of using the API.
Note
this module uses the Scapy in order to generate packets to be used as a basis of the traffic injection. It is recommended to install this module to best experience the example.
- The demo takes the user a full circle:
Generating packets (using Scapy)
exporting the generated packets into .pcap file named dns_traffic.pcap.
Use the
trex_yaml_gen.CTRexYamlgenerator to include that pcap file in the yaml object.Export the YAML object onto a YAML file named dns_traffic.yaml
Push the generated files to TRex server.
Run TRex based on the generated (and pushed) files.
Code Excerpt 1
1
2
3import logging
4import time
5import trex_root_path
6from client.trex_client import *
7from client_utils.general_utils import *
8from client_utils.trex_yaml_gen import *
9from pprint import pprint
10from argparse import ArgumentParser
11
12# import scapy package
13logging.getLogger("scapy.runtime").setLevel(logging.ERROR) # supress scapy import warnings from being displayed
14from scapy.all import *
15
16
17def generate_dns_packets (src_ip, dst_ip):
18 dns_rqst = Ether(src='00:15:17:a7:75:a3', dst='e0:5f:b9:69:e9:22')/IP(src=src_ip,dst=dst_ip,version=4L)/UDP(dport=53, sport=1030)/DNS(rd=1,qd=DNSQR(qname="www.cisco.com"))
19 dns_resp = Ether(src='e0:5f:b9:69:e9:22', dst='00:15:17:a7:75:a3')/IP(src=dst_ip,dst=src_ip,version=4L)/UDP(dport=1030, sport=53)/DNS(aa=1L, qr=1L, an=DNSRR(rclass=1, rrname='www.cisco.com.', rdata='100.100.100.100', type=1), ad=0L, qdcount=1, ns=None, tc=0L, rd=0L, ar=None, opcode=0L, ra=1L, cd=0L, z=0L, rcode=0L, qd=DNSQR(qclass=1, qtype=1, qname='www.cisco.com.'))
20 return [dns_rqst, dns_resp]
21
22def pkts_to_pcap (pcap_filename, packets):
23 wrpcap(pcap_filename, packets)
24
25
26def main (args):
27 # instantiate TRex client
28 trex = CTRexClient('trex-dan', verbose = args.verbose)
29
30 if args.steps:
31 print "\nNext step: .pcap generation."
32 raw_input("Press Enter to continue...")
33 # generate TRex traffic.
34 pkts = generate_dns_packets('21.0.0.2', '22.0.0.12') # In this case - DNS traffic (request-response)
35 print "\ngenerated traffic:"
36 print "=================="
37 map(lambda x: pprint(x.summary()) , pkts)
38 pkts_to_pcap("dns_traffic.pcap", pkts) # Export the generated to a .pcap file
39
40 if args.steps:
41 print "\nNext step: .yaml generation."
42 raw_input("Press Enter to continue...")
43 # Generate .yaml file that uses the generated .pcap file
44 trex_files_path = trex.get_trex_files_path() # fetch the path in which packets are saved on TRex server
45 yaml_obj = CTRexYaml(trex_files_path) # instantiate CTRexYaml obj
46
47 # set .yaml file parameters according to need and use
48 ret_idx = yaml_obj.add_pcap_file("dns_traffic.pcap")
49 yaml_obj.set_cap_info_param('cps', 1.1, ret_idx)
50
51 # export yaml_ob to .yaml file
52 yaml_file_path = trex_files_path + 'dns_traffic.yaml'
53 yaml_obj.to_yaml('dns_traffic.yaml')
54 print "\ngenerated .yaml file:"
55 print "===================="
56 yaml_obj.dump()
57
58 if args.steps:
59 print "\nNext step: run TRex with provided files."
60 raw_input("Press Enter to continue...")
61 # push all relevant files to server
62 trex.push_files( yaml_obj.get_file_list() )
63
64 print "\nStarting TRex..."
65 trex.start_trex(c = 2,
66 m = 1.5,
67 nc = True,
68 p = True,
69 d = 30,
70 f = yaml_file_path, # <-- we use out generated .yaml file here
71 l = 1000)
72
73 if args.verbose:
74 print "TRex state changed to 'Running'."
75 print "Sampling TRex in 0.2 samples/sec (single sample every 5 secs)"
76
77 last_res = dict()
78 while trex.is_running(dump_out = last_res):
79 print "CURRENT RESULT OBJECT:"
80 obj = trex.get_result_obj()
81 print obj
82 time.sleep(5)
83
84
85if __name__ == "__main__":
86 parser = ArgumentParser(description = 'Run TRex client API end-to-end example.',
87 usage = """pkt_generation_for_trex [options]""" )
88
89 parser.add_argument("-s", "--step-by-step", dest="steps",
90 action="store_false", help="Switch OFF step-by-step script overview. Default is: ON.",
91 default = True )
92 parser.add_argument("--verbose", dest="verbose",
93 action="store_true", help="Switch ON verbose option at TRex client. Default is: OFF.",
94 default = False )
95 args = parser.parse_args()
96 main(args)
Footnotes
- 1
The marked codelines corresponds with the steps mentioned above.