How to use OMF Prototypes to specify your Application

1. Prerequisites

2. Goal

  • 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.

3. Scenario

  • 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:
 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

3.2. The OMF Prototypes based on the OTG2 Application

  • Here is the OMF prototype for the Exponential Traffic Generator based on OTG2:
 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 trafficModel and we give it a default value of expo
    • NOTE: the method used here defProperty is different from the defProperty used when definition an OMF Application definition with defApplication
    • the defProperty used inside a defApplication is described in the "How to use your own application" tutorial.
    • the defProperty used here inside a defPrototype is:
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_def here
  • 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 bindProperty method 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
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
 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_generator Prototype 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 addPrototype to associate the Prototype to all the resources in this group
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_generator prototype
  • 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

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
 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
  • 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:


screenshot1.png (41.5 kB) Thierry Rakotoarivelo, 20/09/2010 03:57 pm

screenshot2.png (33.4 kB) Thierry Rakotoarivelo, 20/09/2010 03:57 pm

cbr_generator.rb (1.3 kB) Thierry Rakotoarivelo, 20/09/2010 04:47 pm

expo_generator.rb (1.5 kB) Thierry Rakotoarivelo, 20/09/2010 04:47 pm

otg2_app_def.rb (1.8 kB) Thierry Rakotoarivelo, 20/09/2010 04:47 pm

using-prototypes.rb (1.4 kB) Thierry Rakotoarivelo, 23/09/2010 03:04 pm

using-prototypes-graph.rb (2.5 kB) Thierry Rakotoarivelo, 23/09/2010 03:06 pm