Class: Laborantin::Scenario
- Inherits:
-
Object
- Object
- Laborantin::Scenario
- Extended by:
- Metaprog::Describable, Metaprog::Hookable, Metaprog::MultiName
- Includes:
- Metaprog::Configurable, Metaprog::Datable, Metaprog::Dependencies, Metaprog::Exports, Metaprog::Selector
- Defined in:
- lib/laborantin/core/scenario.rb
Overview
A Scenario represents a measurement done in a given environment. Some of its parameters will change, and we are interested in varying these parameters and then study their impact.
An user will usually creates a Scenario subklass which represents such a measurement. For that he must defines a run method that will yield consecutive lines added to the raw result file. Then this file can be processed to give intermediary or final results.
Like the Environment, all the subklasses will be stored in a @@all class variable for convenience purpose.
Constant Summary collapse
- @@all =
[]
Constants included from Metaprog::MultiName
Metaprog::MultiName::AVAILABLE_NAMES
Class Attribute Summary collapse
-
.parameters ⇒ Object
The set of parameters that will vary for this Scenario.
-
.products ⇒ Object
Some special products that are done after an analysis on a measurement scenario.
Instance Attribute Summary collapse
-
#environment ⇒ Object
The environment in which we run this scenario.
-
#params ⇒ Object
A hash of parameters for this run.
-
#rundir ⇒ Object
An attribute that holds the directory where the config and the results are stored.
Attributes included from Metaprog::Describable
Attributes included from Metaprog::Hookable
Attributes included from Metaprog::MultiName
Attributes included from Metaprog::Selector
Attributes included from Metaprog::Configurable
Attributes included from Metaprog::Datable
Class Method Summary collapse
-
.all ⇒ Object
Returns all the known subklasses of Scenario.
-
.inherited(klass) ⇒ Object
Prepares attributes’ default values whenever a subclass is created.
- .new_loading_from_dir(env, path) ⇒ Object
-
.parameter(name, &blk) ⇒ Object
Defines a new ParameterRange instance for this Scenario.
-
.produces(*args) ⇒ Object
Defines the products names.
-
.scan_env(env) ⇒ Object
Scans the env’s envdir (should be an Environment) for scenarii results.
-
.scenardir(env = nil) ⇒ Object
Returns the path where the results of the instances of this Scenario will be stored given that we are in the env Environment.
Instance Method Summary collapse
-
#analyze! ⇒ Object
For each product define with Scenario.produces, and in its order, create a file with a canonic name in the scenario rundir.
- #command ⇒ Object
-
#config_path ⇒ Object
The path to the config.yaml file that holds the scenario parameters.
- #export_file(mode = 'r', &blk) ⇒ Object
- #export_path ⇒ Object
-
#initialize(env, params = {}) ⇒ Scenario
constructor
Initializes a new instance contains in the env Environment, and for the parameter set params.
- #log(*args) ⇒ Object
-
#perform! ⇒ Object
In the following order: * Calls the setup hooks * Logs some info * Creates the raw result file * Calls the run method (user defined) * …
-
#prepare! ⇒ Object
In the following order: * Log some info in the environment * Creates the rundir to store the result and the config * Stores the configuration as well as the run date BEWARE : currently does not ensure unicity of rundir, so wait one sec between several runs of same Scenario.
-
#product_file(resultname, mode = 'r', brutname = false) ⇒ Object
Yields an open file for a given product, will make sure it is closed.
-
#product_path(resultname, brutname = false) ⇒ Object
Returns the absolute path to a product file (see File.join) If brutname is true, then resultname is appended to the rundir of the scenario.
-
#raw_result_file(mode = 'r') ⇒ Object
Yield the opened raw result file, will close it afterwards.
-
#raw_result_path ⇒ Object
The path to the “raw result”, i.e.
- #runner ⇒ Object
- #table(name, struct) ⇒ Object
Methods included from Metaprog::Hookable
Methods included from Metaprog::MultiName
Methods included from Metaprog::Exports
#export, #exports, #load_exports, #plots, #save_exports
Methods included from Metaprog::Dependencies
Methods included from Metaprog::Selector
included, #load_environments, #load_prior_results, #load_scenarii, #select_instance?
Methods included from Metaprog::Configurable
Methods included from Metaprog::Datable
Constructor Details
#initialize(env, params = {}) ⇒ Scenario
Initializes a new instance contains in the env Environment, and for the parameter set params. Sets the date to Time.now for unicity (with 1sec granularity) Sets the rundir accessor in the directory. Does NOT create any directory, so the accessors can be overwritten if needed.
167 168 169 170 171 172 173 |
# File 'lib/laborantin/core/scenario.rb', line 167 def initialize(env, params={}) @environment = env @params = params @date = Time.now @config = {} @rundir = File.join(self.class.scenardir(environment), date_str) end |
Class Attribute Details
.parameters ⇒ Object
The set of parameters that will vary for this Scenario.
97 98 99 |
# File 'lib/laborantin/core/scenario.rb', line 97 def parameters @parameters end |
.products ⇒ Object
Some special products that are done after an analysis on a measurement scenario. The intended way is to store raw results (e.g. a command output) in a file and then parse them and store the parsed result in another file etc. TODO : products that compares scenarii
103 104 105 |
# File 'lib/laborantin/core/scenario.rb', line 103 def products @products end |
Instance Attribute Details
#environment ⇒ Object
The environment in which we run this scenario.
156 157 158 |
# File 'lib/laborantin/core/scenario.rb', line 156 def environment @environment end |
#params ⇒ Object
A hash of parameters for this run.
153 154 155 |
# File 'lib/laborantin/core/scenario.rb', line 153 def params @params end |
#rundir ⇒ Object
An attribute that holds the directory where the config and the results are stored. Can be overridden (e.g. Scenario.scan_env does that).
160 161 162 |
# File 'lib/laborantin/core/scenario.rb', line 160 def rundir @rundir end |
Class Method Details
.all ⇒ Object
Returns all the known subklasses of Scenario.
139 140 141 |
# File 'lib/laborantin/core/scenario.rb', line 139 def all @@all end |
.inherited(klass) ⇒ Object
Prepares attributes’ default values whenever a subclass is created.
106 107 108 109 110 111 112 113 |
# File 'lib/laborantin/core/scenario.rb', line 106 def inherited(klass) klass.parameters = ParameterHash.new.replace(self.parameters || {}) klass.description = "#{self.description} (child of #{self})" klass.products = self.products ? self.products.dup : [] klass.hooks = Hash.new.replace(self.hooks || {:setup => [], :teardown => []}) klass.selectors = Hash.new.replace(self.selectors || {}) @@all << klass end |
.new_loading_from_dir(env, path) ⇒ Object
85 86 87 88 89 90 91 92 93 |
# File 'lib/laborantin/core/scenario.rb', line 85 def self.new_loading_from_dir(env, path) obj = self.new(env) yml_path = File.join(path, 'config.yaml') tst, params = obj.load_config!(yml_path) obj.params = params obj.date = tst obj.rundir = path obj end |
.parameter(name, &blk) ⇒ Object
Defines a new ParameterRange instance for this Scenario. A block should be passed that will be evaluated in this ParameterRange instance’s context.
parameter(:size) do
values 10, 20, 30
describe "We expect a linear RTT increase with the size"
end
124 125 126 127 128 129 |
# File 'lib/laborantin/core/scenario.rb', line 124 def parameter(name, &blk) raise ArgumentError.new("Parameter #{name} already exists") if self.parameters[name] param = ParameterRange.new(name) param.instance_eval &blk self.parameters[name] = param end |
.produces(*args) ⇒ Object
Defines the products names. IMPORTANT: products are built in the provided order, and they must be valid instance methods name for a Scenario object (hence user defined).
134 135 136 |
# File 'lib/laborantin/core/scenario.rb', line 134 def produces(*args) self.products = [*args].flatten end |
.scan_env(env) ⇒ Object
Scans the env’s envdir (should be an Environment) for scenarii results. It will set their configuration (i.e. run date and parameters hash) according to the stored config.yaml in YAML format. Returns an array of such built scenarii.
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/laborantin/core/scenario.rb', line 69 def self.scan_env(env) list = [] Dir.entries(env.rundir).each do |s| scklass = Laborantin::Scenario.all.find{|t| t.fs_name == s} if scklass Dir.entries(scklass.scenardir(env)).each do |r| if r =~ /\d+-\w+-\d+_\d+-\d+-\d+/ scenar = scklass.new_loading_from_dir(env, File.join(scklass.scenardir(env), r)) list << scenar end end end end list end |
.scenardir(env = nil) ⇒ Object
Returns the path where the results of the instances of this Scenario will be stored given that we are in the env Environment. If env is nil, will use ‘.’ as rootdir for the Scenario results.
146 147 148 149 |
# File 'lib/laborantin/core/scenario.rb', line 146 def scenardir(env=nil) envdir = env.rundir || '.' File.join(envdir, self.fs_name) end |
Instance Method Details
#analyze! ⇒ Object
For each product define with Scenario.produces, and in its order, create a file with a canonic name in the scenario rundir. Call the instance method which has the product name. Appends each yielded line from this method.
224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/laborantin/core/scenario.rb', line 224 def analyze! self.class.products.each do |name| log "(#{name})" product_file(name.to_s, 'w') do |f| send(name) do |l| f.puts l end end end save_exports end |
#command ⇒ Object
295 296 297 |
# File 'lib/laborantin/core/scenario.rb', line 295 def command environment.command end |
#config_path ⇒ Object
The path to the config.yaml file that holds the scenario parameters.
258 259 260 |
# File 'lib/laborantin/core/scenario.rb', line 258 def config_path product_path('config.yaml', true) end |
#export_file(mode = 'r', &blk) ⇒ Object
283 284 285 |
# File 'lib/laborantin/core/scenario.rb', line 283 def export_file(mode='r', &blk) product_file('exports.yaml', mode, true, &blk) end |
#export_path ⇒ Object
287 288 289 |
# File 'lib/laborantin/core/scenario.rb', line 287 def export_path product_path('exports.yaml', true) end |
#log(*args) ⇒ Object
291 292 293 |
# File 'lib/laborantin/core/scenario.rb', line 291 def log(*args) environment.log *args end |
#perform! ⇒ Object
In the following order:
-
Calls the setup hooks
-
Logs some info
-
Creates the raw result file
-
Calls the run method (user defined)
-
… for each yielded line, store it into the raw result file
-
once completed (or on error) closes the raw result file
-
Logs some info
-
Calls the teardown hooks
207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/laborantin/core/scenario.rb', line 207 def perform! call_hooks :setup log "Starting measurement" raw_result_file('w') do |f| run do |l| f.puts l end end log "Measurement finished" call_hooks :teardown save_exports end |
#prepare! ⇒ Object
In the following order:
-
Log some info in the environment
-
Creates the rundir to store the result and the config
-
Stores the configuration as well as the run date
BEWARE : currently does not ensure unicity of rundir, so wait one sec between several runs of same Scenario
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/laborantin/core/scenario.rb', line 182 def prepare! log "Loading prior results:" load_prior_results log "Got #{scenarii.size} scenarios in #{environments.size} environments" log "Description:" log(self.class.description || 'no description', :info) log "Parameters:" log self.params.inspect, :info log "Preparing directory #{rundir}" FileUtils.mkdir_p(rundir) #TODO: ensure unicity environment.record_scenario_dir(rundir, true) log "Storing configuration in YAML format" @config = [date, params] save_config end |
#product_file(resultname, mode = 'r', brutname = false) ⇒ Object
Yields an open file for a given product, will make sure it is closed. mode is the mode in which the file is opened (you should leave it to ‘r’) see the doc for product_path to understand the role of brutname
251 252 253 254 255 |
# File 'lib/laborantin/core/scenario.rb', line 251 def product_file(resultname, mode='r', brutname=false) File.open(product_path(resultname, brutname), mode) do |f| yield f end end |
#product_path(resultname, brutname = false) ⇒ Object
Returns the absolute path to a product file (see File.join) If brutname is true, then resultname is appended to the rundir of the scenario. If brutname is false, then before being appended to the rundir of the scenario, the name is surronded by result.<resultname>.txt
The idea behind this is to avoid name collisions between simple users of Laborantin, and people developping extensions or modules.
243 244 245 246 |
# File 'lib/laborantin/core/scenario.rb', line 243 def product_path(resultname, brutname=false) resultname = "result.#{resultname}.txt" unless brutname File.join(rundir, resultname) end |
#raw_result_file(mode = 'r') ⇒ Object
Yield the opened raw result file, will close it afterwards. mode is the mode in which the file is opened (default to ‘r’) never open the file in another mode, unless you know what you’re doing, because this file most likely contains the value of your work, i.e., your data.
273 274 275 276 277 |
# File 'lib/laborantin/core/scenario.rb', line 273 def raw_result_file(mode='r') product_file('result.raw', mode, true) do |f| yield f end end |
#raw_result_path ⇒ Object
The path to the “raw result”, i.e. the one built when you yield in the run method.
264 265 266 |
# File 'lib/laborantin/core/scenario.rb', line 264 def raw_result_path product_path('result.raw', true) end |
#runner ⇒ Object
299 300 301 |
# File 'lib/laborantin/core/scenario.rb', line 299 def runner environment.runner end |