Class: Laborantin::Scenario
- Inherits:
-
Object
- Object
- Laborantin::Scenario
- Extended by:
- Metaprog::Describable, Metaprog::Hookable, Metaprog::MultiName
- Includes:
- Metaprog::Configurable, Metaprog::Datable
- 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::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.
-
#config_path ⇒ Object
The path to the config.yaml file that holds the scenario parameters.
-
#initialize(env, params = {}) ⇒ Scenario
constructor
Initializes a new instance contains in the env Environment, and for the parameter set params.
-
#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.
- #table(name, struct) ⇒ Object
Methods included from Metaprog::Hookable
Methods included from Metaprog::MultiName
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.
160 161 162 163 164 165 166 |
# File 'lib/laborantin/core/scenario.rb', line 160 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.
91 92 93 |
# File 'lib/laborantin/core/scenario.rb', line 91 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
97 98 99 |
# File 'lib/laborantin/core/scenario.rb', line 97 def products @products end |
Instance Attribute Details
#environment ⇒ Object
The environment in which we run this scenario.
149 150 151 |
# File 'lib/laborantin/core/scenario.rb', line 149 def environment @environment end |
#params ⇒ Object
A hash of parameters for this run.
146 147 148 |
# File 'lib/laborantin/core/scenario.rb', line 146 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).
153 154 155 |
# File 'lib/laborantin/core/scenario.rb', line 153 def rundir @rundir end |
Class Method Details
.all ⇒ Object
Returns all the known subklasses of Scenario.
132 133 134 |
# File 'lib/laborantin/core/scenario.rb', line 132 def all @@all end |
.inherited(klass) ⇒ Object
Prepares attributes’ default values whenever a subclass is created.
100 101 102 103 104 105 106 |
# File 'lib/laborantin/core/scenario.rb', line 100 def inherited(klass) klass.parameters = ParameterHash.new klass.description = '' klass.products = [] klass.hooks = {:setup => [], :teardown => []} @@all << klass end |
.new_loading_from_dir(env, path) ⇒ Object
79 80 81 82 83 84 85 86 87 |
# File 'lib/laborantin/core/scenario.rb', line 79 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
117 118 119 120 121 122 |
# File 'lib/laborantin/core/scenario.rb', line 117 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).
127 128 129 |
# File 'lib/laborantin/core/scenario.rb', line 127 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.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
# File 'lib/laborantin/core/scenario.rb', line 63 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.
139 140 141 142 |
# File 'lib/laborantin/core/scenario.rb', line 139 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.
211 212 213 214 215 216 217 218 219 220 |
# File 'lib/laborantin/core/scenario.rb', line 211 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 end |
#config_path ⇒ Object
The path to the config.yaml file that holds the scenario parameters.
244 245 246 |
# File 'lib/laborantin/core/scenario.rb', line 244 def config_path product_path('config.yaml', true) 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
195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/laborantin/core/scenario.rb', line 195 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 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
175 176 177 178 179 180 181 182 183 184 |
# File 'lib/laborantin/core/scenario.rb', line 175 def prepare! log(self.class.description, :info) unless self.class.description.empty? 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
237 238 239 240 241 |
# File 'lib/laborantin/core/scenario.rb', line 237 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.
229 230 231 232 |
# File 'lib/laborantin/core/scenario.rb', line 229 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.
259 260 261 262 263 |
# File 'lib/laborantin/core/scenario.rb', line 259 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.
250 251 252 |
# File 'lib/laborantin/core/scenario.rb', line 250 def raw_result_path product_path('result.raw', true) end |