laborantin 0.0.2 → 0.0.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +12 -2
- data/bin/files/README.erb +29 -0
- data/bin/files/TODO.erb +2 -0
- data/bin/files/config/ftp.yaml.erb +6 -0
- data/bin/files/config/xmpp.yaml.erb +7 -0
- data/bin/files/environments/environment.rb.erb +13 -0
- data/bin/files/scenarii/scenario.rb.erb +5 -0
- data/bin/labor +226 -0
- data/lib/laborantin/core/environment.rb +56 -54
- data/lib/laborantin/{additions/xmpp_logger.rb → core/monkey_patches.rb} +8 -10
- data/lib/laborantin/core/parameter.rb +10 -1
- data/lib/laborantin/core/parameter_hash.rb +4 -0
- data/lib/laborantin/core/scenario.rb +100 -29
- data/lib/laborantin.rb +3 -96
- metadata +12 -5
data/Rakefile
CHANGED
@@ -3,7 +3,7 @@ require 'rake/gempackagetask'
|
|
3
3
|
|
4
4
|
spec = Gem::Specification.new do |s|
|
5
5
|
s.name = 'laborantin'
|
6
|
-
s.version = '0.0.
|
6
|
+
s.version = '0.0.6'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
8
|
s.summary = "A measurement batch facilitator"
|
9
9
|
|
@@ -14,14 +14,24 @@ spec = Gem::Specification.new do |s|
|
|
14
14
|
|
15
15
|
s.files = ['README', 'LICENSE', 'gpl-3.0.txt',
|
16
16
|
'Rakefile', 'TODO',
|
17
|
+
'bin/labor',
|
18
|
+
'bin/files/README.erb',
|
19
|
+
'bin/files/TODO.erb',
|
20
|
+
'bin/files/config/ftp.yaml.erb',
|
21
|
+
'bin/files/config/xmpp.yaml.erb',
|
22
|
+
'bin/files/environments/environment.rb.erb',
|
23
|
+
'bin/files/scenarii/scenario.rb.erb',
|
17
24
|
'lib/laborantin.rb',
|
18
25
|
'lib/laborantin/core/environment.rb',
|
19
26
|
'lib/laborantin/core/parameter.rb',
|
20
27
|
'lib/laborantin/core/parameter_hash.rb',
|
21
28
|
'lib/laborantin/core/scenario.rb',
|
22
|
-
'lib/laborantin/
|
29
|
+
'lib/laborantin/core/monkey_patches.rb',
|
30
|
+
]
|
23
31
|
|
24
32
|
s.require_path = 'lib'
|
33
|
+
s.bindir = 'bin'
|
34
|
+
s.executables = ['labor']
|
25
35
|
|
26
36
|
s.has_rdoc = false
|
27
37
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
The "<%= File.dirname __FILE__ %>" directory has been created by Laborantin <%= Laborantin::VERSION %>.
|
2
|
+
It is important to understand the hierarchy of Laborantin's directory
|
3
|
+
before moving any file.
|
4
|
+
|
5
|
+
Laborantin has created several files:
|
6
|
+
|
7
|
+
<%= File.dirname __FILE__ %>/
|
8
|
+
|-- README # This file.
|
9
|
+
|-- TODO # A file where you should track what is left.
|
10
|
+
|-- config # Configuration for Laborantin's command.
|
11
|
+
| |-- ftp.yaml # Account config for FTP exports.
|
12
|
+
| `-- xmpp.yaml # Account config for XMPP Logging.
|
13
|
+
|-- environments # Your measurement environments.
|
14
|
+
|-- results # The results of the various run.
|
15
|
+
|-- scenarii # Your scenarii.
|
16
|
+
`-- scripts # A dir to place your additional scripts.
|
17
|
+
|
18
|
+
In addition to this, it has created one environnment ruby file per
|
19
|
+
-e argument as well as one scenario ruby file per -s argument.
|
20
|
+
|
21
|
+
When executing a laborantin run command, Laborantin will scan the current
|
22
|
+
directory for environments and scenarii.
|
23
|
+
|
24
|
+
See <%= Laborantin::WEBSITE %> for further information.
|
25
|
+
|
26
|
+
Laborantin has been written by:
|
27
|
+
- <%= Laborantin::AUTHORS.join("\n- ") %>
|
28
|
+
|
29
|
+
Laborantin is licensend under the <%= Laborantin::LICENSE %>.
|
data/bin/files/TODO.erb
ADDED
data/bin/labor
ADDED
@@ -0,0 +1,226 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
#require 'rubygems'
|
5
|
+
require 'laborantin'
|
6
|
+
#require '../lib/laborantin'
|
7
|
+
require 'fileutils'
|
8
|
+
require 'find'
|
9
|
+
require 'erb'
|
10
|
+
|
11
|
+
class Command
|
12
|
+
attr_accessor :name, :description, :parser, :block, :options, :args
|
13
|
+
|
14
|
+
@@all = []
|
15
|
+
|
16
|
+
def initialize(name, description='')
|
17
|
+
@@all << self
|
18
|
+
@name = name
|
19
|
+
@description = description
|
20
|
+
@options = {}
|
21
|
+
@args = []
|
22
|
+
yield self
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.all
|
26
|
+
@@all
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.for_name(name)
|
30
|
+
@@all.find{|c| c.name == name}
|
31
|
+
end
|
32
|
+
|
33
|
+
def opts(&argblk)
|
34
|
+
@parser = OptionParser.new &argblk
|
35
|
+
script_name = File.basename($0)
|
36
|
+
@parser.summary_indent = "\t"
|
37
|
+
@parser.banner = %{Usage: #{script_name} #{name} [OPTIONS] [env1 [env2 ..]]}
|
38
|
+
@parser.banner << %{\n#{description}} unless description.empty?
|
39
|
+
end
|
40
|
+
|
41
|
+
def parse!(args)
|
42
|
+
begin
|
43
|
+
@args = @parser.parse args
|
44
|
+
rescue OptionParser::InvalidOption => err
|
45
|
+
puts err
|
46
|
+
puts @parser
|
47
|
+
exit
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def execute(&blk)
|
52
|
+
@block = blk
|
53
|
+
end
|
54
|
+
|
55
|
+
def execute!
|
56
|
+
self.instance_eval &@block if @block
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
Command.new('create', 'prepares a dir for laborantin measurements') do |c|
|
61
|
+
c.options[:scenarii] = []
|
62
|
+
c.options[:environments] = []
|
63
|
+
c.options[:force] = false
|
64
|
+
c.opts do |o|
|
65
|
+
o.on('-s', '--scenarii=OPTIONAL', 'scenarii to build, comma separated', Array) {|c.options[:scenarii]|}
|
66
|
+
o.on('-e', '--environments=OPTIONAL', 'environments to prepare, comma separated', Array) {|c.options[:environments]|}
|
67
|
+
o.on_tail('-f', '--force', 'force overwrite') {|c.options[:force]|}
|
68
|
+
o.on_tail('-h', '--help', 'shows this help and exit') {puts o; exit}
|
69
|
+
end
|
70
|
+
|
71
|
+
c.execute do
|
72
|
+
dir = args.shift
|
73
|
+
p dir #not for debug
|
74
|
+
unless c.options[:force]
|
75
|
+
begin
|
76
|
+
FileUtils.mkdir dir
|
77
|
+
rescue Errno::EEXIST => err
|
78
|
+
puts "Directory already exists, use -f/--force to overwrite (will overwrite all generated files, use at your own risk)."
|
79
|
+
exit
|
80
|
+
end
|
81
|
+
end
|
82
|
+
%w{environments scenarii results config scripts}.each do |w|
|
83
|
+
path = File.join( dir, w )
|
84
|
+
p path #not for debug
|
85
|
+
FileUtils.mkdir_p path
|
86
|
+
end
|
87
|
+
%w{README TODO config/ftp.yaml config/xmpp.yaml}.each do |w|
|
88
|
+
res_path = File.join(dir, w)
|
89
|
+
p res_path #not for debug
|
90
|
+
File.open(res_path, 'w') do |f|
|
91
|
+
tpl = ''
|
92
|
+
tpl_path = (File.join(File.dirname(__FILE__), 'files', "#{w}.erb"))
|
93
|
+
File.open(tpl_path) do |tf|
|
94
|
+
tpl = tf.read
|
95
|
+
end
|
96
|
+
erb = ERB.new tpl
|
97
|
+
erb.filename = res_path
|
98
|
+
f.puts erb.result(binding)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
@options[:scenarii].each do |s|
|
102
|
+
res_path = File.join(dir, 'scenarii', "#{s}.rb")
|
103
|
+
p res_path #not for debug
|
104
|
+
File.open(res_path, 'w') do |f|
|
105
|
+
tpl = ''
|
106
|
+
tpl_path = (File.join(File.dirname(__FILE__), 'files', 'scenarii', 'scenario.rb.erb'))
|
107
|
+
File.open(tpl_path) do |tf|
|
108
|
+
tpl = tf.read
|
109
|
+
end
|
110
|
+
erb = ERB.new tpl
|
111
|
+
erb.filename = res_path
|
112
|
+
f.puts erb.result(binding)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
@options[:environments].each do |e|
|
116
|
+
res_path = File.join(dir, 'environments', "#{e}.rb")
|
117
|
+
p res_path #not for debug
|
118
|
+
File.open(res_path, 'w') do |f|
|
119
|
+
tpl = ''
|
120
|
+
tpl_path = (File.join(File.dirname(__FILE__), 'files', 'environments', 'environment.rb.erb'))
|
121
|
+
File.open(tpl_path) do |tf|
|
122
|
+
tpl = tf.read
|
123
|
+
end
|
124
|
+
erb = ERB.new tpl
|
125
|
+
erb.filename = res_path
|
126
|
+
f.puts erb.result(binding)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
Command.new('describe', "describes a laborantin's work") do |c|
|
133
|
+
c.opts do |o|
|
134
|
+
o.on_tail('-h', '--help', 'shows this help and exit') {puts o; exit}
|
135
|
+
end
|
136
|
+
c.execute do
|
137
|
+
FileUtils.cd(args.first || '.')
|
138
|
+
Find.find('environments', 'scenarii') do |f|
|
139
|
+
require f if File.extname(f) == '.rb'
|
140
|
+
end
|
141
|
+
|
142
|
+
Laborantin::Environment.all.each {|e| p e}
|
143
|
+
Laborantin::Scenario.all.each {|s| p s}
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
|
149
|
+
|
150
|
+
Command.new('run', 'actually perform measurements') do |c|
|
151
|
+
c.options[:scenarii] = []
|
152
|
+
c.options[:environments] = []
|
153
|
+
c.options[:filter] = ''
|
154
|
+
c.opts do |o|
|
155
|
+
o.on('-s', '--scenarii=OPTIONAL', 'scenarii to build, comma separated', Array) {|c.options[:scenarii]|}
|
156
|
+
o.on('-e', '--environments=OPTIONAL', 'environments to prepare, comma separated', Array) {|c.options[:environments]|}
|
157
|
+
o.on('-p', '--parameters=OPTIONAL', 'filter parameters (ruby hash format)', String) {|c.options[:filter]|}
|
158
|
+
o.on_tail('-h', '--help', 'shows this help and exit') {puts o; exit}
|
159
|
+
end
|
160
|
+
c.execute do
|
161
|
+
dir = args.first || '.'
|
162
|
+
FileUtils.cd(dir)
|
163
|
+
Find.find('environments', 'scenarii') do |f|
|
164
|
+
require f if File.extname(f) == '.rb'
|
165
|
+
end
|
166
|
+
|
167
|
+
envs = if c.options[:environments].empty?
|
168
|
+
Laborantin::Environment.all
|
169
|
+
else
|
170
|
+
c.options[:environments].map!{|e| e.camelize}
|
171
|
+
Laborantin::Environment.all.select{|e| c.options[:environments].include? e.name}
|
172
|
+
end
|
173
|
+
|
174
|
+
scii = if c.options[:scenarii].empty?
|
175
|
+
Laborantin::Scenario.all
|
176
|
+
else
|
177
|
+
c.options[:scenarii].map!{|e| e.camelize}
|
178
|
+
Laborantin::Scenario.all.select{|e| c.options[:scenarii].include? e.name}
|
179
|
+
end
|
180
|
+
|
181
|
+
params = eval @options[:filter] unless @options[:filter].empty?
|
182
|
+
params.each_key{|k| params[k] = [params[k]].flatten} if params
|
183
|
+
|
184
|
+
envs.each do |eklass|
|
185
|
+
env = eklass.new
|
186
|
+
unless eklass.verifications.find{|v| not env.send(v)} #TODO: pass into class, rescue errors
|
187
|
+
env.prepare!
|
188
|
+
env.log "Running matching scenarii", :info #TODO: pass the logging+running in the env
|
189
|
+
scii.each do |sklass|
|
190
|
+
sklass.parameters.merge! params if params
|
191
|
+
env.log sklass.parameters.inspect
|
192
|
+
sklass.parameters.each_config do |cfg|
|
193
|
+
sc = sklass.new(env, cfg)
|
194
|
+
sc.prepare!
|
195
|
+
sc.perform!
|
196
|
+
sc.analyze!
|
197
|
+
end
|
198
|
+
end
|
199
|
+
env.log "Scenarii performed", :info
|
200
|
+
env.analyze!
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
=begin
|
207
|
+
TODO: replay, scan, push, pull
|
208
|
+
=end
|
209
|
+
|
210
|
+
cmd = Command.for_name ARGV.first
|
211
|
+
|
212
|
+
if cmd
|
213
|
+
cmd.parse!(ARGV.dup[1 .. -1])
|
214
|
+
cmd.execute!
|
215
|
+
else
|
216
|
+
if ARGV.empty?
|
217
|
+
puts %{#{$0} v.#{Laborantin::VERSION}: No command given
|
218
|
+
|
219
|
+
Usage: #{$0} <command> [options ...]
|
220
|
+
<command> among: #{Command.all.map{|c| c.name}.join(', ')}
|
221
|
+
|
222
|
+
use #{$0} <command> --help for help on a specific command}
|
223
|
+
else
|
224
|
+
print "unknown command #{ARGV.first}"
|
225
|
+
end
|
226
|
+
end
|
@@ -21,84 +21,86 @@ Copyright (c) 2009, Lucas Di Cioccio
|
|
21
21
|
|
22
22
|
=end
|
23
23
|
|
24
|
-
|
25
24
|
require 'time'
|
26
25
|
require 'logger'
|
27
26
|
require 'fileutils'
|
28
27
|
|
29
28
|
module Laborantin
|
30
29
|
class Environment
|
30
|
+
@@all = []
|
31
|
+
@@rootdir = '.'
|
32
|
+
class << self
|
33
|
+
attr_accessor :verifications, :description, :envdir
|
31
34
|
|
32
|
-
|
35
|
+
def rootdir=(dir='.')
|
36
|
+
@@rootdir = dir
|
37
|
+
end
|
33
38
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
@scenarii = []
|
38
|
-
@dates = {}
|
39
|
-
self.instance_eval &blk if block_given?
|
40
|
-
end
|
39
|
+
def rootdir
|
40
|
+
@@rootdir || '.'
|
41
|
+
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
scenarii << klass
|
46
|
-
klass.name = sc_name
|
47
|
-
klass.description = desc
|
48
|
-
klass.env = self
|
49
|
-
klass.instance_eval &blk
|
50
|
-
end
|
43
|
+
def resultdir
|
44
|
+
@@resultdir = File.join(@@rootdir, 'results')
|
45
|
+
end
|
51
46
|
|
52
|
-
|
53
|
-
|
54
|
-
|
47
|
+
def inherited(klass)
|
48
|
+
klass.verifications = []
|
49
|
+
klass.description = ''
|
50
|
+
@@all << klass
|
51
|
+
end
|
55
52
|
|
56
|
-
|
57
|
-
|
58
|
-
FileUtils.mkpath(env_dirname) #TODO: clean that
|
59
|
-
log!(Logger.new(File.join(env_dirname, 'environment.log')))
|
60
|
-
@scenarii.each do |sc|
|
61
|
-
info scenario_start_msg(sc)
|
62
|
-
sc.parameters.each_config do |cfg|
|
63
|
-
info "--- #{cfg.inspect}"
|
64
|
-
perform_scenario(sc, cfg)
|
65
|
-
end
|
66
|
-
info scenario_end_msg(sc)
|
53
|
+
def verify(*args)
|
54
|
+
self.verifications = [*args].flatten
|
67
55
|
end
|
68
|
-
@dates[:end] = Time.now
|
69
|
-
end
|
70
56
|
|
71
|
-
|
72
|
-
|
73
|
-
|
57
|
+
def describe(str)
|
58
|
+
self.description = str
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_s
|
62
|
+
"#{self.name}:\n\t#{self.description}"
|
63
|
+
end
|
74
64
|
|
75
|
-
|
76
|
-
|
77
|
-
|
65
|
+
def all
|
66
|
+
@@all
|
67
|
+
end
|
68
|
+
|
69
|
+
def envdir
|
70
|
+
File.join(resultdir, self.name.duck_case)
|
71
|
+
end
|
78
72
|
|
79
|
-
def perform_scenario(sc, cfg)
|
80
|
-
sc.new(cfg).perform!
|
81
73
|
end
|
82
74
|
|
83
|
-
|
84
|
-
|
75
|
+
attr_accessor :rundir, :date, :loggers
|
76
|
+
|
77
|
+
def initialize(dir='.')
|
78
|
+
@date = Time.now
|
79
|
+
@rundir = File.join(self.class.envdir, date_str)
|
80
|
+
@loggers = []
|
85
81
|
end
|
86
82
|
|
87
|
-
def
|
88
|
-
|
83
|
+
def prepare!
|
84
|
+
FileUtils.mkdir_p(rundir) #TODO: ensure unicity
|
85
|
+
@loggers << Logger.new(File.join(rundir, 'environment.log'))
|
86
|
+
@loggers << Logger.new(STDOUT)
|
87
|
+
log(self.class.description, :info) unless self.class.description.empty?
|
88
|
+
log "Directories prepared"
|
89
89
|
end
|
90
90
|
|
91
|
-
def
|
92
|
-
|
91
|
+
def analyze!
|
92
|
+
#TODO
|
93
93
|
end
|
94
94
|
|
95
|
-
def
|
96
|
-
|
95
|
+
def log(str, lvl=:debug)
|
96
|
+
@loggers.each{|l| l.send(lvl, str)}
|
97
97
|
end
|
98
98
|
|
99
|
-
|
100
|
-
|
99
|
+
private
|
100
|
+
|
101
|
+
def date_str
|
102
|
+
date.strftime("%Y-%h-%d_%H-%M-%S")
|
101
103
|
end
|
102
104
|
|
103
|
-
end
|
104
|
-
end
|
105
|
+
end # class
|
106
|
+
end # module
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
#core/monkey_patchs.rb
|
2
2
|
|
3
3
|
=begin
|
4
4
|
|
@@ -21,14 +21,12 @@ Copyright (c) 2009, Lucas Di Cioccio
|
|
21
21
|
|
22
22
|
=end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
xmpp.level = level
|
31
|
-
log! xmpp
|
32
|
-
end
|
24
|
+
class String
|
25
|
+
def camelize
|
26
|
+
self.split('_').map{|i| i.capitalize}.join('')
|
27
|
+
end
|
28
|
+
def duck_case
|
29
|
+
self.gsub(/([A-Z])/){|s| "_#{$1.downcase}"}.sub(/^_/,'')
|
33
30
|
end
|
34
31
|
end
|
32
|
+
|
@@ -23,10 +23,11 @@ Copyright (c) 2009, Lucas Di Cioccio
|
|
23
23
|
|
24
24
|
module Laborantin
|
25
25
|
class ParameterRange
|
26
|
-
attr_accessor :name
|
26
|
+
attr_accessor :name, :description
|
27
27
|
def initialize(name)
|
28
28
|
@name = name
|
29
29
|
@values = []
|
30
|
+
@description = ''
|
30
31
|
end
|
31
32
|
|
32
33
|
def values(*args)
|
@@ -39,5 +40,13 @@ module Laborantin
|
|
39
40
|
yield v
|
40
41
|
end
|
41
42
|
end
|
43
|
+
|
44
|
+
def describe(str)
|
45
|
+
@description = str
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_s
|
49
|
+
"#{values.inspect}\n\t\t#{@description}"
|
50
|
+
end
|
42
51
|
end
|
43
52
|
end
|
@@ -29,13 +29,31 @@ require 'yaml'
|
|
29
29
|
|
30
30
|
module Laborantin
|
31
31
|
class Scenario
|
32
|
+
@@all = []
|
32
33
|
class << self
|
33
|
-
attr_accessor :
|
34
|
+
attr_accessor :description, :parameters, :products, :hooks
|
35
|
+
|
34
36
|
def inherited(klass)
|
35
37
|
klass.parameters = ParameterHash.new
|
36
|
-
klass.
|
38
|
+
klass.description = ''
|
39
|
+
klass.products = []
|
40
|
+
klass.hooks = {:setup => [], :teardown => []}
|
41
|
+
@@all << klass
|
42
|
+
end
|
43
|
+
|
44
|
+
def describe(str)
|
45
|
+
self.description = str
|
46
|
+
end
|
47
|
+
|
48
|
+
def setup(*args)
|
49
|
+
self.hooks[:setup] = [*args].flatten
|
50
|
+
end
|
51
|
+
|
52
|
+
def teardown(*args)
|
53
|
+
self.hooks[:teardown] = [*args].flatten
|
37
54
|
end
|
38
55
|
|
56
|
+
|
39
57
|
def parameter(name, &blk)
|
40
58
|
raise ArgumentError.new("Parameter #{name} already exists") if self.parameters[name]
|
41
59
|
param = ParameterRange.new(name)
|
@@ -43,49 +61,102 @@ module Laborantin
|
|
43
61
|
self.parameters[name] = param
|
44
62
|
end
|
45
63
|
|
46
|
-
def
|
47
|
-
self.
|
64
|
+
def produces(*args)
|
65
|
+
self.products = [*args].flatten
|
66
|
+
end
|
67
|
+
|
68
|
+
def to_s
|
69
|
+
"#{self.name}:\n\t#{self.description}\n#{self.parameters}"
|
48
70
|
end
|
49
71
|
|
50
|
-
def
|
51
|
-
|
72
|
+
def all
|
73
|
+
@@all
|
52
74
|
end
|
53
|
-
end # class <<
|
54
75
|
|
55
|
-
|
76
|
+
def scenardir(env=nil)
|
77
|
+
envdir = env.rundir || '.'
|
78
|
+
File.join(envdir, self.name.duck_case)
|
79
|
+
end
|
80
|
+
end # class <<
|
56
81
|
|
57
|
-
|
82
|
+
attr_reader :params, :environment, :date, :rundir
|
83
|
+
|
84
|
+
def initialize(env, params={})
|
85
|
+
@environment = env
|
58
86
|
@params = params
|
59
|
-
@
|
60
|
-
|
87
|
+
@date = Time.now
|
88
|
+
@rundir = File.join(self.class.scenardir(environment), date_str)
|
61
89
|
end
|
62
90
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
File.open( config_file, 'w+') {|f| f.puts YAML.dump( [Time.now, params] ) }
|
91
|
+
def prepare!
|
92
|
+
log(self.class.description, :info) unless self.class.description.empty?
|
93
|
+
log self.params.inspect, :info
|
94
|
+
log "Preparing directory #{rundir}"
|
95
|
+
FileUtils.mkdir_p(rundir) #TODO: ensure unicity
|
96
|
+
log "Storing configuration in YAML format"
|
97
|
+
File.open( config_path, 'w') {|f| f.puts YAML.dump( [date, params] ) }
|
71
98
|
end
|
72
99
|
|
73
100
|
def perform!
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
101
|
+
call_hooks :setup
|
102
|
+
log "Starting measurement"
|
103
|
+
raw_result_file('w') do |f|
|
104
|
+
run do |l|
|
105
|
+
f.puts l
|
106
|
+
end
|
107
|
+
end
|
108
|
+
log "Measurement finished"
|
109
|
+
call_hooks :teardown
|
110
|
+
end
|
111
|
+
|
112
|
+
def analyze!
|
113
|
+
self.class.products.each do |name|
|
114
|
+
log "Producing #{name}"
|
115
|
+
product_file(name.to_s, 'w') do |f|
|
116
|
+
send name do |l|
|
117
|
+
f.puts l
|
118
|
+
end
|
119
|
+
end
|
120
|
+
log "Product #{name} done"
|
78
121
|
end
|
79
|
-
call_hook :after
|
80
122
|
end
|
81
123
|
|
82
|
-
|
83
|
-
|
84
|
-
|
124
|
+
private
|
125
|
+
|
126
|
+
def call_hooks(name)
|
127
|
+
log "Calling #{name} hooks"
|
128
|
+
self.class.hooks[name].each{|sym| send sym}
|
129
|
+
end
|
130
|
+
|
131
|
+
def date_str
|
132
|
+
date.strftime("%Y-%h-%d_%H-%M-%S")
|
133
|
+
end
|
134
|
+
|
135
|
+
def log(*args)
|
136
|
+
environment.log *args
|
137
|
+
end
|
138
|
+
|
139
|
+
def product_path(resultname, brutname=false)
|
140
|
+
resultname = "result.#{resultname}.txt" unless brutname
|
141
|
+
File.join(rundir, resultname)
|
142
|
+
end
|
143
|
+
|
144
|
+
def product_file(resultname, mode='r', brutname=false)
|
145
|
+
File.open(product_path(resultname, brutname), mode) do |f|
|
146
|
+
yield f
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def config_path
|
151
|
+
product_path('config.yaml', true)
|
152
|
+
end
|
153
|
+
|
154
|
+
def raw_result_path
|
155
|
+
product_path('result.raw', true)
|
85
156
|
end
|
86
157
|
|
87
|
-
def
|
88
|
-
|
158
|
+
def raw_result_file(mode='r')
|
159
|
+
product_file('result.raw', mode, true){|f| yield f}
|
89
160
|
end
|
90
161
|
|
91
162
|
end # class
|
data/lib/laborantin.rb
CHANGED
@@ -25,104 +25,11 @@ require File.join(File.dirname(__FILE__), 'laborantin', 'core', 'scenario')
|
|
25
25
|
require File.join(File.dirname(__FILE__), 'laborantin', 'core', 'parameter')
|
26
26
|
require File.join(File.dirname(__FILE__), 'laborantin', 'core', 'parameter_hash')
|
27
27
|
require File.join(File.dirname(__FILE__), 'laborantin', 'core', 'environment')
|
28
|
-
|
29
|
-
require 'optparse'
|
28
|
+
require File.join(File.dirname(__FILE__), 'laborantin', 'core', 'monkey_patches')
|
30
29
|
|
31
30
|
module Laborantin
|
32
|
-
VERSION = '0.0.
|
31
|
+
VERSION = '0.0.4'
|
33
32
|
AUTHORS = ['Lucas Di Cioccio']
|
34
33
|
WEBSITE = 'http://dicioccio.fr'
|
35
|
-
|
36
|
-
@@env = []
|
37
|
-
|
38
|
-
def environment(name='results', &blk)
|
39
|
-
env = Environment.new(name)
|
40
|
-
env.instance_eval &blk
|
41
|
-
@@env << env
|
42
|
-
end
|
43
|
-
|
44
|
-
def show_env(e)
|
45
|
-
puts "+==/ #{e.name} /==="
|
46
|
-
e.scenarii.each do |s|
|
47
|
-
puts "| #{s.name} : #{s.description} "
|
48
|
-
s.parameters.each_pair do |n, pa|
|
49
|
-
puts "| [#{pa.name}] => #{pa.values.inspect}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
puts '+' + '=' * (e.name.to_s.size + 8)
|
53
|
-
end
|
54
|
-
|
55
|
-
def run_env(e)
|
56
|
-
e.run_scenarii!
|
57
|
-
end
|
58
|
-
|
59
|
-
def scan_scenario(s)
|
60
|
-
realisations = Dir.entries(s).select{|path| not path =~ /^\./ }
|
61
|
-
puts "| [#{File.basename(s)}] => #{realisations.size} "
|
62
|
-
end
|
63
|
-
|
64
|
-
def scan_env(e)
|
65
|
-
puts "+==/ #{e} /==="
|
66
|
-
result_dir = e
|
67
|
-
|
68
|
-
if File.directory?(result_dir)
|
69
|
-
runs = Dir.entries(result_dir).select{|path| not path =~ /^\./}
|
70
|
-
runs.each do |r|
|
71
|
-
puts "| ° #{r}"
|
72
|
-
env_rootname = File.join(result_dir, r)
|
73
|
-
scenarii = Dir.entries(env_rootname).select{|path| not path =~ /^\./}
|
74
|
-
scenarii.each do |s|
|
75
|
-
s = File.join(env_rootname, s)
|
76
|
-
scan_scenario(s) if File.directory?(s)
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
80
|
-
puts '+' + '=' * (e.size + 8)
|
81
|
-
end
|
82
|
-
|
83
|
-
at_exit do
|
84
|
-
|
85
|
-
#Default opts
|
86
|
-
OPTIONS = { :list => false,
|
87
|
-
:run => false,
|
88
|
-
:scan => false,
|
89
|
-
:replay => false }
|
90
|
-
|
91
|
-
#Parsing
|
92
|
-
ARGV.options do |o|
|
93
|
-
script_name = File.basename($0)
|
94
|
-
o.set_summary_indent("\t")
|
95
|
-
o.banner = "Usage: #{script_name} [OPTIONS] [env1 [env2 ..]]"
|
96
|
-
o.on("-d", "--describe", "Describe available environments") { |OPTIONS[:list]| }
|
97
|
-
o.on("-r", "--run", "Run environments") { |OPTIONS[:run]| }
|
98
|
-
o.on("-s", "--scan", "Eye-candy scan for environments results") {|OPTIONS[:scan]|}
|
99
|
-
o.on_tail("-h", "--h", "Show this help.") {puts o; exit}
|
100
|
-
o.parse!
|
101
|
-
end
|
102
|
-
|
103
|
-
#Parsing remaining args
|
104
|
-
env_list = if ARGV.empty?
|
105
|
-
@@env
|
106
|
-
else
|
107
|
-
ARGV.map{|n| @@env.find{|e| e.name.to_s == n} }.compact
|
108
|
-
end
|
109
|
-
|
110
|
-
#Running wrt to the opts
|
111
|
-
if OPTIONS[:list]
|
112
|
-
env_list.each {|e| show_env(e) }
|
113
|
-
exit
|
114
|
-
end
|
115
|
-
|
116
|
-
if OPTIONS[:run]
|
117
|
-
env_list.each {|e| run_env(e) }
|
118
|
-
exit
|
119
|
-
end
|
120
|
-
|
121
|
-
if OPTIONS[:scan]
|
122
|
-
env_list.each {|e| scan_env(e.env_rootname)}
|
123
|
-
exit
|
124
|
-
end
|
125
|
-
|
126
|
-
puts "Run with -h or --help for help"
|
127
|
-
end
|
34
|
+
LICENSE = 'GNU GPL version 3'
|
128
35
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: laborantin
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Di Cioccio Lucas
|
@@ -9,14 +9,14 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-07-
|
12
|
+
date: 2009-07-20 00:00:00 +02:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
16
|
description:
|
17
17
|
email: lucas.dicioccio<@nospam@>frihd.net
|
18
|
-
executables:
|
19
|
-
|
18
|
+
executables:
|
19
|
+
- labor
|
20
20
|
extensions: []
|
21
21
|
|
22
22
|
extra_rdoc_files: []
|
@@ -27,12 +27,19 @@ files:
|
|
27
27
|
- gpl-3.0.txt
|
28
28
|
- Rakefile
|
29
29
|
- TODO
|
30
|
+
- bin/labor
|
31
|
+
- bin/files/README.erb
|
32
|
+
- bin/files/TODO.erb
|
33
|
+
- bin/files/config/ftp.yaml.erb
|
34
|
+
- bin/files/config/xmpp.yaml.erb
|
35
|
+
- bin/files/environments/environment.rb.erb
|
36
|
+
- bin/files/scenarii/scenario.rb.erb
|
30
37
|
- lib/laborantin.rb
|
31
38
|
- lib/laborantin/core/environment.rb
|
32
39
|
- lib/laborantin/core/parameter.rb
|
33
40
|
- lib/laborantin/core/parameter_hash.rb
|
34
41
|
- lib/laborantin/core/scenario.rb
|
35
|
-
- lib/laborantin/
|
42
|
+
- lib/laborantin/core/monkey_patches.rb
|
36
43
|
has_rdoc: false
|
37
44
|
homepage: http://rubyforge.org/projects/laborantin
|
38
45
|
post_install_message:
|