omf_ec 6.1.4.pre.2 → 6.1.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.
- checksums.yaml +7 -0
- data/Gemfile +4 -1
- data/example/config/logging_to_oml.yml +5 -5
- data/example/config/with_custom_logging.yml +6 -6
- data/lib/omf_ec/backward/app_definition.rb +2 -0
- data/lib/omf_ec/backward/default_events.rb +4 -2
- data/lib/omf_ec/context/app_context.rb +8 -3
- data/lib/omf_ec/dsl.rb +9 -0
- data/lib/omf_ec/experiment.rb +5 -0
- data/lib/omf_ec/experiment_property.rb +2 -2
- data/lib/omf_ec/group.rb +18 -0
- data/lib/omf_ec/parameter.rb +48 -0
- data/lib/omf_ec/property.rb +172 -0
- data/lib/omf_ec/prototype.rb +232 -0
- data/lib/omf_ec/runner.rb +3 -3
- data/lib/omf_ec.rb +1 -0
- metadata +35 -39
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 771993407e8b4d1cfb88ea8863d2d8693eb67dc4
|
|
4
|
+
data.tar.gz: 829d83eaa6c6d17df8c2ddab66ddea1ad42f028d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d412ccbfae115220d733f494845de3833e29d7444a9093ce2cf05c109cf234b4c5825f3347e88899eb6d9279948a2bd2ac9b4c774e3932630522a02fda4afc3d
|
|
7
|
+
data.tar.gz: f96fbb4334636616db143256a9acfa50f8eff2ed25fbd1071c4a4935bdf594996850229f62aba3c9517bb82d9e8882b009bbab64cd941c068664e2549f49d4e0
|
data/Gemfile
CHANGED
|
@@ -17,17 +17,17 @@ logging:
|
|
|
17
17
|
rolling_file:
|
|
18
18
|
level: all
|
|
19
19
|
log_dir: /var/tmp
|
|
20
|
-
# max
|
|
21
|
-
size:
|
|
22
|
-
# keep
|
|
23
|
-
keep:
|
|
20
|
+
# max 10k of each log file
|
|
21
|
+
size: 10240
|
|
22
|
+
# keep 1 log in total
|
|
23
|
+
keep: 1
|
|
24
24
|
date_pattern: "%F %T %z"
|
|
25
25
|
pattern: "[%d] %-5l %c: %m\n"
|
|
26
26
|
# To OML is enabled by default when oml_uri option is SET
|
|
27
27
|
# Uncomment this if you need to change the default
|
|
28
28
|
#
|
|
29
29
|
# oml4r:
|
|
30
|
-
# level:
|
|
30
|
+
# level: debug
|
|
31
31
|
# appName: 'omf_ec'
|
|
32
32
|
# domain: '<%= OmfEc.experiment.id %>'
|
|
33
33
|
# collect: tcp:some_other_oml_server:3003
|
|
@@ -14,17 +14,17 @@ logging:
|
|
|
14
14
|
date_pattern: "%H:%M:%S"
|
|
15
15
|
pattern: "%d %5l %c{2}: %m\n"
|
|
16
16
|
# To turn colour on use color_scheme: default
|
|
17
|
-
color_scheme:
|
|
17
|
+
color_scheme: none
|
|
18
18
|
# To Rolling log file, and log everything
|
|
19
19
|
rolling_file:
|
|
20
20
|
level: all
|
|
21
21
|
log_dir: /var/tmp
|
|
22
|
-
# max
|
|
23
|
-
size:
|
|
24
|
-
# keep
|
|
25
|
-
keep:
|
|
22
|
+
# max 10k of each log file
|
|
23
|
+
size: 10240
|
|
24
|
+
# keep 1 log in total
|
|
25
|
+
keep: 1
|
|
26
26
|
date_pattern: "%F %T %z"
|
|
27
27
|
pattern: "[%d] %-5l %c: %m\n"
|
|
28
28
|
|
|
29
29
|
# Use OML server located at localhost port 3003
|
|
30
|
-
|
|
30
|
+
oml_uri: tcp:localhost:3003
|
|
@@ -39,7 +39,7 @@ module OmfEc
|
|
|
39
39
|
results = []
|
|
40
40
|
all_groups? do |g|
|
|
41
41
|
plan = g.app_contexts.size * g.members.values.uniq.size
|
|
42
|
-
actual = state.count { |v| v.joined?(g.address("application")) }
|
|
42
|
+
actual = state.count { |v| v.joined?(g.address("application")) && v[:state] == "stopped" }
|
|
43
43
|
results << (plan == actual) unless (plan == 0)
|
|
44
44
|
end
|
|
45
45
|
!results.include?(false)
|
|
@@ -89,10 +89,12 @@ module OmfEc
|
|
|
89
89
|
all_nodes_up?(state) && all_interfaces_ready?(state)
|
|
90
90
|
end
|
|
91
91
|
|
|
92
|
-
def_event :
|
|
92
|
+
def_event :ALL_APPS_UP do |state|
|
|
93
93
|
all_nodes_up?(state) && all_apps_ready?(state)
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
+
alias_event :ALL_UP_AND_INSTALLED, :ALL_APPS_UP
|
|
97
|
+
|
|
96
98
|
def_event :ALL_APPS_DONE do |state|
|
|
97
99
|
all_nodes_up?(state) &&
|
|
98
100
|
all_groups? do |g|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
module OmfEc::Context
|
|
7
7
|
# Holds application configuration
|
|
8
8
|
class AppContext
|
|
9
|
-
attr_accessor :name, :app_def, :param_values, :oml_collections
|
|
9
|
+
attr_accessor :name, :app_def, :param_values, :oml_collections, :proto_props
|
|
10
10
|
|
|
11
11
|
# Keep track of contexts for each app, i.e. multiple contexts can share
|
|
12
12
|
# the same app def. This happens for example when a group can have the
|
|
@@ -57,13 +57,18 @@ module OmfEc::Context
|
|
|
57
57
|
self
|
|
58
58
|
end
|
|
59
59
|
|
|
60
|
+
def bindProperty(prop_name, prop_ref = prop_name)
|
|
61
|
+
@proto_props ||= Hashie::Mash.new
|
|
62
|
+
@proto_props[prop_name] = prop_ref
|
|
63
|
+
end
|
|
64
|
+
|
|
60
65
|
# For now this follows v5.4 syntax...
|
|
61
66
|
# We have not yet finalised an OML syntax inside OEDL for v6
|
|
62
67
|
# TODO: v6 currently does not support OML filters. Formerly in v5.x, these
|
|
63
68
|
# filters were defined in an optional block.
|
|
64
69
|
def measure(mp, opts, &block)
|
|
65
70
|
collect_point = opts.delete(:collect)
|
|
66
|
-
collect_point ||= OmfEc.experiment.oml_uri
|
|
71
|
+
collect_point ||= OmfEc.experiment.oml_uri
|
|
67
72
|
if collect_point.nil?
|
|
68
73
|
warn "No OML URI configured for measurement collection! "+
|
|
69
74
|
"(see option 'oml_uri'). Disabling OML Collection for '#{mp}'."
|
|
@@ -83,7 +88,7 @@ module OmfEc::Context
|
|
|
83
88
|
# - if this context's param_values has a property which also exists in
|
|
84
89
|
# the app def and if that property has an assigned value, then
|
|
85
90
|
# use that value for the properties of this context
|
|
86
|
-
p = original.merge({:
|
|
91
|
+
p = original.merge({type: 'application', state: 'stopped'})
|
|
87
92
|
@param_values.each do |k,v|
|
|
88
93
|
if p[:parameters].key?(k)
|
|
89
94
|
p[:parameters][k][:value] = v.kind_of?(OmfEc::ExperimentProperty) ? v.value : v
|
data/lib/omf_ec/dsl.rb
CHANGED
|
@@ -311,5 +311,14 @@ module OmfEc
|
|
|
311
311
|
end
|
|
312
312
|
end
|
|
313
313
|
|
|
314
|
+
# Define a new prototype. The supplied block is executed with the new Prototype instance as a single argument.
|
|
315
|
+
#
|
|
316
|
+
# @param refName reference name for this property
|
|
317
|
+
# @param name optional, short/easy to remember name for this property
|
|
318
|
+
def defPrototype(refName, name = nil, &block)
|
|
319
|
+
p = Prototype.create(refName)
|
|
320
|
+
p.name = name
|
|
321
|
+
block.call(p)
|
|
322
|
+
end
|
|
314
323
|
end
|
|
315
324
|
end
|
data/lib/omf_ec/experiment.rb
CHANGED
|
@@ -157,6 +157,11 @@ module OmfEc
|
|
|
157
157
|
@name || @id
|
|
158
158
|
end
|
|
159
159
|
|
|
160
|
+
# Unique experiment id (Class method)
|
|
161
|
+
def self.ID
|
|
162
|
+
instance.id
|
|
163
|
+
end
|
|
164
|
+
|
|
160
165
|
# Parsing user defined events, checking conditions against internal state, and execute callbacks if triggered
|
|
161
166
|
def process_events
|
|
162
167
|
self.synchronize do
|
|
@@ -12,7 +12,7 @@ module OmfEc
|
|
|
12
12
|
# Experiment Properties defined for a given experiment.
|
|
13
13
|
# Most of this implementation is re-used from OMF 5.4
|
|
14
14
|
#
|
|
15
|
-
class
|
|
15
|
+
class ExperimentProperty
|
|
16
16
|
|
|
17
17
|
# Contains all the experiment properties
|
|
18
18
|
@@properties = Hashie::Mash.new
|
|
@@ -166,7 +166,7 @@ module OmfEc
|
|
|
166
166
|
# Implicit conversion to String (required for + operator)
|
|
167
167
|
def to_str() @value.to_s end
|
|
168
168
|
|
|
169
|
-
# More convenient conversion
|
|
169
|
+
# More convenient conversion
|
|
170
170
|
def to_f() @value.to_f end
|
|
171
171
|
def to_i() @value.to_i end
|
|
172
172
|
|
data/lib/omf_ec/group.rb
CHANGED
|
@@ -109,6 +109,24 @@ module OmfEc
|
|
|
109
109
|
OmfEc::Context::GroupContext.new(group: self)
|
|
110
110
|
end
|
|
111
111
|
|
|
112
|
+
# Add a new Prototype to the NodeSet associated with this Root Path
|
|
113
|
+
#
|
|
114
|
+
# - name = name of the Prototype to associate with the NodeSet of this Path
|
|
115
|
+
# - params = optional, a Hash with the bindings to be passed on to the
|
|
116
|
+
#
|
|
117
|
+
# Prototype instance (see Prototype.instantiate)
|
|
118
|
+
def addPrototype(name, params = nil)
|
|
119
|
+
debug "Use prototype #{name}."
|
|
120
|
+
p = OmfEc::Prototype[name]
|
|
121
|
+
if p.nil?
|
|
122
|
+
error "Unknown prototype '#{name}'"
|
|
123
|
+
return
|
|
124
|
+
end
|
|
125
|
+
p.instantiate(self, params)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
alias_method :prototype, :addPrototype
|
|
129
|
+
|
|
112
130
|
include OmfEc::Backward::Group
|
|
113
131
|
end
|
|
114
132
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright (c) 2006-2009 National ICT Australia (NICTA), Australia
|
|
2
|
+
# This software may be used and distributed solely under the terms of the MIT license (License).
|
|
3
|
+
# You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
|
|
4
|
+
# By downloading or using this software you accept the terms and the liability disclaimer in the License.
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2004-2009 WINLAB, Rutgers University, USA
|
|
7
|
+
|
|
8
|
+
module OmfEc
|
|
9
|
+
# This class describes a Parameter
|
|
10
|
+
class Parameter
|
|
11
|
+
|
|
12
|
+
attr_reader :id, :name, :description, :defaultValue
|
|
13
|
+
|
|
14
|
+
#
|
|
15
|
+
# Create a new Parameter instance
|
|
16
|
+
#
|
|
17
|
+
# - id = parameter identifier
|
|
18
|
+
# - name = name for this parameter
|
|
19
|
+
# - description = short description of this parameter
|
|
20
|
+
# - defaultValue = optional, a defautl value for this parameter (default=nil)
|
|
21
|
+
#
|
|
22
|
+
def initialize(id, name, description, defaultValue = nil)
|
|
23
|
+
@id = id
|
|
24
|
+
@name = name != nil ? name : id
|
|
25
|
+
@description = description
|
|
26
|
+
@defaultValue = defaultValue
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# Return the definition of this Parameter as an XML element
|
|
31
|
+
#
|
|
32
|
+
# [Return] an XML element with the definition of this Parameter
|
|
33
|
+
#
|
|
34
|
+
def to_xml
|
|
35
|
+
a = REXML::Element.new("parameter")
|
|
36
|
+
a.add_attribute("id", id)
|
|
37
|
+
a.add_attribute("name", name)
|
|
38
|
+
if (description != nil)
|
|
39
|
+
a.add_element("description").text = description
|
|
40
|
+
end
|
|
41
|
+
if (defaultValue != nil)
|
|
42
|
+
a.add_element("default").text = defaultValue
|
|
43
|
+
end
|
|
44
|
+
return a
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (c) 2006-2009 National ICT Australia (NICTA), Australia
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2004-2009 WINLAB, Rutgers University, USA
|
|
5
|
+
#
|
|
6
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
# in the Software without restriction, including without limitation the rights
|
|
9
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
# furnished to do so, subject to the following conditions:
|
|
12
|
+
#
|
|
13
|
+
# The above copyright notice and this permission notice shall be included in
|
|
14
|
+
# all copies or substantial portions of the Software.
|
|
15
|
+
#
|
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
# THE SOFTWARE.
|
|
23
|
+
#
|
|
24
|
+
#
|
|
25
|
+
module OmfEc
|
|
26
|
+
# This class describes a Property, which is part of a Prototype
|
|
27
|
+
class Property
|
|
28
|
+
|
|
29
|
+
#
|
|
30
|
+
# Unmarshall a Property instance from an XML tree.
|
|
31
|
+
#
|
|
32
|
+
# - defRoot = the root of the XML tree describing the Property
|
|
33
|
+
#
|
|
34
|
+
# [Return] a new Property instance initialized with the information from the XML tree
|
|
35
|
+
#
|
|
36
|
+
def self.from_xml(defRoot)
|
|
37
|
+
if (defRoot.name != "property")
|
|
38
|
+
raise "Property definition needs to start with an 'property' element"
|
|
39
|
+
end
|
|
40
|
+
idref = defRoot.attributes['idref']
|
|
41
|
+
obj = unit = nil
|
|
42
|
+
isBinding = false
|
|
43
|
+
defRoot.elements.each { |el|
|
|
44
|
+
case el.name
|
|
45
|
+
when 'binding'
|
|
46
|
+
obj = el.attribute['idref']
|
|
47
|
+
isBinding = true
|
|
48
|
+
when 'value'
|
|
49
|
+
obj = el.text
|
|
50
|
+
unit = el.attribute['unit']
|
|
51
|
+
else
|
|
52
|
+
warn "Ignoring element '#{el.name}'"
|
|
53
|
+
end
|
|
54
|
+
}
|
|
55
|
+
if isBinding then warn "NOT IMPLEMENTED: Resolving bindings from XML streams" end
|
|
56
|
+
p = self.new(idred, obj, unit, isBinding)
|
|
57
|
+
return p
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
attr_reader :idref, :value, :unit, :bindingRef, :isBound
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
# Create a new Property instance
|
|
64
|
+
#
|
|
65
|
+
# - idref = Reference to property in {@link AppDefinition}
|
|
66
|
+
# - obj = Value or property binding to establish value of property
|
|
67
|
+
# - unit = Unit of value
|
|
68
|
+
# - isBinding = If true "obj" is a property reference, otherwise it's a value
|
|
69
|
+
#
|
|
70
|
+
def initialize(idref, obj = nil, unit = nil, isBinding = false)
|
|
71
|
+
@idref = idref
|
|
72
|
+
@unit = unit
|
|
73
|
+
if isBinding
|
|
74
|
+
@bindingRef = obj
|
|
75
|
+
else
|
|
76
|
+
@value = obj
|
|
77
|
+
end
|
|
78
|
+
@isBound = isBinding
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
#
|
|
82
|
+
# Return the definition of this Property as an XML element
|
|
83
|
+
#
|
|
84
|
+
# [Return] a XML element describing this Property
|
|
85
|
+
#
|
|
86
|
+
def to_xml
|
|
87
|
+
a = REXML::Element.new("property")
|
|
88
|
+
a.add_attribute("name", idref)
|
|
89
|
+
if isBound
|
|
90
|
+
a.add_element("binding", {"idref" => bindingRef})
|
|
91
|
+
elsif value != nil
|
|
92
|
+
v = a.add_element("value")
|
|
93
|
+
v.text = value
|
|
94
|
+
if (unit != nil)
|
|
95
|
+
v.add_attribute("unit", unit)
|
|
96
|
+
end
|
|
97
|
+
else
|
|
98
|
+
Log.warn("NOT IMPLEMENTED: check for default value in app definition")
|
|
99
|
+
end
|
|
100
|
+
return a
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
#
|
|
106
|
+
# This module defines the methods used to create new Properties when defining Prototypes/Applications in Experiments
|
|
107
|
+
#
|
|
108
|
+
module CreatePropertiesModule
|
|
109
|
+
|
|
110
|
+
#
|
|
111
|
+
# Set a property of the application to a specific value
|
|
112
|
+
#
|
|
113
|
+
# - propName = Name of the application property
|
|
114
|
+
# - value = Value of property
|
|
115
|
+
# - unit = optional, unit for this Property
|
|
116
|
+
#
|
|
117
|
+
def setProperty(propName, value, unit = nil)
|
|
118
|
+
prop = OmfEc::Property.new(propName, value, unit)
|
|
119
|
+
@properties += [prop]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
#
|
|
123
|
+
# Bind the value of a property to another property in the context
|
|
124
|
+
#
|
|
125
|
+
# - propName = name of application property
|
|
126
|
+
# - propRef = Property to bind to (default = 'propName')
|
|
127
|
+
#
|
|
128
|
+
def bindProperty(propName, propRef = propName)
|
|
129
|
+
prop = OmfEc::Property.new(propName, propRef, nil, true)
|
|
130
|
+
@properties += [prop]
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
#
|
|
134
|
+
# Add a list of properties described in a hash table
|
|
135
|
+
# where key is the property name and the value its value.
|
|
136
|
+
# If value starts with "$", value is interpreted as
|
|
137
|
+
# the name of another property to bind to.
|
|
138
|
+
#
|
|
139
|
+
# - properties = a Hash describing a set of properties
|
|
140
|
+
#
|
|
141
|
+
def addProperties(properties)
|
|
142
|
+
if properties != nil
|
|
143
|
+
if properties.kind_of?(Hash)
|
|
144
|
+
properties.each {|k, v|
|
|
145
|
+
if v.kind_of?(Symbol)
|
|
146
|
+
v = v.to_s
|
|
147
|
+
end
|
|
148
|
+
if v.kind_of?(String) && v[0] == ?$
|
|
149
|
+
# is binding
|
|
150
|
+
bindProperty(k, v[1..-1])
|
|
151
|
+
else
|
|
152
|
+
setProperty(k, v)
|
|
153
|
+
end
|
|
154
|
+
}
|
|
155
|
+
elsif properties.kind_of? Array
|
|
156
|
+
properties.each {|p|
|
|
157
|
+
if ! p.kind_of? OmfEc::Property
|
|
158
|
+
raise "Propertie array needs to contain Property, but is '" \
|
|
159
|
+
+ p.class.to_s + "'."
|
|
160
|
+
end
|
|
161
|
+
@properties += [p]
|
|
162
|
+
}
|
|
163
|
+
else
|
|
164
|
+
raise "Properties declarations needs to be a Hash or Array, but is '" \
|
|
165
|
+
+ properties.class.to_s + "'."
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
end
|
|
172
|
+
end
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Copyright (c) 2006-2009 National ICT Australia (NICTA), Australia
|
|
2
|
+
# This software may be used and distributed solely under the terms of the MIT license (License).
|
|
3
|
+
# You should find a copy of the License in LICENSE.TXT or at http://opensource.org/licenses/MIT.
|
|
4
|
+
# By downloading or using this software you accept the terms and the liability disclaimer in the License.
|
|
5
|
+
#
|
|
6
|
+
# Copyright (c) 2004-2009 WINLAB, Rutgers University, USA
|
|
7
|
+
|
|
8
|
+
require "omf_ec/parameter"
|
|
9
|
+
|
|
10
|
+
module OmfEc
|
|
11
|
+
# This class describes a prototype which can be used to access applications within an Experiment.
|
|
12
|
+
class Prototype
|
|
13
|
+
|
|
14
|
+
@@prototypes = Hash.new
|
|
15
|
+
@@bindStruct = Struct.new(:name)
|
|
16
|
+
|
|
17
|
+
# Return a known Prototype instance.
|
|
18
|
+
#
|
|
19
|
+
# [Return] the uri 'URI' identifying the Prototype
|
|
20
|
+
#
|
|
21
|
+
def self.[](uri)
|
|
22
|
+
proto = @@prototypes[uri]
|
|
23
|
+
if proto == nil
|
|
24
|
+
debug "Loading prototype '#{uri}'"
|
|
25
|
+
str, type = OConfig.load(uri, true)
|
|
26
|
+
#MObject.debug('Prototype: ', 'str: "', str, '".')
|
|
27
|
+
if type == "text/xml"
|
|
28
|
+
# proto = Prototype.from_xml(str.to_xml???)
|
|
29
|
+
elsif type == "text/ruby"
|
|
30
|
+
# 'str' has already been evaluated
|
|
31
|
+
proto = @@prototypes[uri]
|
|
32
|
+
end
|
|
33
|
+
if proto == nil
|
|
34
|
+
raise "Unknown prototype '#{uri}'."
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
proto
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Create a new Prototype instance.
|
|
42
|
+
#
|
|
43
|
+
# - uri = an URI identifying the new Prototype
|
|
44
|
+
# - name = an optional name for this Prototype (default = 'uri')
|
|
45
|
+
#
|
|
46
|
+
def self.create(uri, name = uri)
|
|
47
|
+
return Prototype.new(uri, name)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Reset all class state. Specifically forget all prototype declarations.
|
|
51
|
+
# This is primarily used by the test suite.
|
|
52
|
+
#
|
|
53
|
+
def self.reset()
|
|
54
|
+
@@prototypes = Hash.new
|
|
55
|
+
@@bindStruct = Struct.new(:name)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Global reference
|
|
59
|
+
attr_writer :uri
|
|
60
|
+
|
|
61
|
+
# Name of prototype
|
|
62
|
+
attr_writer :name
|
|
63
|
+
|
|
64
|
+
# Version of prototype
|
|
65
|
+
attr_reader :version
|
|
66
|
+
|
|
67
|
+
# Description of the prototype
|
|
68
|
+
attr_writer :description
|
|
69
|
+
|
|
70
|
+
# Parameters of the prototype
|
|
71
|
+
attr_reader :parameters
|
|
72
|
+
|
|
73
|
+
# Applications used on the prototype
|
|
74
|
+
attr_reader :applications
|
|
75
|
+
|
|
76
|
+
# Create a new Prototype instance.
|
|
77
|
+
#
|
|
78
|
+
# - uri = an URI identifying the new Prototype
|
|
79
|
+
# - name = an optional name for this Prototype (default = 'uri')
|
|
80
|
+
#
|
|
81
|
+
def initialize(uri, name = uri)
|
|
82
|
+
if @@prototypes.has_key? uri
|
|
83
|
+
raise StandardError, "Prototype with name '#{uri}' already exists."
|
|
84
|
+
end
|
|
85
|
+
@@prototypes[uri] = self
|
|
86
|
+
|
|
87
|
+
@uri = uri
|
|
88
|
+
@name = name
|
|
89
|
+
@properties = Hashie::Mash.new
|
|
90
|
+
@incPrototypes = Hash.new
|
|
91
|
+
@applications = Array.new
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Instantiate this prototype for a particular node set.
|
|
95
|
+
#
|
|
96
|
+
# - group = Group to configure according to this prototype
|
|
97
|
+
# - bindings = a Hash with the bindings for local parameters
|
|
98
|
+
#
|
|
99
|
+
def instantiate(group, bindings)
|
|
100
|
+
bindings = Hashie::Mash.new(bindings)
|
|
101
|
+
# check if bindings contain unknown properties
|
|
102
|
+
if (diff = bindings.keys - @properties.keys) != []
|
|
103
|
+
raise "Unknown parameters '#{diff.join(', ')}'" \
|
|
104
|
+
+ " not in '#{@properties.keys.join(', ')}'."
|
|
105
|
+
end
|
|
106
|
+
# merge bindings with properties declaration
|
|
107
|
+
context = Hash.new
|
|
108
|
+
@properties.each do |name, param|
|
|
109
|
+
#puts "A>> #{name}"
|
|
110
|
+
value = getBoundValue(name, bindings)
|
|
111
|
+
if value != nil
|
|
112
|
+
context[name] = getBoundValue(name, bindings)
|
|
113
|
+
else
|
|
114
|
+
warn "No specific or default value found for Property '#{name}'. Prototype '#{@name}' will not use it!"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
@incPrototypes.each do |name, params|
|
|
119
|
+
proto = Prototype[name]
|
|
120
|
+
p = params.clone
|
|
121
|
+
p.each do |key, val|
|
|
122
|
+
if val.kind_of?(@@bindStruct)
|
|
123
|
+
#puts "B>> #{val.name}:#{key}"
|
|
124
|
+
value = getBoundValue(name, bindings)
|
|
125
|
+
if value != nil
|
|
126
|
+
p[key] = val = value
|
|
127
|
+
else
|
|
128
|
+
warn "No specific or default value found for Property '#{name}'. Prototype '#{@name}' will not use it!"
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
#debug "recursive bindings: #{key}=>#{val}"
|
|
132
|
+
end
|
|
133
|
+
proto.instantiate(group, p)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
@applications.each do |app|
|
|
137
|
+
name, location, block = *app
|
|
138
|
+
|
|
139
|
+
if block
|
|
140
|
+
block_with_binding_props = proc do |app_ctx|
|
|
141
|
+
block.call(app_ctx)
|
|
142
|
+
app_ctx.proto_props.each do |p_name, p_ref|
|
|
143
|
+
app_ctx.setProperty(p_name, context[p_ref]) if context[p_ref]
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
if block_with_binding_props
|
|
149
|
+
group.addApplication(name, location, &block_with_binding_props)
|
|
150
|
+
else
|
|
151
|
+
group.addApplication(name, location)
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Return the value of a given property 'name' within the
|
|
157
|
+
# context of 'bindings'.
|
|
158
|
+
#
|
|
159
|
+
# - name = name of the property to get the value from
|
|
160
|
+
# - bindings = context for this property
|
|
161
|
+
#
|
|
162
|
+
# [Return] The value of the property
|
|
163
|
+
#
|
|
164
|
+
def getBoundValue(name, bindings)
|
|
165
|
+
if (bindings.has_key? name)
|
|
166
|
+
return bindings[name]
|
|
167
|
+
else
|
|
168
|
+
# use default
|
|
169
|
+
if (@properties[name] == nil)
|
|
170
|
+
raise "Unknown property #{name}"
|
|
171
|
+
end
|
|
172
|
+
return @properties[name].defaultValue
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
private :getBoundValue
|
|
176
|
+
|
|
177
|
+
# Define a property for this prototype
|
|
178
|
+
#
|
|
179
|
+
# - id = ID of parameter, also used as name
|
|
180
|
+
# - description = Description of parameter's purpose
|
|
181
|
+
# - default = Default value if not set, makes parameter optional
|
|
182
|
+
#
|
|
183
|
+
def defProperty(id, description, default = nil)
|
|
184
|
+
if @properties[id] != nil
|
|
185
|
+
raise "Property '" + id + "' already defined."
|
|
186
|
+
end
|
|
187
|
+
param = OmfEc::Parameter.new(id, id, description, default)
|
|
188
|
+
@properties[id] = param
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Returns an object which maintains the connection to a
|
|
192
|
+
# a local property of this Prototype.
|
|
193
|
+
#
|
|
194
|
+
# - name = name of the local property
|
|
195
|
+
#
|
|
196
|
+
# [Return] a structure with connection info to the local property
|
|
197
|
+
#
|
|
198
|
+
def bindProperty(name)
|
|
199
|
+
@@bindStruct.new(name)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Set the version number for this Prototype
|
|
203
|
+
#
|
|
204
|
+
# - major = major version number
|
|
205
|
+
# - minor = minor version number
|
|
206
|
+
# - revision = revision version number
|
|
207
|
+
#
|
|
208
|
+
def setVersion(major = 0, minor = 0, revision = 0)
|
|
209
|
+
#TODO Needs new implementation
|
|
210
|
+
#@currentVersion = MutableVersion.new(major, minor, revision)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Add a nested Prototype which should be instantiated when
|
|
214
|
+
# this Prototype is instantiated.
|
|
215
|
+
#
|
|
216
|
+
# - name = Name used for reference
|
|
217
|
+
# - param = Hash of parameter bindings
|
|
218
|
+
#
|
|
219
|
+
def addPrototype(name, param)
|
|
220
|
+
if @incPrototypes.has_key? name
|
|
221
|
+
raise "Prototype already has a prototype '" + name + "'."
|
|
222
|
+
end
|
|
223
|
+
@incPrototypes[name] = param
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# Add an Application which should be installed on this prototype.
|
|
227
|
+
#
|
|
228
|
+
def addApplication(name, location = nil, &block)
|
|
229
|
+
@applications << [name, location, block]
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
data/lib/omf_ec/runner.rb
CHANGED
|
@@ -36,8 +36,8 @@ module OmfEc
|
|
|
36
36
|
rolling_file: {
|
|
37
37
|
level: :debug,
|
|
38
38
|
log_dir: '/var/tmp',
|
|
39
|
-
size: 1024*
|
|
40
|
-
keep:
|
|
39
|
+
size: 1024*10, # max 510k of each log file
|
|
40
|
+
keep: 1, # keep 1 log in total
|
|
41
41
|
date_pattern: '%F %T %z',
|
|
42
42
|
pattern: '[%d] %-5l %c: %m\n'
|
|
43
43
|
}
|
|
@@ -165,7 +165,7 @@ module OmfEc
|
|
|
165
165
|
if @config_opts[:oml_uri]
|
|
166
166
|
# Only change default if they are not set in config file
|
|
167
167
|
@config_opts[:logging][:appenders][:oml4r] ||= {
|
|
168
|
-
level: :
|
|
168
|
+
level: :debug, # Log everything to OML
|
|
169
169
|
appName: 'omf_ec',
|
|
170
170
|
domain: OmfEc.experiment.id,
|
|
171
171
|
collect: @config_opts[:oml_uri]
|
data/lib/omf_ec.rb
CHANGED
metadata
CHANGED
|
@@ -1,126 +1,111 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: omf_ec
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 6.1.4
|
|
5
|
-
prerelease: 6
|
|
4
|
+
version: 6.1.4
|
|
6
5
|
platform: ruby
|
|
7
6
|
authors:
|
|
8
7
|
- NICTA
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date: 2014-
|
|
11
|
+
date: 2014-08-19 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: minitest
|
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
|
17
|
-
none: false
|
|
18
16
|
requirements:
|
|
19
|
-
- -
|
|
17
|
+
- - '>='
|
|
20
18
|
- !ruby/object:Gem::Version
|
|
21
19
|
version: '0'
|
|
22
20
|
type: :development
|
|
23
21
|
prerelease: false
|
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
-
none: false
|
|
26
23
|
requirements:
|
|
27
|
-
- -
|
|
24
|
+
- - '>='
|
|
28
25
|
- !ruby/object:Gem::Version
|
|
29
26
|
version: '0'
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
|
31
28
|
name: simplecov
|
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
|
33
|
-
none: false
|
|
34
30
|
requirements:
|
|
35
|
-
- -
|
|
31
|
+
- - '>='
|
|
36
32
|
- !ruby/object:Gem::Version
|
|
37
33
|
version: '0'
|
|
38
34
|
type: :development
|
|
39
35
|
prerelease: false
|
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
41
|
-
none: false
|
|
42
37
|
requirements:
|
|
43
|
-
- -
|
|
38
|
+
- - '>='
|
|
44
39
|
- !ruby/object:Gem::Version
|
|
45
40
|
version: '0'
|
|
46
41
|
- !ruby/object:Gem::Dependency
|
|
47
42
|
name: pry
|
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
|
49
|
-
none: false
|
|
50
44
|
requirements:
|
|
51
|
-
- -
|
|
45
|
+
- - '>='
|
|
52
46
|
- !ruby/object:Gem::Version
|
|
53
47
|
version: '0'
|
|
54
48
|
type: :development
|
|
55
49
|
prerelease: false
|
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
57
|
-
none: false
|
|
58
51
|
requirements:
|
|
59
|
-
- -
|
|
52
|
+
- - '>='
|
|
60
53
|
- !ruby/object:Gem::Version
|
|
61
54
|
version: '0'
|
|
62
55
|
- !ruby/object:Gem::Dependency
|
|
63
56
|
name: mocha
|
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
|
65
|
-
none: false
|
|
66
58
|
requirements:
|
|
67
|
-
- -
|
|
59
|
+
- - '>='
|
|
68
60
|
- !ruby/object:Gem::Version
|
|
69
61
|
version: '0'
|
|
70
62
|
type: :development
|
|
71
63
|
prerelease: false
|
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
73
|
-
none: false
|
|
74
65
|
requirements:
|
|
75
|
-
- -
|
|
66
|
+
- - '>='
|
|
76
67
|
- !ruby/object:Gem::Version
|
|
77
68
|
version: '0'
|
|
78
69
|
- !ruby/object:Gem::Dependency
|
|
79
70
|
name: evented-spec
|
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
|
81
|
-
none: false
|
|
82
72
|
requirements:
|
|
83
|
-
- -
|
|
73
|
+
- - '>='
|
|
84
74
|
- !ruby/object:Gem::Version
|
|
85
75
|
version: '0'
|
|
86
76
|
type: :development
|
|
87
77
|
prerelease: false
|
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
89
|
-
none: false
|
|
90
79
|
requirements:
|
|
91
|
-
- -
|
|
80
|
+
- - '>='
|
|
92
81
|
- !ruby/object:Gem::Version
|
|
93
82
|
version: '0'
|
|
94
83
|
- !ruby/object:Gem::Dependency
|
|
95
84
|
name: omf_common
|
|
96
85
|
requirement: !ruby/object:Gem::Requirement
|
|
97
|
-
none: false
|
|
98
86
|
requirements:
|
|
99
87
|
- - '='
|
|
100
88
|
- !ruby/object:Gem::Version
|
|
101
|
-
version: 6.1.4
|
|
89
|
+
version: 6.1.4
|
|
102
90
|
type: :runtime
|
|
103
91
|
prerelease: false
|
|
104
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
105
|
-
none: false
|
|
106
93
|
requirements:
|
|
107
94
|
- - '='
|
|
108
95
|
- !ruby/object:Gem::Version
|
|
109
|
-
version: 6.1.4
|
|
96
|
+
version: 6.1.4
|
|
110
97
|
- !ruby/object:Gem::Dependency
|
|
111
98
|
name: sequel
|
|
112
99
|
requirement: !ruby/object:Gem::Requirement
|
|
113
|
-
none: false
|
|
114
100
|
requirements:
|
|
115
|
-
- -
|
|
101
|
+
- - '>='
|
|
116
102
|
- !ruby/object:Gem::Version
|
|
117
103
|
version: '0'
|
|
118
104
|
type: :runtime
|
|
119
105
|
prerelease: false
|
|
120
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
-
none: false
|
|
122
107
|
requirements:
|
|
123
|
-
- -
|
|
108
|
+
- - '>='
|
|
124
109
|
- !ruby/object:Gem::Version
|
|
125
110
|
version: '0'
|
|
126
111
|
description: Experiment controller of OMF, a generic framework for controlling and
|
|
@@ -168,6 +153,9 @@ files:
|
|
|
168
153
|
- lib/omf_ec/graph.rb
|
|
169
154
|
- lib/omf_ec/graph/graph_description.rb
|
|
170
155
|
- lib/omf_ec/group.rb
|
|
156
|
+
- lib/omf_ec/parameter.rb
|
|
157
|
+
- lib/omf_ec/property.rb
|
|
158
|
+
- lib/omf_ec/prototype.rb
|
|
171
159
|
- lib/omf_ec/runner.rb
|
|
172
160
|
- lib/omf_ec/version.rb
|
|
173
161
|
- omf_ec.gemspec
|
|
@@ -183,26 +171,34 @@ files:
|
|
|
183
171
|
homepage: http://omf.mytestbed.net
|
|
184
172
|
licenses:
|
|
185
173
|
- MIT
|
|
174
|
+
metadata: {}
|
|
186
175
|
post_install_message:
|
|
187
176
|
rdoc_options: []
|
|
188
177
|
require_paths:
|
|
189
178
|
- lib
|
|
190
179
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
191
|
-
none: false
|
|
192
180
|
requirements:
|
|
193
|
-
- -
|
|
181
|
+
- - '>='
|
|
194
182
|
- !ruby/object:Gem::Version
|
|
195
183
|
version: 1.9.3
|
|
196
184
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
|
-
none: false
|
|
198
185
|
requirements:
|
|
199
|
-
- -
|
|
186
|
+
- - '>='
|
|
200
187
|
- !ruby/object:Gem::Version
|
|
201
|
-
version:
|
|
188
|
+
version: '0'
|
|
202
189
|
requirements: []
|
|
203
190
|
rubyforge_project: omf_ec
|
|
204
|
-
rubygems_version:
|
|
191
|
+
rubygems_version: 2.0.14
|
|
205
192
|
signing_key:
|
|
206
|
-
specification_version:
|
|
193
|
+
specification_version: 4
|
|
207
194
|
summary: OMF experiment controller
|
|
208
|
-
test_files:
|
|
195
|
+
test_files:
|
|
196
|
+
- test/oedls/empty.oedl
|
|
197
|
+
- test/omf_ec/app_context_spec.rb
|
|
198
|
+
- test/omf_ec/context_spec.rb
|
|
199
|
+
- test/omf_ec/dsl_spec.rb
|
|
200
|
+
- test/omf_ec/experiment_property_spec.rb
|
|
201
|
+
- test/omf_ec/experiment_spec.rb
|
|
202
|
+
- test/omf_ec/group_spec.rb
|
|
203
|
+
- test/omf_ec/runner_spec.rb
|
|
204
|
+
- test/test_helper.rb
|