omf_ec 6.1.4.pre.2 → 6.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|