Changes between Initial Version and Version 1 of OMF5.3Experiment


Ignore:
Timestamp:
09/07/11 17:23:16 (13 years ago)
Author:
agosain@bbn.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • OMF5.3Experiment

    v1 v1  
     1[[PageOutline]]
     2
     3== Writing experiment script, and throughput experiment example  ==
     4
     5=== Throughput experiment design, and flow ===
     6
     7
     8Here we briefly describe an OMF experiment that:
     9
     10 - runs on a mobile node with stand-alone OMF installation.[[BR]]
     11 - connects to the GENI WiMAX base-station using the OMF wimax driver.[[BR]]
     12 - measures RSSI (Received Signal Strength Indicator), CINR (Carrier to Interference-plus-Noise Ratio), and Avg. Transmit Power using the OMF wimax driver. [[BR]]
     13 - Asks the experimenter for a manual prompt to start the iperf server/client. [[BR]]
     14 - The experimenter uses the iperf dual mode experiments which do not require coordination between the client and server.
     15 - Log GPS Coordinates of the MS while it performs simultaneous or non-simultaneous uplink and downlink UDP throughput/jitter/loss measurements.[[BR]]
     16 - At the end of the experiment,Copy measurements to a given folder.
     17
     18
     19=== Throughput experiment script ===
     20
     21Experiments in OMF are written in a domain-specific language called OEDL which is based on Ruby. More information about OEDL can be found at:
     22http://mytestbed.net/projects/omf/wiki/OEDL-5-3
     23
     24Here we briefly describe an OMF experiment that:
     25
     26  - runs on a mobile node with stand-alone OMF installation.[[BR]]
     27 - connects to the GENI WiMAX base-station using the OMF wimax driver.[[BR]]
     28 - measures RSSI, CINR, and Avg. Transmit Power using the OMF wimax driver. [[BR]]
     29 - Asks the experimenter for a manual prompt to start the iperf server/client. [[BR]]
     30 - The experimenter uses the iperf dual mode experiments which do not require coordination between the client and server.
     31 - Log GPS Coordinates of the MS while it performs simultaneous or non-simultaneous uplink and downlink UDP throughput/jitter/loss measurements.[[BR]]
     32 -  At the end of the experiment,Copy measurements to a given folder.
     33
     34The following is the OEDL corresponding to this experiment. Next, we will go over different parts of it in more detail. Other similar experiments performing downlink/uplink TCP tests are available at http://software.geni.net/local-sw/
     35
     36{{{
     37#----------------------------------------------------------------------
     38# Copyright (c) 2011 Raytheon BBN Technologies
     39#
     40# Permission is hereby granted, free of charge, to any person obtaining
     41# a copy of this software and/or hardware specification (the "Work") to
     42# deal in the Work without restriction, including without limitation the
     43# rights to use, copy, modify, merge, publish, distribute, sublicense,
     44# and/or sell copies of the Work, and to permit persons to whom the Work
     45# is furnished to do so, subject to the following conditions:
     46#
     47# The above copyright notice and this permission notice shall be
     48# included in all copies or substantial portions of the Work.
     49#
     50# THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     51# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     52# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     53# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     54# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     55# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     56# OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS
     57# IN THE WORK.
     58#----------------------------------------------------------------------
     59
     60
     61defProperty('res1', "omf.bbn.node1", "ID of a node")
     62
     63# Added support for GPS
     64defApplication('gpslogger','gps') do |app|
     65  app.path="gpslogger"
     66  app.appPackage = "gpslogger.tar"
     67  app.version(1,0,0)
     68  app.shortDescription = "GPS Logger"
     69  app.description = "Retrieves GPS fix data from gpsd and feeds it into OML."
     70  app.defMeasurement('gps_data') do |mp|
     71    mp.defMetric('lat', :float)
     72    mp.defMetric('lon', :float)
     73    mp.defMetric('ele', :float)
     74    mp.defMetric('fix', :string)
     75    mp.defMetric('time', :string)
     76  end
     77end
     78
     79# Added support for link status
     80defApplication('linkstatus_app','linkstatus') do |app|
     81  app.path="wiwrapper.rb"
     82  app.appPackage = "wiwrapper.tar"
     83  app.version(1,0,0)
     84  app.shortDescription = "Wrapper around wimaxcu link status"
     85  app.description = <<TEXT
     86This is a wrapper around wimaxcu link status command
     87TEXT
     88
     89  app.defProperty('sampling','Sampling interval in sec', 's', {:type => :integer, :dynamic => false})
     90  app.defMeasurement('wimaxstat') do |m|
     91    m.defMetric('CenterFrequency', :long)
     92    m.defMetric('RSSI', :long)
     93    m.defMetric('CINR', :long)
     94    m.defMetric('TXPWR', :long) 
     95  end
     96end
     97
     98
     99defGroup('Actor', property.res1) {|node|
     100  node.prototype("test:proto:new_iperfudpdual", {
     101  'client' => '192.1.240.126',
     102  'interval' => '1',
     103  'time' => 30,
     104  'len' => '1440',
     105  'bandwidth' => '20M'
     106  })
     107
     108  node.addApplication("gpslogger") {|app|
     109    app.measure('gps_data', :interval => 3)
     110  }
     111 
     112  node.addApplication("linkstatus_app") { |app|
     113    app.setProperty('sampling', 5)
     114    app.measure('wimaxstat')
     115  }
     116
     117  node.net.x0.profile = '51'
     118
     119}
     120
     121onEvent(:ALL_UP_AND_INSTALLED) do |event|
     122  wait 5
     123  info "Press enter to continue"
     124  STDIN.gets
     125  group('Actor').startApplications
     126  wait 40
     127  group('Actor').stopApplications
     128  info "Experiment is done. Copying measurements to /home/geni/experiment_logs"
     129  info "Enter prefix: "
     130  prefix=STDIN.gets
     131  prefix.strip!
     132  FileUtils.cp "/tmp/#{Experiment.ID}.sq3" , "/home/geni/experiment_logs/#{prefix}_#{Experiment.ID}.sq3"
     133  info "files copied."
     134  Experiment.done
     135end
     136
     137
     138# support for visualization of data
     139addTab(:defaults)
     140addTab(:graph2) do |tab|
     141  opts = { :postfix => %{This graph shows the throughput.}, :updateEvery => 1 }
     142  tab.addGraph("Throughput", opts) do |g|
     143    data = []
     144    mp = ms('iperf_transfer')
     145    mp.project(:oml_ts_server, :size).each do |sample|
     146      time, tr = sample.tuple
     147      data << [time, tr]
     148    end
     149   
     150    g.addLine(data, :label => "Bandwidth")
     151   
     152  end
     153end
     154}}}
     155
     156==== Support for GPS logging ====
     157
     158This section adds support for tracking measurement locations using a GPS device attached to the mobile node.
     159
     160{{{
     161# Added support for GPS
     162defApplication('gpslogger','gps') do |app|
     163  app.path="gpslogger"
     164  app.appPackage = "gpslogger.tar"
     165  app.version(1,0,0)
     166  app.shortDescription = "GPS Logger"
     167  app.description = "Retrieves GPS fix data from gpsd and feeds it into OML."
     168  app.defMeasurement('gps_data') do |mp|
     169    mp.defMetric('lat', :float)
     170    mp.defMetric('lon', :float)
     171    mp.defMetric('ele', :float)
     172    mp.defMetric('fix', :string)
     173    mp.defMetric('time', :string)
     174  end
     175end
     176}}}
     177
     178A tar ball containing the gpslogger application has to be present in the same folder where you will run your experiment from.
     179
     180
     181==== Support for Link Status Measurements  ====
     182
     183This section of the experiment OEDL adds support for logging link status parameters such as RSSI, CINR, and Transmit Power.
     184 
     185{{{
     186# Added support for link status
     187defApplication('linkstatus_app','linkstatus') do |app|
     188  app.path="wiwrapper.rb"
     189  app.appPackage = "wiwrapper.tar"
     190  app.version(1,0,0)
     191  app.shortDescription = "Wrapper around wimaxcu link status"
     192  app.description = <<TEXT
     193This is a wrapper around wimaxcu link status command
     194TEXT
     195
     196  app.defProperty('sampling','Sampling interval in sec', 's', {:type => :integer, :dynamic => false})
     197  app.defMeasurement('wimaxstat') do |m|
     198    m.defMetric('CenterFrequency', :long)
     199    m.defMetric('RSSI', :long)
     200    m.defMetric('CINR', :long)
     201    m.defMetric('TXPWR', :long) 
     202  end
     203end
     204}}}
     205
     206The link status information is typically provided by tools associated with the specific WiMAX driver you're using. Our mobile node is equipped with an Intel WiMAX card for which a tool named 'wimaxcu' is available that provides link info.
     207
     208In order to be able to properly use wimaxcu link status reports in the experiment, we will have to write an OMF wrapper around it as 'wimaxcu' does not come with OML support. To create the wrapper:
     209
     210 - Create a folder named wiwrapper
     211 - Put the following code segment in a separate file named wiwrapper.rb, and place it in the wiwrapper folder
     212 - Get the file 'oml4r.rb' from http://mytestbed.net/repositories/changes/oml/lib/client/ruby/oml4r.rb
     213 - Put the file 'oml4r.rb' in wiwrapper folder
     214 - Make a tar ball of wiwrapper folder(wiwrapper.tar).
     215 - Put the tar ball, wiwrapper.rb, and oml4r.rb in the same directory as that of your experiment (we assume this is the directory you run your experiments from).
     216 
     217This is the code for wiwrapper.rb:
     218
     219{{{
     220#----------------------------------------------------------------------
     221# Copyright (c) 2011 Raytheon BBN Technologies
     222#
     223# Permission is hereby granted, free of charge, to any person obtaining
     224# a copy of this software and/or hardware specification (the "Work") to
     225# deal in the Work without restriction, including without limitation the
     226# rights to use, copy, modify, merge, publish, distribute, sublicense,
     227# and/or sell copies of the Work, and to permit persons to whom the Work
     228# is furnished to do so, subject to the following conditions:
     229#
     230# The above copyright notice and this permission notice shall be
     231# included in all copies or substantial portions of the Work.
     232#
     233# THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     234# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     235# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     236# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
     237# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     238# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     239# OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS
     240# IN THE WORK.
     241#----------------------------------------------------------------------
     242
     243#!/usr/bin/env ruby
     244$LOAD_PATH<<'/usr/bin'
     245require 'oml4r'
     246
     247
     248
     249APPNAME = "wimaxcu"
     250APPPATH = "/usr/bin/wimaxcu"
     251APPVERSION = "1.0"
     252
     253
     254
     255class MPStat < OML4R::MPBase
     256    name :wimaxstat
     257    param :CenterFrequency, :type => :long
     258    param :RSSI, :type => :long
     259    param :CINR, :type => :long
     260        param :TXPWR,:type => :long
     261
     262    # wimaxcu returns other metrics which we ignore here
     263end
     264
     265class Wrapper
     266
     267  def process_output(output)
     268    # wimaxcu returns a sequence of lines
     269    # The 1st line is a list of labels for the fields of the remaining lines
     270    # Each remaining line is for a detected stations, and follows the format:
     271    # ADDR AID CHAN RATE RSSI DBM IDLE TXSEQ RXSEQ CAPS ACAPS ERP STATE MODE
     272    lines = output.split("\n")
     273    lines.delete_at(0)
     274    lines.delete_at(1)
     275    lines.delete_at(4)
     276    column = Array.new
     277    lines.each { |row|
     278      nums = row.scan(/\d+|-\d+/)
     279      column << nums
     280    }
     281
     282    # Inject the measurements into OML
     283    MPStat.inject(column[0], column[1], column[2], column[3])
     284  end
     285
     286
     287  def initialize(args)
     288   
     289    # Initialise some variable specific to this wrapper
     290    @interval = 5
     291
     292    # Now call the Init of OML4R with the command line arguments (args)
     293    # and a block defining the arguments specific to this wrapper
     294    OML4R::init(args, :appID => APPNAME) { |argParser|
     295      argParser.banner = "\nExecute a wrapper around #{APPNAME}\n" +
     296                         "Use -h or --help for a list of options\n\n"
     297      argParser.on("-s", "--sampling DURATION",
     298                   "Interval in second between collected samples") { |time|
     299                      @interval = time
     300                   }
     301      argParser.on_tail("-v", "--version",
     302                        "Show the version\n") { |v|
     303                           puts "Version: #{APPVERSION}"; exit
     304                        }
     305    }
     306
     307    # Finally do some checking specific to this wrapper
     308    # e.g. here we do not proceed if the user did not give us a
     309    # valid interface to monitor
     310    #unless @interface != nil
     311    #  raise "You did not specify an interface to monitor! (-i option)"
     312    #end
     313  end
     314
     315  def start()
     316    while true
     317      # Run the wlanconfig command with the following syntax
     318      #   "wlanconfig <interface> list"
     319      cmd = "#{APPPATH} status link"
     320      output = `#{cmd}`
     321      # Process its output
     322      process_output(output)
     323      # Wait for a given duration and loop again
     324      sleep @interval.to_i
     325    end
     326  end
     327end
     328
     329begin
     330  app = Wrapper.new(ARGV)
     331  app.start()
     332rescue Exception => ex
     333  puts "Received an Exception when executing the wrapper!"
     334  puts "The Exception is: #{ex}\n"
     335end
     336}}}
     337
     338For more information on writing wrappers in OMF/OML see: http://mytestbed.net/wiki/omf/OMLWrapperHowTo
     339
     340==== Support for Bandwidth Measurements ====
     341
     342We use an OMLized version of iperf to perform bi-directional simultaneous uplink/downlink tests.
     343
     344
     345===== Installation of the new iperf Application =====
     346
     347The following installation works with OML-2.5.0 and OMF-5.3.
     348
     349 - Remove all existing versions of iperf from the node, if they exist
     350 - Make sure that automake and autoconf are installed, if not,
     351{{{
     352 sudo apt-get install automake autoconf
     353}}}
     354 
     355 - Install the very latest liboml2-dev package using the instructions here: http://omf.mytestbed.net/projects/oml/wiki/Installing_OML_packages
     356 - Check out the new iperf code:
     357{{{
     358git clone git://git.mytestbed.net/iperf.git -b oml/master
     359}}}
     360
     361Configure the new code
     362
     363
     364{{{
     365 cd iperf
     366 ./autogen.sh
     367 ./configure
     368
     369}}}
     370 - check the config.log file to make sure ldd finds the required oml2 libraries.
     371 - Make and install the application
     372
     373{{{
     374 make
     375 sudo make install
     376}}}
     377
     378 - Upon successful compilation
     379{{{
     380 cd oml
     381 cat iperf.app > new_iperf.rb
     382}}}
     383
     384 - Open new_iperf.rb and replace all occurrences of ':uint32' with ':long'
     385 - In the same file, replace all occurences of ':double' with ':float'
     386 - Copy the file to the application directory in OML
     387
     388{{{
     389 cp new_iperf.rb /usr/share/omf-expctl-5.3/repository/test/app/
     390}}}
     391
     392
     393===== Creating OMF prototypes for iperf udp dualtest =====
     394
     395 
     396{{{
     397cd /usr/share/omf-expctl-5.3/repository/test/proto/
     398}}}
     399
     400 - create a file named new_iperfudpdual.rb and copy the following code in it:
     401{{{
     402# Define a prototype
     403#
     404defPrototype("test:proto:new_iperfudpdual") { |p|
     405  p.name = "Iperf UDP Dual Send/Receive Test"
     406  p.description = "Nodes which send a stream of packets"
     407
     408  # Define the properties (and their default values) that can be configured
     409  # for this prototype
     410  #
     411  p.defProperty('client', 'Host to send packets to','localhost')
     412  p.defProperty('len', 'Size of packets','1440')
     413  p.defProperty('time', 'Experiment duration (sec)', 10)
     414  p.defProperty('dualtest','Do simultaneous Bidirectional Test', true)
     415  p.defProperty('interval', 'Interval between reports',1)
     416  p.defProperty('udp','Use UDP',true)
     417  p.defProperty('reportstyle','report using OML','O')
     418  p.defProperty('bandwidth','target udp bandwidth','20M')
     419  #p.defProperty('stdin','input data to be transmitted from stdin',true) 
     420
     421  # Define the application to be installed on this type of node,
     422  # bind the application properties to the prototype properties,
     423  # and finally, define what measurements should be collected
     424  # for each application.
     425  #
     426  p.addApplication("test:app:new_iperf"){|new_iperf|
     427    new_iperf.bindProperty('client', 'client')
     428    new_iperf.bindProperty('time')
     429    new_iperf.bindProperty('dualtest')
     430    new_iperf.bindProperty('len')
     431    new_iperf.bindProperty('udp')
     432    new_iperf.bindProperty('interval')
     433    new_iperf.bindProperty('reportstyle')
     434    new_iperf.bindProperty('bandwidth')
     435 
     436    new_iperf.measure('transfer', :samples => 1)
     437    new_iperf.measure('packets', :samples =>1)
     438    new_iperf.measure('application', :samples =>1)
     439    new_iperf.measure('settings', :samples=>1)
     440    new_iperf.measure('connection', :samples=>1)
     441    new_iperf.measure('losses', :samples=>1)
     442    new_iperf.measure('jitter', :samples=>1)
     443  }
     444}
     445}}}
     446
     447To gain a better understanding of prototypes and wrappers in OMF, please refer to http://mytestbed.net/wiki/1/How_to_run_an_application_using_Prototypes
     448
     449==== Putting Everything Together ====
     450
     451The following segment of the OEDL, puts all the pieces we described so far together. It basically defines a one-node group that is prepared to run the gps-logging, link-status-monitoring, and bandwidth tests together.
     452
     453{{{
     454defGroup('Actor', property.res1) {|node|
     455  node.prototype("test:proto:new_iperfudpdual", {
     456  'client' => '192.1.240.126',
     457  'interval' => '1',
     458  'time' => 30,
     459  'len' => '1440',
     460  'bandwidth' => '20M'
     461  })
     462
     463  node.addApplication("gpslogger") {|app|
     464    app.measure('gps_data', :interval => 3)
     465  }
     466 
     467  node.addApplication("linkstatus_app") { |app|
     468    app.setProperty('sampling', 5)
     469    app.measure('wimaxstat')
     470  }
     471
     472  node.net.x0.profile = '51'
     473
     474}
     475
     476onEvent(:ALL_UP_AND_INSTALLED) do |event|
     477  wait 5
     478  info "Press enter to continue"
     479  STDIN.gets
     480  group('Actor').startApplications
     481  wait 40
     482  group('Actor').stopApplications
     483  info "Experiment is done. Copying measurements to /home/geni/experiment_logs"
     484  info "Enter prefix: "
     485  prefix=STDIN.gets
     486  prefix.strip!
     487  FileUtils.cp "/tmp/#{Experiment.ID}.sq3" , "/home/geni/experiment_logs/#{prefix}_#{Experiment.ID}.sq3"
     488  info "files copied."
     489  Experiment.done
     490end
     491}}}
     492
     493Note how we have used the prototype and specified bandwidth measurement parameters. The last line, "node.net.x0.profile='51'" is a call to the OMF WiMAX driver to asking to establish a connection with the GENI base-station.
     494
     495Note that at the end of the experiment, we give the chance to the user to prefix the sqlite3 file created by OML. This provides a simple but useful means to annotate the collected data. For example, we have used a naming convention to ease the post-processing of collected data. As we will discuss later, our post-analysis script assumes that the name of the collected sq3 files have the following pattern: point#{i}_*.sq3 . This prefixing chance at the end of the experiment, allows the user to follow this naming convention.
     496
     497==== Using the Visualization Service ====
     498
     499OMF provides  means to visualize the data being collected in real-time. This web based service is available by connecting to port 4000 on the MS (http://localhost:4000) to view the live experiment data being plotted. The next segment of OEDL shows an example of using the visualization service:
     500
     501{{{
     502# support for visualization of data
     503addTab(:defaults)
     504addTab(:graph2) do |tab|
     505  opts = { :postfix => %{This graph shows the amount of data being transferred.}, :updateEvery => 1 }
     506  tab.addGraph("Transfers", opts) do |g|
     507    data = []
     508    mp = ms('iperf_transfer')
     509    mp.project(:oml_ts_server, :size).each do |sample|
     510      time, tr = sample.tuple
     511      data << [time, tr]
     512    end
     513   
     514    g.addLine(data, :label => "Transfer (bytes)")
     515   
     516  end
     517end
     518}}}
     519
     520
     521=== Saving the experiment image ===
     522
     523The experiment described above is a sample. The motivation is for experimenters to develop new experiments using the framework described above. Once the experimenters have modified the scripts and created new experiments on the Wimax MS, they will need to save their work for repeating experiments.
     524
     525- On the OMF aggregate manager machine
     526
     527{{{
     528omf save -n <node_name>
     529}}}
     530
     531- Restart the Wimax MS and the MS will boot from PXE
     532
     533- The image will be saved on the OMF aggregate manager machine under /var/lib/omf-images-5.3
     534
     535- Rename the image and re-use if needed.
     536
     537
     538
     539
     540
     541
     542