omf_ec 6.0.0.pre.3 → 6.0.0.pre.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +1 -0
- data/bin/omf_ec +264 -0
- data/example/engine_oedl.rb +52 -0
- data/example/engine_test.rb +90 -0
- data/example/test_exp/test00.rb +12 -0
- data/example/test_exp/test01.rb +22 -0
- data/example/test_exp/test02.rb +30 -0
- data/{exp_repo/test/exp → example/test_exp}/test03.rb +2 -42
- data/{exp_repo/test/exp → example/test_exp}/test04.rb +2 -2
- data/{exp_repo/test/exp → example/test_exp}/test05.rb +4 -4
- data/{exp_repo/test/exp → example/test_exp}/test06.rb +6 -6
- data/example/test_exp/test07.rb +65 -0
- data/lib/omf_ec/app_definition.rb +57 -0
- data/lib/omf_ec/backward/app_definition.rb +35 -0
- data/lib/omf_ec/backward/core_ext/array.rb +19 -0
- data/lib/omf_ec/backward/default_events.rb +71 -0
- data/lib/omf_ec/backward/dsl.rb +83 -0
- data/lib/omf_ec/backward/exp/testbed.rb +47 -0
- data/lib/omf_ec/backward/group.rb +72 -0
- data/lib/omf_ec/context/app_context.rb +54 -0
- data/lib/omf_ec/context/def_app_context.rb +6 -0
- data/lib/omf_ec/context/group_context.rb +88 -0
- data/lib/omf_ec/context/net_context.rb +46 -0
- data/lib/omf_ec/context.rb +10 -0
- data/lib/omf_ec/dsl.rb +159 -0
- data/lib/omf_ec/experiment.rb +71 -0
- data/lib/omf_ec/group.rb +158 -0
- data/lib/omf_ec/version.rb +1 -1
- data/lib/omf_ec.rb +34 -1
- data/omf_ec.gemspec +2 -3
- data/test/omf_ec/context_spec.rb +19 -0
- data/test/omf_ec/group_spec.rb +14 -0
- data/test/test_helper.rb +19 -0
- metadata +44 -89
- data/bin/omf +0 -147
- data/bin/omf_pre +0 -76
- data/bin/omf_test +0 -161
- data/example/net_devices.rb +0 -75
- data/exp_repo/system/exp/eventlib.rb +0 -96
- data/exp_repo/system/exp/imageNode.rb +0 -283
- data/exp_repo/system/exp/reset.rb +0 -21
- data/exp_repo/system/exp/saveNode.rb +0 -99
- data/exp_repo/system/exp/stat.rb +0 -49
- data/exp_repo/system/exp/stdlib.rb +0 -122
- data/exp_repo/system/exp/tell.rb +0 -53
- data/exp_repo/system/exp/testlib.rb +0 -12
- data/exp_repo/system/exp/winlib.rb +0 -154
- data/exp_repo/system/topo/active.rb +0 -9
- data/exp_repo/system/topo/all.rb +0 -10
- data/exp_repo/system/topo/circle.rb +0 -23
- data/exp_repo/test/app/aodvd.rb +0 -73
- data/exp_repo/test/app/appDef1.rb +0 -102
- data/exp_repo/test/app/athstats.rb +0 -76
- data/exp_repo/test/app/echo.rb +0 -36
- data/exp_repo/test/app/gennyReceiverAppDef.rb +0 -100
- data/exp_repo/test/app/gennySenderAppDef.rb +0 -106
- data/exp_repo/test/app/itgdec.rb +0 -79
- data/exp_repo/test/app/itgr.rb +0 -77
- data/exp_repo/test/app/itgs.rb +0 -105
- data/exp_repo/test/app/nop.rb +0 -36
- data/exp_repo/test/app/otg2.rb +0 -68
- data/exp_repo/test/app/otg2_mp.rb +0 -56
- data/exp_repo/test/app/otr2.rb +0 -56
- data/exp_repo/test/app/otr2_mp.rb +0 -51
- data/exp_repo/test/app/trace_oml2.rb +0 -62
- data/exp_repo/test/app/wlanconfig_oml2.rb +0 -42
- data/exp_repo/test/exp/conf-room-demo.rb +0 -118
- data/exp_repo/test/exp/planetlab.rb +0 -82
- data/exp_repo/test/exp/test01.rb +0 -42
- data/exp_repo/test/exp/test02.rb +0 -60
- data/exp_repo/test/exp/tutorial/hello-world-wired.rb +0 -79
- data/exp_repo/test/exp/tutorial/hello-world-wireless.rb +0 -87
- data/exp_repo/test/exp/tutorial/using-filters.rb +0 -69
- data/exp_repo/test/exp/tutorial/using-groups.rb +0 -64
- data/exp_repo/test/exp/tutorial/using-properties.rb +0 -93
- data/exp_repo/test/exp/tutorial/using-prototypes.rb +0 -111
- data/exp_repo/test/proto/aodvrouter.rb +0 -55
- data/exp_repo/test/proto/driverqueryapp.rb +0 -59
- data/exp_repo/test/proto/forwarder.rb +0 -73
- data/exp_repo/test/proto/itgcbrsender.rb +0 -70
- data/exp_repo/test/proto/itgdecoder.rb +0 -64
- data/exp_repo/test/proto/itgreceiver.rb +0 -55
- data/exp_repo/test/proto/itgvoipsender.rb +0 -64
- data/exp_repo/test/proto/listener2.rb +0 -62
- data/exp_repo/test/proto/nop.rb +0 -47
- data/exp_repo/test/proto/probelink.rb +0 -48
- data/exp_repo/test/proto/raw_receiver.rb +0 -64
- data/exp_repo/test/proto/receiver2_mp.rb +0 -48
- data/exp_repo/test/proto/sender2_mp.rb +0 -54
- data/exp_repo/test/proto/udp_receiver.rb +0 -55
- data/exp_repo/test/proto/udp_sender.rb +0 -61
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'securerandom'
|
|
2
|
+
|
|
3
|
+
module OmfEc
|
|
4
|
+
# Application Definition used in experiment script
|
|
5
|
+
#
|
|
6
|
+
# @!attribute name [String] name of the resource
|
|
7
|
+
class AppDefinition
|
|
8
|
+
|
|
9
|
+
# TODO: eventually this call would mirror all the properties of the App Proxy
|
|
10
|
+
# right now we just have name, binary_path, parameters
|
|
11
|
+
attr_accessor :name, :properties
|
|
12
|
+
|
|
13
|
+
# @param [String] name name of the application to define
|
|
14
|
+
def initialize(name)
|
|
15
|
+
self.name = name
|
|
16
|
+
self.properties = Hash.new
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Add new parameter(s) to this Application Definition
|
|
20
|
+
#
|
|
21
|
+
# @param [Hash] params a hash with the parameters to add
|
|
22
|
+
#
|
|
23
|
+
def define_parameter(params)
|
|
24
|
+
@properties[:parameters] = Hash.new unless @properties.key?(:parameters)
|
|
25
|
+
if params.kind_of? Hash
|
|
26
|
+
@properties[:parameters].merge!(params)
|
|
27
|
+
else
|
|
28
|
+
error "Cannot define parameter for app '#{self.name}'! Parameter "+
|
|
29
|
+
"not passed as a Hash ('#{params.inspect}')"
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def define_measurement_point(mp)
|
|
34
|
+
@properties[:oml] = Hash.new unless @properties.key?(:oml)
|
|
35
|
+
if mp.kind_of? Hash
|
|
36
|
+
@properties[:oml][:available_mps] = Array.new unless @properties[:oml].key?(:available_mps)
|
|
37
|
+
@properties[:oml][:available_mps] << mp
|
|
38
|
+
else
|
|
39
|
+
error "Cannot define Measurement Point for app '#{self.name}'! MP "+
|
|
40
|
+
"not passed as a Hash ('#{mp.inspect}')"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def method_missing(method_name, *args)
|
|
45
|
+
k = method_name.to_sym
|
|
46
|
+
return @properties[k] if @properties.key?(k)
|
|
47
|
+
m = method_name.to_s.match(/(.*?)([=]?)$/)
|
|
48
|
+
if m[2] == '='
|
|
49
|
+
@properties[m[1].to_sym] = args.first
|
|
50
|
+
else
|
|
51
|
+
super
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
include OmfEc::Backward::AppDefinition
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module OmfEc
|
|
2
|
+
module Backward
|
|
3
|
+
module AppDefinition
|
|
4
|
+
# The following are ODEL 5 methods
|
|
5
|
+
|
|
6
|
+
# Add a new parameter to this Application Definition
|
|
7
|
+
# This method is for backward compatibility with previous OEDL 5
|
|
8
|
+
#
|
|
9
|
+
# @param [String] name name of the application to define
|
|
10
|
+
def defProperty(name = :mandatory, description = nil, parameter = nil, options = {})
|
|
11
|
+
opts = {:description => description, :cmd => parameter}
|
|
12
|
+
# Map old OMF5 types to OMF6
|
|
13
|
+
options[:type] = 'Numeric' if options[:type] == :integer
|
|
14
|
+
options[:type] = 'String' if options[:type] == :string
|
|
15
|
+
options[:type] = 'Boolean' if options[:type] == :boolean
|
|
16
|
+
opts = opts.merge(options)
|
|
17
|
+
define_parameter(Hash[name,opts])
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def defMetric(name,type)
|
|
21
|
+
@fields << {:field => name, :type => type}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def defMeasurement(name,&block)
|
|
25
|
+
mp = {:mp => name, :fields => []}
|
|
26
|
+
@fields = []
|
|
27
|
+
# call the block with ourserlves to process its 'defMetric' statements
|
|
28
|
+
block.call(self) if block
|
|
29
|
+
@fields.each { |f| mp[:fields] << f }
|
|
30
|
+
define_measurement_point(mp)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
class Array
|
|
2
|
+
def startApplications
|
|
3
|
+
if !self.empty? && self.all? { |v| v.class == OmfEc::Group }
|
|
4
|
+
self.each { |g| g.startApplications }
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def stopApplications
|
|
9
|
+
if !self.empty? && self.all? { |v| v.class == OmfEc::Group }
|
|
10
|
+
self.each { |g| g.stopApplications }
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def exec(name)
|
|
15
|
+
if !self.empty? && self.all? { |v| v.class == OmfEc::Group }
|
|
16
|
+
self.each { |g| g.exec(name) }
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module OmfEc
|
|
2
|
+
module Backward
|
|
3
|
+
module DefaultEvents
|
|
4
|
+
|
|
5
|
+
class << self
|
|
6
|
+
def included(base)
|
|
7
|
+
base.instance_eval do
|
|
8
|
+
|
|
9
|
+
def_event :ALL_UP do |state|
|
|
10
|
+
!all_groups.empty? && all_groups.all? do |g|
|
|
11
|
+
plan = g.members.uniq.sort
|
|
12
|
+
actual = state.find_all do |v|
|
|
13
|
+
v[:membership] && v[:membership].include?(g.id)
|
|
14
|
+
end.map { |v| v[:uid] }.sort
|
|
15
|
+
plan == actual
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
on_event :ALL_UP do
|
|
20
|
+
all_groups do |group|
|
|
21
|
+
# Deal with brilliant net.w0.ip syntax...
|
|
22
|
+
group.net_ifs && group.net_ifs.each do |nif|
|
|
23
|
+
nif.map_channel_freq
|
|
24
|
+
r_type = nif.conf[:type]
|
|
25
|
+
r_hrn = nif.conf[:hrn]
|
|
26
|
+
r_index = nif.conf[:index]
|
|
27
|
+
|
|
28
|
+
conf_to_send =
|
|
29
|
+
if r_type == 'wlan'
|
|
30
|
+
{ type: r_type,
|
|
31
|
+
mode: nif.conf.merge(:phy => "<%= request_wlan_devices[#{r_index}][:name] %>").except(:hrn, :type, :index)
|
|
32
|
+
}
|
|
33
|
+
else
|
|
34
|
+
nif.conf.merge(type: r_type).except(:index)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
group.create_resource(r_hrn, conf_to_send)
|
|
38
|
+
end
|
|
39
|
+
# Create proxies for each apps that were added to this group
|
|
40
|
+
group.app_contexts.each { |a| group.create_resource(a.name, a.properties) }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def_event :ALL_INTERFACE_UP do |state|
|
|
45
|
+
!all_groups.empty? && all_groups.all? do |g|
|
|
46
|
+
plan = g.net_ifs.map { |v| v.conf[:hrn] }.uniq.size * g.members.uniq.size
|
|
47
|
+
actual = state.find_all do |v|
|
|
48
|
+
v[:membership] &&
|
|
49
|
+
(v[:membership].include?("#{g.id}_wlan") || v[:membership].include?("#{g.id}_net"))
|
|
50
|
+
end.size
|
|
51
|
+
plan == actual
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def_event :ALL_UP_AND_INSTALLED do |state|
|
|
56
|
+
!all_groups.empty? && all_groups.all? do |g|
|
|
57
|
+
plan = g.app_contexts.size * g.members.uniq.size
|
|
58
|
+
actual = state.find_all do |v|
|
|
59
|
+
v[:membership] && v[:membership].include?("#{g.id}_application")
|
|
60
|
+
end.size
|
|
61
|
+
plan == actual
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module OmfEc
|
|
2
|
+
module Backward
|
|
3
|
+
module DSL
|
|
4
|
+
class << self
|
|
5
|
+
def included(base)
|
|
6
|
+
v5_style(:defProperty, base)
|
|
7
|
+
v5_style(:defEvent, base)
|
|
8
|
+
v5_style(:onEvent, base)
|
|
9
|
+
v5_style(:allEqual, base)
|
|
10
|
+
v5_style(:onEvent, base)
|
|
11
|
+
v5_style(:allGroups, base)
|
|
12
|
+
v5_style(:allNodes!, base)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def v5_style(name, base)
|
|
16
|
+
new_name = name.to_s.underscore.to_sym
|
|
17
|
+
unless method_defined? new_name
|
|
18
|
+
base.class_eval do
|
|
19
|
+
alias_method name, new_name
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def defApplication(uri,name,&block)
|
|
26
|
+
# URI parameter was used by previous OMF5 EC, for now we
|
|
27
|
+
# do nothing with it in OMF6
|
|
28
|
+
def_application(name,&block)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def defGroup(name, *members, &block)
|
|
32
|
+
group = OmfEc::Group.new(name)
|
|
33
|
+
OmfEc.exp.groups << group
|
|
34
|
+
|
|
35
|
+
members.each do |m|
|
|
36
|
+
m_group = OmfEc.exp.groups.find { |v| v.name == m }
|
|
37
|
+
if m_group
|
|
38
|
+
group.members += m_group.members
|
|
39
|
+
else
|
|
40
|
+
group.members << m
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
block.call(group) if block
|
|
45
|
+
|
|
46
|
+
OmfEc.comm.subscribe(group.id, create_if_non_existent: true) do |m|
|
|
47
|
+
unless m.error?
|
|
48
|
+
members.each do |m|
|
|
49
|
+
group.add_resource(m)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
rg = OmfEc.comm.get_topic(group.id)
|
|
53
|
+
|
|
54
|
+
rg.on_message lambda {|m| m.operation == :inform && m.read_content('inform_type') == 'FAILED' && m.context_id.nil? } do |i|
|
|
55
|
+
warn "RC reports failure: '#{i.read_content("reason")}'"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
rg.on_message lambda {|m| m.operation == :inform && m.read_content('inform_type') == 'STATUS' && m.context_id.nil? } do |i|
|
|
59
|
+
r = OmfEc.exp.state.find { |v| v[:uid] == i.read_property(:uid) }
|
|
60
|
+
unless r.nil?
|
|
61
|
+
i.each_property do |p|
|
|
62
|
+
key = p.attr('key').to_sym
|
|
63
|
+
r[key] = i.read_property(key)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
Experiment.instance.process_events
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Wait for some time before issuing more commands
|
|
73
|
+
#
|
|
74
|
+
# @param [Fixnum] duration Time to wait in seconds (can be
|
|
75
|
+
#
|
|
76
|
+
def wait(duration)
|
|
77
|
+
info "Request from Experiment Script: Wait for #{duration}s...."
|
|
78
|
+
warn "Calling 'wait' or 'sleep' will block entire EC event loop. Please try 'after' or 'every'"
|
|
79
|
+
sleep duration
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
comm = OmfEc.comm
|
|
2
|
+
|
|
3
|
+
testbed_topic = comm.get_topic('testbed')
|
|
4
|
+
|
|
5
|
+
msgs = {
|
|
6
|
+
create: comm.create_message([type: 'application']),
|
|
7
|
+
req_platform: comm.request_message([:platform]),
|
|
8
|
+
conf_path: comm.configure_message([binary_path: @cmd]),
|
|
9
|
+
run_application: comm.configure_message([state: :run])
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
msgs[:create].on_inform_created do |message|
|
|
13
|
+
app_topic = comm.get_topic(message.resource_id)
|
|
14
|
+
app_topic.subscribe do
|
|
15
|
+
msgs[:req_platform].publish app_topic.id
|
|
16
|
+
sleep 1
|
|
17
|
+
msgs[:conf_path].publish app_topic.id
|
|
18
|
+
sleep 1
|
|
19
|
+
msgs[:run_application].publish app_topic.id
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
app_topic.on_message do |m|
|
|
23
|
+
if m.operation == :inform
|
|
24
|
+
case m.read_content("inform_type")
|
|
25
|
+
when 'STATUS'
|
|
26
|
+
if m.read_property("status_type") == 'APP_EVENT'
|
|
27
|
+
after (2) { comm.disconnect } if m.read_property("event") =~ /DONE.(OK|ERROR)/
|
|
28
|
+
puts m.read_property("msg")
|
|
29
|
+
end
|
|
30
|
+
when 'ERROR'
|
|
31
|
+
logger.error m.read_content('reason') if m.read_content("inform_type") == 'ERROR'
|
|
32
|
+
when 'WARN'
|
|
33
|
+
logger.warn m.read_content('reason') if m.read_content("inform_type") == 'WARN'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
msgs[:req_platform].on_inform_status do |m|
|
|
40
|
+
m.each_property do |p|
|
|
41
|
+
logger.info "#{p.attr('key')} => #{p.content.strip}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
testbed_topic.subscribe do
|
|
46
|
+
msgs[:create].publish testbed_topic.id
|
|
47
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
require 'securerandom'
|
|
2
|
+
|
|
3
|
+
module OmfEc
|
|
4
|
+
module Backward
|
|
5
|
+
module Group
|
|
6
|
+
# The following are ODEL 5 methods
|
|
7
|
+
|
|
8
|
+
# Create an application for the group and start it
|
|
9
|
+
#
|
|
10
|
+
def exec(name)
|
|
11
|
+
create_resource(name, type: 'application', binary_path: name)
|
|
12
|
+
|
|
13
|
+
e_uid = SecureRandom.uuid
|
|
14
|
+
|
|
15
|
+
e_name = "#{self.name}_application_#{name}_created_#{e_uid}"
|
|
16
|
+
|
|
17
|
+
def_event e_name do |state|
|
|
18
|
+
state.find_all { |v| v[:hrn] == name }.size >= self.members.uniq.size
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
on_event e_name do
|
|
22
|
+
resources[type: 'application', name: name].state = :run
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def startApplications
|
|
27
|
+
resources[type: 'application'].state = :run
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def stopApplications
|
|
31
|
+
resources[type: 'application'].state = :stop
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def addApplication(name, &block)
|
|
35
|
+
app_cxt = OmfEc::Context::AppContext.new(name)
|
|
36
|
+
block.call(app_cxt) if block
|
|
37
|
+
self.app_contexts << app_cxt
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @example
|
|
41
|
+
# group('actor', 'node1', 'node2') do |g|
|
|
42
|
+
# g.net.w0.ip = '0.0.0.0'
|
|
43
|
+
# g.net.e0.ip = '0.0.0.1'
|
|
44
|
+
# end
|
|
45
|
+
def net
|
|
46
|
+
self.net_ifs ||= []
|
|
47
|
+
self
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def method_missing(name, *args, &block)
|
|
51
|
+
if name =~ /w(\d+)/
|
|
52
|
+
net = self.net_ifs.find { |v| v.conf[:hrn] == "wlan#{$1}" }
|
|
53
|
+
if net.nil?
|
|
54
|
+
net = OmfEc::Context::NetContext.new(:type => 'wlan', :hrn => "wlan#{$1}", :index => $1)
|
|
55
|
+
self.net_ifs << net
|
|
56
|
+
end
|
|
57
|
+
net
|
|
58
|
+
elsif name =~ /e(\d+)/
|
|
59
|
+
net = self.net_ifs.find { |v| v.conf[:hrn] == "eth#{$1}" }
|
|
60
|
+
if net.nil?
|
|
61
|
+
net = OmfEc::Context::NetContext.new(:type => 'net', :hrn => "eth#{$1}", :index => $1)
|
|
62
|
+
self.net_ifs << net
|
|
63
|
+
end
|
|
64
|
+
net
|
|
65
|
+
else
|
|
66
|
+
super
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module OmfEc::Context
|
|
2
|
+
class AppContext
|
|
3
|
+
attr_accessor :name, :app_def, :param_values, :oml_collections
|
|
4
|
+
|
|
5
|
+
# Keep track of contexts for each app, i.e. multiple contexts can share
|
|
6
|
+
# the same app def. This happens for example when a group can have the
|
|
7
|
+
# same applications added to it many times, but with different parameter
|
|
8
|
+
# values for each. Thus we need to distinguish these different context
|
|
9
|
+
@@context_count = Hash.new
|
|
10
|
+
|
|
11
|
+
def initialize(name)
|
|
12
|
+
if OmfEc.exp.app_definitions.key?(name)
|
|
13
|
+
self.app_def = OmfEc.exp.app_definitions[name]
|
|
14
|
+
self.param_values = Hash.new
|
|
15
|
+
self.oml_collections = Array.new
|
|
16
|
+
@@context_count[name] = 0 unless @@context_count.key?(name)
|
|
17
|
+
id = @@context_count[name]
|
|
18
|
+
@@context_count[name] += 1
|
|
19
|
+
self.name = "#{name}_cxt_#{id}"
|
|
20
|
+
self
|
|
21
|
+
else
|
|
22
|
+
raise RuntimeError, "Cannot create context for unknwon application '#{name}'"
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def setProperty(key, value)
|
|
27
|
+
@param_values[key] = value
|
|
28
|
+
self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# For now this follows v5.4 syntax...
|
|
32
|
+
# We have not yet finalised an OML syntax inside OEDL for v6
|
|
33
|
+
def measure(mp,filters)
|
|
34
|
+
collection = {:url => OmfEc.exp.oml_uri, :streams => [] }
|
|
35
|
+
stream = { :mp => mp , :filters => [] }.merge(filters)
|
|
36
|
+
collection[:streams] << stream
|
|
37
|
+
@oml_collections << collection
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def properties
|
|
41
|
+
# deep copy the properties from the our app definition
|
|
42
|
+
original = Marshal.load(Marshal.dump(app_def.properties))
|
|
43
|
+
p = original.merge({:type => 'application'})
|
|
44
|
+
@param_values.each { |k,v| p[:parameters][k][:value] = v if p[:parameters].key?(k) }
|
|
45
|
+
if @oml_collections.size > 0
|
|
46
|
+
p[:use_oml] = true
|
|
47
|
+
p[:oml][:id] = @name
|
|
48
|
+
p[:oml][:experiment] = OmfEc.exp.id
|
|
49
|
+
p[:oml][:collection] = @oml_collections
|
|
50
|
+
end
|
|
51
|
+
p
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module OmfEc::Context
|
|
2
|
+
class GroupContext
|
|
3
|
+
attr_accessor :group
|
|
4
|
+
attr_accessor :guard
|
|
5
|
+
attr_accessor :operation
|
|
6
|
+
|
|
7
|
+
def initialize(opts)
|
|
8
|
+
self.group = opts.delete(:group)
|
|
9
|
+
self.guard = opts
|
|
10
|
+
self
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def [](opts = {})
|
|
14
|
+
self.guard.merge!(opts)
|
|
15
|
+
self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def method_missing(name, *args, &block)
|
|
19
|
+
if name =~ /(.+)=/
|
|
20
|
+
self.operation = :configure
|
|
21
|
+
name = $1
|
|
22
|
+
elsif name =~ /release/
|
|
23
|
+
self.operation = :release
|
|
24
|
+
else
|
|
25
|
+
self.operation = :request
|
|
26
|
+
end
|
|
27
|
+
send_message(name, *args, &block)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def send_message(name, value = nil, &block)
|
|
31
|
+
send_to = self.group
|
|
32
|
+
send_to = send_to + "_#{self.guard[:type]}" if self.guard[:type]
|
|
33
|
+
|
|
34
|
+
# if release, we need to request resource ids first
|
|
35
|
+
op_name = self.operation == :release ? "request_message" : "#{self.operation}_message"
|
|
36
|
+
|
|
37
|
+
o_m = OmfEc.comm.__send__(op_name, send_to) do |m|
|
|
38
|
+
m.element(:guard) do |g|
|
|
39
|
+
self.guard.each_pair do |k, v|
|
|
40
|
+
g.property(k, v)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
unless self.operation == :release
|
|
45
|
+
m.property(name, value)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
unless self.operation == :configure
|
|
49
|
+
m.property(:uid)
|
|
50
|
+
m.property(:hrn)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
o_m.publish send_to
|
|
55
|
+
|
|
56
|
+
o_m.on_inform_status do |i|
|
|
57
|
+
if self.operation == :release
|
|
58
|
+
uid = i.read_property(:uid)
|
|
59
|
+
info "Going to release #{uid}"
|
|
60
|
+
release_m = OmfEc.comm.release_message(self.group) { |m| m.element('resource_id', uid) }
|
|
61
|
+
|
|
62
|
+
release_m.publish self.group
|
|
63
|
+
|
|
64
|
+
release_m.on_inform_released do |m|
|
|
65
|
+
info "#{m.resource_id} released"
|
|
66
|
+
r = OmfEc.exp.state.find { |v| v[:uid] == m.resource_id }
|
|
67
|
+
r[:released] = true unless r.nil?
|
|
68
|
+
block.call if block
|
|
69
|
+
Experiment.instance.process_events
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
r = OmfEc.exp.state.find { |v| v[:uid] == i.read_property(:uid) }
|
|
74
|
+
unless r.nil?
|
|
75
|
+
i.each_property do |p|
|
|
76
|
+
p_key = p.attr('key').to_sym
|
|
77
|
+
r[p_key] = i.read_property(p_key)
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
Experiment.instance.process_events
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
o_m.on_inform_failed do |i|
|
|
84
|
+
warn "RC reports failure: '#{i.read_content("reason")}'"
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module OmfEc::Context
|
|
2
|
+
class NetContext
|
|
3
|
+
# Wifi frequency channel matching
|
|
4
|
+
FREQUENCY= {
|
|
5
|
+
1 => 2412, 2 => 2417, 3 => 2422, 4 => 2427, 5 => 2432, 6 => 2437,
|
|
6
|
+
7 => 2442, 8 => 2447, 9 => 2452, 10 => 2457, 11 => 2462, 12 => 2467,
|
|
7
|
+
13 => 2472, 14 => 2484, 36 => 5180, 40 => 5200, 44 => 5220, 48 => 5240,
|
|
8
|
+
52 => 5260, 56 => 5280, 60 => 5300, 64 => 5320, 100 => 5500, 104 => 5520,
|
|
9
|
+
108 => 5540, 112 => 5560, 116 => 5580, 120 => 5600, 124 => 5620, 128 => 5640,
|
|
10
|
+
132 => 5660, 136 => 5680, 140 => 5700, 149 => 5745, 153 => 5765, 157 => 5785,
|
|
11
|
+
161 => 5805, 165 => 5825
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
attr_accessor :conf
|
|
15
|
+
|
|
16
|
+
def initialize(opts)
|
|
17
|
+
self.conf = opts
|
|
18
|
+
self
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def method_missing(name, *args, &block)
|
|
22
|
+
if name =~ /(.+)=/
|
|
23
|
+
net_prop = $1.to_sym
|
|
24
|
+
net_prop = case net_prop
|
|
25
|
+
when :type then :hw_mode
|
|
26
|
+
when :ip then :ip_addr
|
|
27
|
+
else
|
|
28
|
+
net_prop
|
|
29
|
+
end
|
|
30
|
+
self.conf.merge!(net_prop => args[0])
|
|
31
|
+
else
|
|
32
|
+
super
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def map_channel_freq
|
|
37
|
+
if self.conf[:channel] && self.conf[:frequency].nil?
|
|
38
|
+
self.conf[:frequency] = FREQUENCY[self.conf[:channel].to_i]
|
|
39
|
+
end
|
|
40
|
+
if self.conf[:channel].nil? && self.conf[:frequency]
|
|
41
|
+
self.conf[:channel] = FREQUENCY.keys.find { |k| FREQUENCY[k] == self.conf[:frequency].to_i }
|
|
42
|
+
end
|
|
43
|
+
self
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|