TRex Stateful Python API Tutorial ================================= :author: Dan Klein :email: :revnumber: 1.0 :quotes.++: :numbered: include::trex_ga.asciidoc[] === TRex traffic generator TRex traffic generator is a tool design the benchmark platforms with realistic traffic. This is a work-in-progress product, which is under constant developement, new features are added and support for more router's fuctionality is achieved. === TRex Control TRex control plane is under developement, and a phase 1 is planned to be published soon (Apr 2015). + This document will shortly describe the planned control plane for TRex, which is planned to be more scalable and support automation more intuitively. ==== TRex Control Plane - High Level TRex control plane is based on a JSON RPC transactions between clients and server. + Each TRex machine will have a server running on it, closely interacting with TRex (clients do not approach TRex directly). + As future feature, and as multiple T-Rexes might run on the same machine, single server shall serve all T-Rexes running a machine. The client is a Python based application that created `TRexClient` instances. + Using class methods, the client interacts with TRex server, and enable it to perform the following commands: 1. Start TRex run (custom parameters supported). 2. Stop TRex run. 3. Check what is the TRex status (possible states: `Idle, Starting, Running`). 4. Poll (by customize sampling) the server and get live results from TRex **while still running**. 5. Get custom TRex stats based on a window of saved history of latest 'N' polling results. ==== TRex Control Plane - Example crumbs - **Exmaple #1: Checking TRex status and Launching TRex** The following program checks TRex status, and later on launches it, querying its status along different time slots. [source, python] ---- import time trex = CTRexClient('trex-name') print "Before Running, TRex status is: ", trex.is_running() # <1> print "Before Running, TRex status is: ", trex.get_running_status() # <2> ret = trex.start_trex( c = 2, # <3> m = 0.1, d = 20, f = 'avl/sfr_delay_10_1g.yaml', nc = True, p = True, l = 1000) print "After Starting, TRex status is: ", trex.is_running(), trex.get_running_status() time.sleep(10) # <4> print "Is TRex running? ", trex.is_running(), trex.get_running_status() # <5> ---- <1> `is_running()` returns a boolean and checks if TRex is running or not. <2> `get_running_status()` returns a Python dictionary with TRex state, along with a verbose field containing extra info, if available. <3> TRex lanching. All types of inputs are supported. Some fields (such as 'f' and 'c' are mandatory). <4> Going to sleep for few seconds, allowing TRex to start. <5> Checking out with TRex status again, printing both a boolean return value and a full status. This code will prompt the following output, assuming a server was launched on the TRex machine. ---- Connecting to TRex @ http://trex-dan:8090/ ... Before Running, TRex status is: False Before Running, TRex status is: {u'state': , u'verbose': u'TRex is Idle'} <1> <1> After Starting, TRex status is: False {u'state': , u'verbose': u'TRex is starting'} <1> <1> Is TRex running? True {u'state': , u'verbose': u'TRex is Running'} <1> <1> ---- <1> When looking at TRex status, both an enum status (`Idle, Starting, Running`) and verbose output are available. * **Exmaple #2: Checking TRex status and Launching TRex with 'BAD PARAMETERS'** The following program checks TRex status, and later on launches it with wrong input ('mdf' is not legal option), hence TRex run will not start and a message will be available. [source, python] ---- import time trex = CTRexClient('trex-name') print "Before Running, TRex status is: ", trex.is_running() # <1> print "Before Running, TRex status is: ", trex.get_running_status() # <2> ret = trex.start_trex( c = 2, # <3> #<4> mdf = 0.1, d = 20, f = 'avl/sfr_delay_10_1g.yaml', nc = True, p = True, l = 1000) print "After Starting, TRex status is: ", trex.is_running(), trex.get_running_status() time.sleep(10) # <5> print "Is TRex running? ", trex.is_running(), trex.get_running_status() # <6> ---- <1> `is_running()` returns a boolean and checks if TRex is running or not. <2> `get_running_status()` returns a Python dictionary with TRex state, along with a verbose field containing extra info, if available. <3> TRex lanching. All types of inputs are supported. Some fields (such as 'f' and 'c' are mandatory). <4> Wrong parameter ('mdf') injected. <5> Going to sleep for few seconds, allowing TRex to start. <6> Checking out with TRex status again, printing both a boolean return value and a full status. This code will prompt the following output, assuming a server was launched on the TRex machine. ---- Connecting to TRex @ http://trex-dan:8090/ ... Before Running, TRex status is: False Before Running, TRex status is: {u'state': , u'verbose': u'TRex is Idle'} <1> <1> After Starting, TRex status is: False {u'state': , u'verbose': u'TRex is starting'} <1> <1> Is TRex running? False {u'state': , u'verbose': u'TRex run failed due to wrong input parameters, or due to reachability issues.'} <2> <2> ---- <1> When looking at TRex status, both an enum status (`Idle, Starting, Running`) and verbose output are available. <2> After TRex lanuching failed, a message indicating the failure reason. However, TRex is back Idle, ready to handle another launching request. * **Exmaple #3: Launching TRex, monitor live data and stopping on demand** The following program will launch TRex, and while it runs poll the server (every 5 seconds) for running inforamtion, such as latency, drops, and other extractable parameters. + Then, after some criteria was met, TRex execution is terminated, enabeling others to use the resource instead of waiting for the entire execution to finish. [source, python] ---- print "Before Running, TRex status is: ", trex.get_running_status() print "Starting TRex..." ret = trex.start_trex( c = 2, mdf = 0.1, d = 100, f = 'avl/sfr_delay_10_1g.yaml', nc = True, p = True, l = 1000) print "After Starting, TRex status is: ", trex.is_running(), trex.get_running_status() print "sleeping 20 secs.." time.sleep(20) for i in range(5): print "Is TRex running? ", trex.is_running(), trex.get_running_status() #<1> #<2> received_info = trex.get_running_info() #<3> # Custom data processing is done here #<4> time.sleep(5) print "Terminating TRex..." #<5> ret = trex.stop_trex() print "After stopping, TRex status is: ", trex.is_running(), trex.get_running_status() #<6> ---- <1> Running queries is still optional, although not mandatory in order to get stats. <2> `get_running_info()` will return the latest data dump available from TRex. + Some aditional data manipulation and queries are under developement, including manipulation over number of dumps, which is useful for avoiding "spikes" of singular behavior. <3> Data processing. This is fully customizable for the relevant test initiated. <4> The sampling rate is flexibale and can be configured depending on the desired output. <5> TRex termination. <6> Post-termination check for status. This code will prompt the following output, assuming a server was launched on the TRex machine. ---- Connecting to TRex @ http://trex-dan:8090/ ... Before Running, TRex status is: False Before Running, TRex status is: {u'state': , u'verbose': u'TRex is Idle'} Starting TRex... After Starting, TRex status is: False {u'state': , u'verbose': u'TRex is starting'} <1> Is TRex running? True {u'state': , u'verbose': u'TRex is Running'} <1> Is TRex running? True {u'state': , u'verbose': u'TRex is Running'} <1> Is TRex running? True {u'state': , u'verbose': u'TRex is Running'} <1> Is TRex running? True {u'state': , u'verbose': u'TRex is Running'} <1> Is TRex running? True {u'state': , u'verbose': u'TRex is Running'} Before terminating, TRex status is: True {u'state': , u'verbose': u'TRex is Running'} Terminating TRex... #<2> After stopping, TRex status is: False {u'state': , u'verbose': u'TRex finished (terminated).'} ---- <1> Polling TRex status while in a data polling loop. <2> After termination, we can see that TRex is back idle, also the `verbose` field shows the stop reason