How to use OMF Prototypes to specify your Application¶
1. Prerequisites¶
- Make sure that you understand how OMF works from a user's point of view.
- Make sure that you have completed and understood the basic "Hello World" tutorial.
- Make sure that you have completed and understood the "how to use your own application" tutorial.
2. Goal¶
- In the previous "how to use your own application" tutorial, we saw how to create and use an Application Definition which will allow your experiment to use and control your own or a 3rd party application.
- While you can use your own application directly in your experiment through its Application Definition, sometime you may want to use a more specific instance of that application without necessary having to set a all collection of parameters each time. You can do this in your OMF experiment through the definition of a Prototype
- A Prototype is a specialized version of your application for which you have preset some parameters and/or some measurements to collect.
- This tutorial shows you:
- how to write an OMF Prototype definition (which uses an existing OMF Application definition)
- how to use it within your Experiment Description
3. Scenario¶
- Here we are using the same simple scenario as in the basic "Hello World" tutorial (one traffic Sender and one Receiver)
- However:
- the traffic generator application (OTG2) used in the "Hello World" tutorial can actually generate 2 types of traffic: a constant bit rate one (CBR), and an exponential distributed one (EXPO). We only used the CBR mode in the previous "Hello World"
- Here we will create 2 OMF Prototypes that will be specializations of the OTG2 application:
- Prototype 1 will be an Exponential traffic generator (EXPO)
- Prototype 2 will be a Constant-Bit-Rate traffic generator (CBR)
- Both Prototypes will be using the OTG2 application definition (a simple version in the "how to use your own application" tutorial)
- Both Prototypes will have default values for the traffic generation parameters
3. The Experiment Files¶
3.1. The OTG2 Application Definition¶
- We have already given an example of an Application Definition for OTG2 in the "How to use your own application" tutorial
- However that previous Application Definition was quite simple and expose all the the possible traffic generation options of the OTG2 applciation
- Here is an extended Application Definition for OTG2, which gives us access to more of OTG2's options:
- download it here: otg2_app_def.rb
1 defApplication('otg2_app_def', 'otg2') do |app|
2
3 app.path = "/usr/bin/otg2"
4 app.version(1, 1, 2)
5 app.shortDescription = "Programmable traffic generator v2"
6 app.description = "OTG is a simple configurable traffic generator."
7
8 app.defProperty('generator', 'Type of packet generator to use (cbr or expo)', 'g', {:type => :string, :dynamic => false})
9 app.defProperty('udp:broadcast', 'Broadcast', nil, {:type => :integer, :dynamic => false})
10 app.defProperty('udp:dst_host', 'IP address of the Destination', nil, {:type => :string, :dynamic => false})
11 app.defProperty('udp:dst_port', 'Destination Port to send to', nil, {:type => :integer, :dynamic => false})
12 app.defProperty('udp:local_host', 'IP address of this Source node', nil, {:type => :string, :dynamic => false})
13 app.defProperty('udp:local_port', 'Local Port of this source node', nil, {:type => :integer, :dynamic => false})
14 app.defProperty("cbr:size", "Size of packet [bytes]", nil, {:dynamic => true, :type => :integer})
15 app.defProperty("cbr:rate", "Data rate of the flow [kbps]", nil, {:dynamic => true, :type => :integer})
16 app.defProperty("exp:size", "Size of packet [bytes]", nil, {:dynamic => true, :type => :integer})
17 app.defProperty("exp:rate", "Data rate of the flow [kbps]", nil, {:dynamic => true, :type => :integer})
18 app.defProperty("exp:ontime", "Average length of burst [msec]", nil, {:dynamic => true, :type => :integer})
19 app.defProperty("exp:offtime", "Average length of idle time [msec]", nil, {:dynamic => true, :type => :integer})
20
21 app.defMeasurement('udp_out') do |mp|
22 mp.defMetric('ts',:float)
23 mp.defMetric('flow_id',:long)
24 mp.defMetric('seq_no',:long)
25 mp.defMetric('pkt_length',:long)
26 mp.defMetric('dst_host',:string)
27 mp.defMetric('dst_port',:long)
28 end
29 end
- This type of Application Definition has already been explained in details in the "How to use your own application" tutorial.
3.2. The OMF Prototypes based on the OTG2 Application¶
- Here is the OMF prototype for the Exponential Traffic Generator based on OTG2:
- download it here: expo_generator.rb
1 defPrototype("expo_generator") do |proto|
2 proto.name = "UDP_EXPO_Traffic_Generator"
3 proto.description = "A traffic generator using an Exponential model"
4
5 proto.defProperty('trafficModel', 'Model of traffic to use', 'expo')
6 proto.defProperty('destinationHost', 'Host to send packets to')
7 proto.defProperty('destinationPort', 'Host to send packets to',3000)
8 proto.defProperty('localHost', 'Host that generate the packets')
9 proto.defProperty('localPort', 'Host that generate the packets',3000)
10 proto.defProperty('packetSize', 'Size of packets [bytes]', 512)
11 proto.defProperty('rate', 'Number of bits per second [kbps]', 1024)
12 proto.defProperty('burstDuration', 'Average burst duration [msec]', 10)
13 proto.defProperty('idleDuration', 'Average idle duration [msec]', 50)
14 proto.defProperty('broadcast', 'Allow broadcast', 1)
15
16 proto.addApplication("otg2_app_def") do |app|
17 app.bindProperty('generator', 'trafficModel')
18 app.bindProperty('udp:broadcast', 'broadcast')
19 app.bindProperty('udp:dst_host', 'destinationHost')
20 app.bindProperty('udp:dst_port', 'destinationPort')
21 app.bindProperty('udp:local_host', 'localHost')
22 app.bindProperty('udp:local_port', 'localPort')
23 app.bindProperty('exp:size', 'packetSize')
24 app.bindProperty('exp:rate', 'rate')
25 app.bindProperty('exp:ontime', 'burstDuration')
26 app.bindProperty('exp:offtime', 'idleDuration')
27 app.measure('udp_out', :samples => 1) do |mp|
28 mp.filter('seq_no','first')
29 mp.filter('pkt_length','first')
30 end
31 end
32 end
- Line 1: we define a new OMF Prototype and give it the URI
expo_generator
- Line 2-3: some information about this prototype
- Line 5-14: we define some configurable parameters (or properties) for this prototype
- For example, we define a property
trafficModeland we give it a default value ofexpo - NOTE: the method used here
defPropertyis different from thedefPropertyused when definition an OMF Application definition withdefApplication - the
defPropertyused inside adefApplicationis described in the "How to use your own application" tutorial. - the
defPropertyused here inside adefPrototypeis:
- For example, we define a property
syntax: defProperty(name, description, default)
- name : the name for this property, this will be use to set it in the experiment
- description : some description of this property
- default : a default value (optional) to give to this property, when it is not
explicitly set in the experiment
- Line 16: defines the OMF Application Definition which describes the Application on which this Prototype is based
- the URI for the Application Definition to use here should be exactly the one assigned to the Application Definition, e.g.
otg2_app_defhere
- the URI for the Application Definition to use here should be exactly the one assigned to the Application Definition, e.g.
- Line 17-26: each property that we defined for this prototype (line 5 to 14) need to be bound to a given property defined in the Application Definition
- this is done by using the
bindPropertymethod described below - any configurable parameters of the original Application Definition which is not bound here to a Prototype property will not be accessible for configuration bia the Prototype
- this is done by using the
syntax: bindProperty(target, property)
- target : the name for the Application Definition property to which a Prototype
property should be bound to
- property : the name of the Prototype property, which we want to bind to some existing
Application Definition property.
- Line 27-29: defines the measurements we would like to collect for this Prototype and the filters to apply to them
- the measurements defined here need to be made available by existing Measurement Point, as defined in the Application Definition
- the use of measurements and filters to apply to them is described in the Measurements and Filters tutorial
- Here is the OMF prototype for the Constant-Bit-Rate Traffic Generator based on OTG2:
- download it here: expo_generator.rb
- the descriptions of the previous prototype above also applies to this following one
1 defPrototype("cbr_generator") do |proto|
2 proto.name = "UDP_CBR_Traffic_Generator"
3 proto.description = "A traffic generator using a Constant Bit Rate model"
4
5 proto.defProperty('trafficModel', 'Model of traffic to use', 'cbr')
6 proto.defProperty('destinationHost', 'Host to send packets to')
7 proto.defProperty('destinationPort', 'Host to send packets to',3000)
8 proto.defProperty('localHost', 'Host that generate the packets')
9 proto.defProperty('localPort', 'Host that generate the packets',3000)
10 proto.defProperty('packetSize', 'Size of packets [bytes]', 512)
11 proto.defProperty('rate', 'Number of bits per second [kbps]', 1024)
12 proto.defProperty('broadcast', 'Allow broadcast', 1)
13
14 proto.addApplication("otg2_app_def") do |app|
15 app.bindProperty('generator', 'trafficModel')
16 app.bindProperty('udp:broadcast', 'broadcast')
17 app.bindProperty('udp:dst_host', 'destinationHost')
18 app.bindProperty('udp:dst_port', 'destinationPort')
19 app.bindProperty('udp:local_host', 'localHost')
20 app.bindProperty('udp:local_port', 'localPort')
21 app.bindProperty('cbr:size', 'packetSize')
22 app.bindProperty('cbr:rate', 'rate')
23 app.measure('udp_out', :samples => 1) do |mp|
24 mp.filter('seq_no','first')
25 mp.filter('pkt_length','first')
26 end
27 end
28 end
3.3. The Experiment Description¶
- Here is the OMF Experiment Description using the above CBR and EXPO prototypes
- download it here: using-prototypes.rb
1 defGroup('CBR_Sender', "omf.nicta.node8") do |node|
2 options = { 'localHost' => '%net.w0.ip%',
3 'destinationHost' => '192.168.255.255',
4 'packetSize' => 256 }
5 node.addPrototype("cbr_generator", options)
6 end
7
8 defGroup('EXPO_Sender', "omf.nicta.node8") do |node|
9 options = { 'localHost' => '%net.w0.ip%',
10 'destinationHost' => '192.168.255.255',
11 'packetSize' => 1024 }
12 node.addPrototype("expo_generator", options)
13 end
14
15 defGroup('Receiver', "omf.nicta.node9") do |node|
16 node.addApplication("test:app:otr2") do |app|
17 app.setProperty('udp:local_host', '192.168.255.255')
18 app.setProperty('udp:local_port', 3000)
19 app.measure('udp_in', :samples => 1)
20 end
21 end
22
23 allGroups.net.w0 do |interface|
24 interface.mode = "adhoc"
25 interface.type = 'g'
26 interface.channel = "6"
27 interface.essid = "helloworld"
28 interface.ip = "192.168.0.%index%"
29 end
30
31 onEvent(:ALL_UP_AND_INSTALLED) do |event|
32 wait 10
33 info "Starting the Receiver"
34 group("Receiver").startApplications
35 info "Starting the EXPO-traffic Sender"
36 group("EXPO_Sender").startApplications
37 wait 40
38 info "Stopping the EXPO-traffic Sender"
39 group("EXPO_Sender").stopApplications
40 wait 5
41 info "Starting the CBR-traffic Sender"
42 group("CBR_Sender").startApplications
43 wait 40
44 info "Now stopping all everything"
45 #allGroups.stopApplications
46 group("CBR_Sender").stopApplications
47 group("Receiver").stopApplications
48 Experiment.done
49 end
- Line 1-6: we define a group named "CBR_Sender"
- we do NOT add the OTG2 application directly to the resource (
omf.nicta.node8) in this group as we did in the "Hello World" tutorial - instead here we add a the
cbr_generatorPrototype to this resources:- first we define the list of properties which we would like to set for this Prototype (line 2 to 4)
- then we use
addPrototypeto associate the Prototype to all the resources in this group
- we do NOT add the OTG2 application directly to the resource (
syntax: addPrototype(uri, options) - uri : the URI of the Prototype (e.g. as we defined in the Prototype Definitions above) - options : the list of properties and values which we would like to set for this Prototype
- Line 8-13: we do the same for another group "EXPO_Sender", but with a the
expo_generatorprototype
- Line 31-49: this is the experiment scenario
- first we start the receiver
- we start the exponential traffic generator and let it run for 40sec
- we stop the exponential generator and wait for 5sec
- we start the constant-bit-rate generator and let it run from 40sec
- we stop everything
- Please refer to the following tutorials for detailed description of the rest of this experiment:
4. Running the experiment¶
5.1. How to run it¶
Please refer to the "Hello World" tutorial and the Getting Started page to find out how to run an experiment with OMF. Here we assume that you have the above ED saved in the file named using-prototypes.rb, and the above Application and Prototype Definitions in the same directory with the file names as specified by their respective URIs.
- to run the experiment:
omf-5.3 exec using-prototypes.rb
6. The Results¶
- Please refer to the "Hello World" tutorial to find out how to access and use your result database
- you can download an example of a database produced by this experiment here: attachment:myDatabase
- Similar to the "Hello World" tutorial, we extend our Experiment Description to request the plotting of a couple graphs on the EC's webpage during the runtime of our experiment
- To do that, we had the following lines to our ED
- download the extended ED here: using-prototypes-graph.rb
1 addTab(:defaults)
2 addTab(:graph2) do |tab|
3 opts1 = { :postfix => %{This graph shows the Sequence Number from CBR and EXP UDP traffic.}, :updateEvery => 1 }
4 tab.addGraph("Sequence Number", opts1) do |g|
5 dataOut = Hash.new
6 mpOut = ms('udp_out')
7 mpOut.project(:oml_sender_id, :oml_ts_server, :seq_no).each do |sample|
8 sender, time, seq = sample.tuple
9 dataOut[sender] = [] if dataOut[sender] == nil
10 dataOut[sender] << [time,seq]
11 end
12 dataOut.each do |source, data|
13 g.addLine(data, :label => "#{msSenderName[source]}")
14 end
15 end
16 opts2 = { :postfix => %{This graph shows the Packet Size (bytes)from CBR and EXP UDP traffic.}, :updateEvery => 1 }
17 tab.addGraph("Packet Size", opts2) do |g|
18 dataOut = Hash.new
19 mpOut = ms('udp_out')
20 mpOut.project(:oml_sender_id, :oml_ts_server, :pkt_length).each do |sample|
21 sender, time, plength = sample.tuple
22 dataOut[sender] = [] if dataOut[sender] == nil
23 dataOut[sender] << [time,plength]
24 end
25 dataOut.each do |source, data|
26 g.addLine(data, :label => "#{msSenderName[source]}")
27 end
28 end
29 end
- Another tutorial provides a full description on How to define graphs to plot during your experiment's runtime. Please refer to the "Hello World" tutorial to find out how to access the EC's webpage during your experiment runtime
- While this experiment is running, you should have 2 graphs available at the EC's web pag
- The 1st graph shows the Sequence number of the UDP traffic generated by the EXPO and CBR traffic generators
- notice the non-linear growth of the sequence numbers for the Exponential traffic compared to the Constant-Bit-Rate traffic
- The 2nd graph shows the size of the generated UDP packets, which are consistent with the parameters set in the Experiment Description
7. What is Next?¶
Now that you know how to use OMF Prototypes, you may want to read the following basic OMF tutorials. Each one of them is introducing an OMF feature, using the simple "Hello World" experiment as a base. You do not need to follow them in the order suggested below.
And finally, a "Conference Room" scenario which combines all of the above features: