rutema 1.1.3 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/.gemtest +0 -0
  2. data/History.txt +5 -0
  3. data/Manifest.txt +28 -23
  4. data/README.md +91 -0
  5. data/README.txt +2 -10
  6. data/Rakefile +6 -9
  7. data/bin/rutema +9 -0
  8. data/bin/rutemax +2 -0
  9. data/lib/rutema/configuration.rb +7 -8
  10. data/lib/rutema/elements/minimal.rb +45 -0
  11. data/lib/rutema/gems.rb +3 -3
  12. data/lib/rutema/models/activerecord.rb +164 -0
  13. data/lib/rutema/models/base.rb +5 -0
  14. data/lib/rutema/{specification.rb → objectmodel.rb} +4 -10
  15. data/lib/rutema/parsers/base.rb +29 -0
  16. data/lib/rutema/parsers/xml.rb +186 -0
  17. data/lib/rutema/reporters/activerecord.rb +9 -18
  18. data/lib/rutema/{reporter.rb → reporters/base.rb} +3 -7
  19. data/lib/rutema/reporters/email.rb +2 -5
  20. data/lib/rutema/reporters/text.rb +2 -2
  21. data/lib/rutema/reporters/yaml.rb +1 -2
  22. data/lib/rutema/runners/default.rb +157 -0
  23. data/lib/rutema/runners/step.rb +23 -0
  24. data/lib/rutema/system.rb +15 -420
  25. data/test/distro_test/config/full.rutema +2 -0
  26. data/test/distro_test/specs/check.spec +8 -0
  27. data/test/distro_test/specs/duplicate_name.spec +8 -0
  28. data/test/distro_test/specs/fail.spec +9 -0
  29. data/test/distro_test/specs/setup.spec +8 -0
  30. data/test/distro_test/specs/teardown.spec +8 -0
  31. data/test/rutema.rutema +1 -1
  32. data/test/rutema.spec +5 -5
  33. data/test/test_activerecord.rb +0 -0
  34. data/test/test_configuration.rb +7 -9
  35. data/test/test_couchdb.rb +14 -0
  36. data/test/{test_specification.rb → test_objectmodel.rb} +8 -11
  37. data/test/test_parsers.rb +136 -0
  38. data/test/test_rake.rb +2 -3
  39. data/test/{test_reporter.rb → test_reporters.rb} +0 -0
  40. data/test/test_runners.rb +72 -0
  41. data/test/test_system.rb +3 -166
  42. metadata +57 -62
  43. data/bin/rutema_upgrader +0 -81
  44. data/distro_test.sh +0 -6
  45. data/lib/rutema/model.rb +0 -231
  46. data/lib/rutema/reporters/couchdb.rb +0 -62
  47. data/lib/rutema/reporters/standard_reporters.rb +0 -7
  48. data/selftest.sh +0 -2
  49. data/test/data/sample09.db +0 -0
  50. data/test/migration.spec +0 -9
  51. data/test/test_model.rb +0 -62
@@ -0,0 +1,157 @@
1
+ # Copyright (c) 2007-2011 Vassilis Rizopoulos. All rights reserved.
2
+ $:.unshift File.join(File.dirname(__FILE__),'..','..')
3
+
4
+ module Rutema
5
+ #Runner executes TestScenario instances and maintains the state of all scenarios run.
6
+ class Runner
7
+ attr_reader :states,:number_of_runs,:context
8
+ attr_accessor :setup,:teardown
9
+ attr_writer :attended
10
+
11
+ #setup and teardown are TestScenario instances that will run before and after each call
12
+ #to the scenario.
13
+ def initialize context=nil,setup=nil, teardown=nil,logger=nil
14
+ @setup=setup
15
+ @teardown=teardown
16
+ @attended=false
17
+ @logger=logger
18
+ @logger||=Patir.setup_logger
19
+ @states=Hash.new
20
+ @number_of_runs=0
21
+ @context=context || Hash.new
22
+ end
23
+
24
+ #Tells you if the system runs in the mode that expects user input
25
+ def attended?
26
+ return @attended
27
+ end
28
+ #Runs a scenario and stores the result internally
29
+ #
30
+ #Returns the result of the run as a Patir::CommandSequenceStatus
31
+ def run name,scenario, run_setup=true
32
+ @logger.debug("Starting run for #{name} with #{scenario.inspect}")
33
+ @context[:scenario_name]=name
34
+ #if setup /teardown is defined we need to execute them before and after
35
+ if @setup && run_setup
36
+ @logger.info("Setup for #{name}")
37
+ @states["#{name}_setup"]=run_scenario("#{name}_setup",@setup)
38
+ @states["#{name}_setup"].sequence_id="s#{@number_of_runs}"
39
+ if @states["#{name}_setup"].executed?
40
+ #do not execute the scenario unless the setup was succesful
41
+ if @states["#{name}_setup"].success?
42
+ @logger.info("Scenario for #{name}")
43
+ @states[name]=run_scenario(name,scenario)
44
+ @states[name].sequence_id="#{@number_of_runs}"
45
+ else
46
+ @states[name]=initialize_state(name,scenario)
47
+ @states[name].sequence_id="#{@number_of_runs}"
48
+ end
49
+ end
50
+ else
51
+ @logger.info("Scenario for #{name}")
52
+ @states[name]=run_scenario(name,scenario)
53
+ @states[name].sequence_id="#{@number_of_runs}"
54
+ end
55
+ #no setup means no teardown
56
+ if @teardown && run_setup
57
+ #always execute teardown
58
+ @logger.warn("Teardown for #{name}")
59
+ @states["#{name}_teardown"]=run_scenario("#{name}_teardown",@teardown)
60
+ @states["#{name}_teardown"].sequence_id="#{@number_of_runs}t"
61
+ end
62
+ @number_of_runs+=1
63
+ @context[:scenario_name]=nil
64
+ return @states[name]
65
+ end
66
+
67
+ #Returns the state of the scenario with the given name.
68
+ #
69
+ #Will return nil if no scenario is found under that name.
70
+ def [](name)
71
+ return @states[name]
72
+ end
73
+
74
+ #Resets the Runner's internal state
75
+ def reset
76
+ @states.clear
77
+ @number_of_runs=0
78
+ end
79
+
80
+ #returns true if all the scenarios in the last run were succesful or if nothing was run yet
81
+ def success?
82
+ @success=true
83
+ @states.each do |k,v|
84
+ @success&=(v.status!=:error)
85
+ end
86
+ return @success
87
+ end
88
+ private
89
+ def run_scenario name,scenario
90
+ state=initialize_state(name,scenario)
91
+ begin
92
+ if evaluate_attention(scenario,state)
93
+ stps=scenario.steps
94
+ if stps.empty?
95
+ @logger.warn("Scenario #{name} contains no steps")
96
+ state.status=:warning
97
+ else
98
+ stps.each do |s|
99
+ state.step=run_step(s)
100
+ break if :error==state.status
101
+ end
102
+ end
103
+ end
104
+ rescue
105
+ @logger.error("Encountered error in #{name}: #{$!.message}")
106
+ @logger.debug($!)
107
+ state.status=:error
108
+ end
109
+ state.stop_time=Time.now
110
+ state.sequence_id=@number_of_runs
111
+ return state
112
+ end
113
+ def initialize_state name,scenario
114
+ state=Patir::CommandSequenceStatus.new(name,scenario.steps)
115
+ end
116
+ def evaluate_attention scenario,state
117
+ if scenario.attended?
118
+ if !self.attended?
119
+ @logger.warn("Attended scenario cannot be run in unattended mode")
120
+ state.status=:warning
121
+ return false
122
+ end
123
+ state.strategy=:attended
124
+ else
125
+ state.strategy=:unattended
126
+ end
127
+ return true
128
+ end
129
+ def run_step step
130
+ @logger.info("Running step #{step.number} - #{step.name}")
131
+ if step.has_cmd? && step.cmd.respond_to?(:run)
132
+ step.cmd.run(@context)
133
+ msg=step.to_s
134
+ if !step.cmd.success?
135
+ msg<<"\n#{step.cmd.output}" unless step.cmd.output.empty?
136
+ msg<<"\n#{step.cmd.error}" unless step.cmd.error.empty?
137
+ end
138
+ else
139
+ @logger.warn("No command associated with step '#{step.step_type}'. Step number is #{step.number}")
140
+ end
141
+ step.status=:success if step.status==:error && step.ignore?
142
+ log_step_result(step,msg)
143
+ return step
144
+ end
145
+ def log_step_result step,msg
146
+ if step.status==:error
147
+ if step.ignore?
148
+ @logger.warn("Step failed but result is being ignored!\n#{msg}")
149
+ else
150
+ @logger.error(msg)
151
+ end
152
+ else
153
+ @logger.info(msg) if msg && !msg.empty?
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,23 @@
1
+ # Copyright (c) 2007-2011 Vassilis Rizopoulos. All rights reserved.
2
+ $:.unshift File.join(File.dirname(__FILE__),'..','..')
3
+
4
+ require 'rutema/runners/default'
5
+
6
+ module Rutema
7
+ #StepRunner halts before every step and asks if it should be executed or not.
8
+ class StepRunner<Runner
9
+ def initialize setup=nil, teardown=nil,logger=nil
10
+ @questioner=HighLine.new
11
+ super(setup,teardown,logger)
12
+ end
13
+ def run_step step
14
+ if @questioner.agree("Execute #{step.to_s}?")
15
+ return super(step)
16
+ else
17
+ msg="#{step.number} - #{step.step_type} - #{step.status}"
18
+ @logger.info(msg)
19
+ return step
20
+ end
21
+ end
22
+ end
23
+ end
data/lib/rutema/system.rb CHANGED
@@ -4,259 +4,27 @@ require 'rexml/document'
4
4
  require 'patir/configuration'
5
5
  require 'patir/command'
6
6
  require 'patir/base'
7
- require 'rutema/specification'
8
7
  require 'rutema/configuration'
9
- require 'rutema/reporters/standard_reporters'
8
+
9
+ require 'rutema/parsers/base'
10
+ require 'rutema/parsers/xml'
11
+
12
+ require 'rutema/runners/default'
13
+ require 'rutema/runners/step'
14
+
15
+ require 'rutema/reporters/activerecord'
16
+ require 'rutema/reporters/text'
17
+ require 'rutema/reporters/yaml'
18
+ require 'rutema/reporters/email'
10
19
 
11
20
  module Rutema
12
21
  #This module defines the version numbers for the library
13
22
  module Version
14
23
  MAJOR=1
15
- MINOR=1
16
- TINY=3
24
+ MINOR=2
25
+ TINY=0
17
26
  STRING=[ MAJOR, MINOR, TINY ].join( "." )
18
27
  end
19
- #The Elements module provides the namespace for the various modules adding parser functionality
20
- module Elements
21
- #Minimal offers a minimal(chic) set of elements for use in specifications
22
- #
23
- #These are:
24
- # echo
25
- # command
26
- # prompt
27
- module Minimal
28
- #echo prints a message on the screen:
29
- # <echo text="A meaningful message"/>
30
- # <echo>A meaningful message</echo>
31
- def element_echo step
32
- step.cmd=Patir::RubyCommand.new("echo"){|cmd| cmd.error="";cmd.output="#{step.text}";$stdout.puts(cmd.output) ;:success}
33
- end
34
- #prompt asks the user a yes/no question. Answering yes means the step is succesful.
35
- # <prompt text="Do you want fries with that?"/>
36
- #
37
- #A prompt element automatically makes a specification "attended"
38
- def element_prompt step
39
- step.attended=true
40
- step.cmd=Patir::RubyCommand.new("prompt") do |cmd|
41
- cmd.output=""
42
- cmd.error=""
43
- if HighLine.new.agree("#{step.text}")
44
- step.output="y"
45
- else
46
- raise "n"
47
- end#if
48
- end#do rubycommand
49
- end
50
- #command executes a shell command
51
- # <command cmd="useful_command.exe with parameters", working_directory="some/directory"/>
52
- def element_command step
53
- raise ParserError,"missing required attribute cmd in #{step}" unless step.has_cmd?
54
- wd=Dir.pwd
55
- wd=step.working_directory if step.has_working_directory?
56
- step.cmd=Patir::ShellCommand.new(:cmd=>step.cmd,:working_directory=>File.expand_path(wd))
57
- end
58
- end
59
- end
60
- #Is raised when an error is found in a specification
61
- class ParserError<RuntimeError
62
- end
63
-
64
- #Base class that bombs out when used.
65
- #
66
- #Initialze expects a hash and as a base implementation assigns :logger as the internal logger.
67
- #
68
- #By default the internal logger will log to the console if no logger is provided.
69
- class SpecificationParser
70
- attr_reader :configuration
71
- def initialize params
72
- @logger=params[:logger]
73
- @logger||=Patir.setup_logger
74
- @configuration=params[:configuration]
75
- @logger.warn("No system configuration provided to the parser") unless @configuration
76
- end
77
-
78
- def parse_specification param
79
- raise ParserError,"not implemented. You should derive a parser implementation from SpecificationParser!"
80
- end
81
- end
82
-
83
- #BaseXMLParser encapsulates all the XML parsing code
84
- class BaseXMLParser<SpecificationParser
85
- ELEM_SPEC="specification"
86
- ELEM_DESC="specification/description"
87
- ELEM_TITLE="specification/title"
88
- ELEM_SCENARIO="specification/scenario"
89
- ELEM_REQ="requirement"
90
- #Parses __param__ and returns the Rutema::TestSpecification instance
91
- #
92
- #param can be the filename of the specification or the contents of that file.
93
- #
94
- #Will throw ParserError if something goes wrong
95
- def parse_specification param
96
- @logger.debug("Loading #{param}")
97
- begin
98
- if File.exists?(param)
99
- #read the file
100
- txt=File.read(param)
101
- filename=File.expand_path(param)
102
- else
103
- filename=Dir.pwd
104
- #try to parse the parameter
105
- txt=param
106
- end
107
- spec=parse_case(txt,filename)
108
- raise "Missing required attribute 'name' in specification element" unless spec.has_name? && !spec.name.empty?
109
- return spec
110
- rescue
111
- @logger.debug($!)
112
- raise ParserError,"Error loading #{param}: #{$!.message}"
113
- end
114
- end
115
-
116
- private
117
- #Parses the XML specification of a testcase and creates the corresponding TestSpecification instance
118
- def parse_case xmltxt,filename
119
- #the testspec to return
120
- spec=TestSpecification.new
121
- #read the test spec
122
- xmldoc=REXML::Document.new( xmltxt )
123
- #validate it
124
- validate_case(xmldoc)
125
- #parse it
126
- el=xmldoc.elements[ELEM_SPEC]
127
- xmldoc.root.attributes.each do |attr,value|
128
- add_attribute(spec,attr,value)
129
- end
130
- #get the title
131
- spec.title=xmldoc.elements[ELEM_TITLE].text
132
- spec.title||=""
133
- spec.title.strip!
134
- #get the description
135
- #strip line feeds, cariage returns and remove all tabs
136
- spec.description=xmldoc.elements[ELEM_DESC].text
137
- spec.description||=""
138
- begin
139
- spec.description.strip!
140
- spec.description.gsub!(/\t/,'')
141
- end unless spec.description.empty?
142
- #get the requirements
143
- reqs=el.elements.select{|e| e.name==ELEM_REQ}
144
- reqs.collect!{|r| r.attributes["name"]}
145
- spec.requirements=reqs
146
- #Get the scenario
147
- Dir.chdir(File.dirname(filename)) do
148
- spec.scenario=parse_scenario(xmldoc.elements[ELEM_SCENARIO].to_s) if xmldoc.elements[ELEM_SCENARIO]
149
- end
150
- spec.filename=filename
151
- return spec
152
- end
153
- #Validates the XML file from our point of view.
154
- #
155
- #Checks for the existence of ELEM_SPEC, ELEM_DESC and ELEM_TITLE and raises ParserError if they're missing.
156
- def validate_case xmldoc
157
- raise ParserError,"missing #{ELEM_SPEC} element" unless xmldoc.elements[ELEM_SPEC]
158
- raise ParserError,"missing #{ELEM_DESC} element" unless xmldoc.elements[ELEM_DESC]
159
- raise ParserError,"missing #{ELEM_TITLE} element" unless xmldoc.elements[ELEM_TITLE]
160
- end
161
-
162
- #Parses the scenario XML element and returns the Rutema::TestScenario instance
163
- def parse_scenario xmltxt
164
- @logger.debug("Parsing scenario from #{xmltxt}")
165
- scenario=Rutema::TestScenario.new
166
- xmldoc=REXML::Document.new( xmltxt )
167
- xmldoc.root.attributes.each do |attr,value|
168
- add_attribute(scenario,attr,value)
169
- end
170
- number=0
171
- xmldoc.root.elements.each do |el|
172
- step=parse_step(el.to_s)
173
- if step.step_type=="include_scenario"
174
- included_scenario=include_scenario(step)
175
- included_scenario.steps.each do |st|
176
- @logger.debug("Adding included step #{st}")
177
- number+=1
178
- st.number=number
179
- st.included_in=step.file
180
- scenario.add_step(st)
181
- end
182
- else
183
- number+=1
184
- step.number=number
185
- scenario.add_step(step)
186
- end
187
- end
188
- return scenario
189
- end
190
-
191
- #Parses xml and returns the Rutema::TestStep instance
192
- def parse_step xmltxt
193
- xmldoc=REXML::Document.new( xmltxt )
194
- #any step element
195
- step=Rutema::TestStep.new()
196
- step.ignore=false
197
- xmldoc.root.attributes.each do |attr,value|
198
- add_attribute(step,attr,value)
199
- end
200
- step.text=xmldoc.root.text.strip if xmldoc.root.text
201
- step.step_type=xmldoc.root.name
202
- return step
203
- end
204
-
205
- def add_attribute element,attr,value
206
- if boolean?(value)
207
- element.attribute(attr,eval(value))
208
- else
209
- element.attribute(attr,value)
210
- end
211
- end
212
-
213
- def boolean? attribute_value
214
- return true if attribute_value=="true" || attribute_value=="false"
215
- return false
216
- end
217
-
218
- #handles <include_scenario> elements, adding the steps to the current scenario
219
- def include_scenario step
220
- @logger.debug("Including file from #{step}")
221
- raise ParserError,"missing required attribute file in #{step}" unless step.has_file?
222
- raise ParserError,"Cannot find #{File.expand_path(step.file)}" unless File.exists?(File.expand_path(step.file))
223
- #Load the scenario
224
- step.file=File.expand_path(step.file)
225
- include_content=File.read(step.file)
226
- @logger.debug(include_content)
227
- return parse_scenario(include_content)
228
- end
229
- end
230
- #The ExtensibleXMLParser allows you to easily add methods to handle specification elements.
231
- #
232
- #A method element_foo(step) allows you to add behaviour for foo scenario elements.
233
- #
234
- #The method will receive a Rutema::TestStep instance.
235
- class ExtensibleXMLParser<BaseXMLParser
236
- def parse_specification param
237
- spec = super(param)
238
- #change into the directory the spec is in to handle relative paths correctly
239
- Dir.chdir(File.dirname(File.expand_path(spec.filename))) do |path|
240
- #iterate through the steps
241
- spec.scenario.steps.each do |step|
242
- #do we have a method to handle the element?
243
- if respond_to?(:"element_#{step.step_type}")
244
- begin
245
- self.send(:"element_#{step.step_type}",step)
246
- rescue
247
- raise ParserError, $!.message
248
- end
249
- end
250
- end
251
- end
252
- return spec
253
- end
254
- end
255
- #MinimalXMLParser offers three runnable steps in the scenarios as defined in Rutema::Elements::Minimal
256
- class MinimalXMLParser<ExtensibleXMLParser
257
- include Rutema::Elements::Minimal
258
- end
259
-
260
28
  #This class coordinates parsing, execution and reporting of test specifications
261
29
  class Coordinator
262
30
  attr_accessor :configuration,:parse_errors,:parsed_files
@@ -358,7 +126,7 @@ module Rutema
358
126
  def last_run_a_success?
359
127
  return @runner.success?
360
128
  end
361
- def to_s
129
+ def to_s#:nodoc:
362
130
  "Parsed #{@parsed_files.size} files\n#{TextReporter.new.report(@specifications,@runner.states.values,@parse_errors,@configuration)}"
363
131
  end
364
132
  private
@@ -457,178 +225,6 @@ module Rutema
457
225
  return status
458
226
  end
459
227
  end
460
-
461
- #Runner executes TestScenario instances and maintains the state of all scenarios run.
462
- class Runner
463
- attr_reader :states,:number_of_runs,:context
464
- attr_accessor :setup,:teardown
465
- attr_writer :attended
466
-
467
- #setup and teardown are TestScenario instances that will run before and after each call
468
- #to the scenario.
469
- def initialize context=nil,setup=nil, teardown=nil,logger=nil
470
- @setup=setup
471
- @teardown=teardown
472
- @attended=false
473
- @logger=logger
474
- @logger||=Patir.setup_logger
475
- @states=Hash.new
476
- @number_of_runs=0
477
- @context=context || Hash.new
478
- end
479
-
480
- #Tells you if the system runs in the mode that expects user input
481
- def attended?
482
- return @attended
483
- end
484
- #Runs a scenario and stores the result internally
485
- #
486
- #Returns the result of the run as a Patir::CommandSequenceStatus
487
- def run name,scenario, run_setup=true
488
- @logger.debug("Starting run for #{name} with #{scenario.inspect}")
489
- @context[:scenario_name]=name
490
- #if setup /teardown is defined we need to execute them before and after
491
- if @setup && run_setup
492
- @logger.info("Setup for #{name}")
493
- @states["#{name}_setup"]=run_scenario("#{name}_setup",@setup)
494
- @states["#{name}_setup"].sequence_id="s#{@number_of_runs}"
495
- if @states["#{name}_setup"].executed?
496
- #do not execute the scenario unless the setup was succesful
497
- if @states["#{name}_setup"].success?
498
- @logger.info("Scenario for #{name}")
499
- @states[name]=run_scenario(name,scenario)
500
- @states[name].sequence_id="#{@number_of_runs}"
501
- else
502
- @states[name]=initialize_state(name,scenario)
503
- @states[name].sequence_id="#{@number_of_runs}"
504
- end
505
- end
506
- else
507
- @logger.info("Scenario for #{name}")
508
- @states[name]=run_scenario(name,scenario)
509
- @states[name].sequence_id="#{@number_of_runs}"
510
- end
511
- #no setup means no teardown
512
- if @teardown && run_setup
513
- #always execute teardown
514
- @logger.warn("Teardown for #{name}")
515
- @states["#{name}_teardown"]=run_scenario("#{name}_teardown",@teardown)
516
- @states["#{name}_teardown"].sequence_id="#{@number_of_runs}t"
517
- end
518
- @number_of_runs+=1
519
- @context[:scenario_name]=nil
520
- return @states[name]
521
- end
522
-
523
- #Returns the state of the scenario with the given name.
524
- #
525
- #Will return nil if no scenario is found under that name.
526
- def [](name)
527
- return @states[name]
528
- end
529
-
530
- #Resets the Runner's internal state
531
- def reset
532
- @states.clear
533
- @number_of_runs=0
534
- end
535
-
536
- #returns true if all the scenarios in the last run were succesful or if nothing was run yet
537
- def success?
538
- @success=true
539
- @states.each do |k,v|
540
- @success&=(v.status!=:error)
541
- end
542
- return @success
543
- end
544
- private
545
- def run_scenario name,scenario
546
- state=initialize_state(name,scenario)
547
- begin
548
- if evaluate_attention(scenario,state)
549
- stps=scenario.steps
550
- if stps.empty?
551
- @logger.warn("Scenario #{name} contains no steps")
552
- state.status=:warning
553
- else
554
- stps.each do |s|
555
- state.step=run_step(s)
556
- break if :error==state.status
557
- end
558
- end
559
- end
560
- rescue
561
- @logger.error("Encountered error in #{name}: #{$!.message}")
562
- @logger.debug($!)
563
- state.status=:error
564
- end
565
- state.stop_time=Time.now
566
- state.sequence_id=@number_of_runs
567
- return state
568
- end
569
- def initialize_state name,scenario
570
- state=Patir::CommandSequenceStatus.new(name,scenario.steps)
571
- end
572
- def evaluate_attention scenario,state
573
- if scenario.attended?
574
- if !self.attended?
575
- @logger.warn("Attended scenario cannot be run in unattended mode")
576
- state.status=:warning
577
- return false
578
- end
579
- state.strategy=:attended
580
- else
581
- state.strategy=:unattended
582
- end
583
- return true
584
- end
585
- def run_step step
586
- @logger.info("Running step #{step.number} - #{step.name}")
587
- if step.has_cmd? && step.cmd.respond_to?(:run)
588
- step.cmd.run(@context)
589
- msg=step.to_s
590
- if !step.cmd.success?
591
- msg<<"\n#{step.cmd.output}" unless step.cmd.output.empty?
592
- msg<<"\n#{step.cmd.error}" unless step.cmd.error.empty?
593
- end
594
- else
595
- @logger.warn("No command associated with step '#{step.step_type}'. Step number is #{step.number}")
596
- end
597
- step.status=:success if step.status==:error && step.ignore?
598
- log_step_result(step,msg)
599
- return step
600
- end
601
- def log_step_result step,msg
602
- if step.status==:error
603
- if step.ignore?
604
- @logger.warn("Step failed but result is being ignored!\n#{msg}")
605
- else
606
- @logger.error(msg)
607
- end
608
- else
609
- @logger.info(msg) if msg && !msg.empty?
610
- end
611
- end
612
-
613
- end
614
-
615
- #StepRunner halts before every step and asks if it should be executed or not.
616
- class StepRunner<Runner
617
- def initialize context=nil,setup=nil, teardown=nil,logger=nil
618
- @questioner=HighLine.new
619
- super(context,setup,teardown,logger)
620
- end
621
- def run_step step
622
- if @questioner.agree("Execute #{step.to_s}?")
623
- return super(step)
624
- else
625
- msg="#{step.number} - #{step.step_type} - #{step.status}"
626
- @logger.info(msg)
627
- return step
628
- end
629
- end
630
- end
631
-
632
228
  #The "executioner" application class
633
229
  #
634
230
  #Parses the commandline, sets up the configuration and launches Cordinator
@@ -640,7 +236,7 @@ module Rutema
640
236
  @logger.info("rutemax v#{Version::STRING}")
641
237
  begin
642
238
  raise "No configuration file defined!" if !@config_file
643
- @configuration=RutemaXConfigurator.new(@config_file,@logger).configuration
239
+ @configuration=RutemaConfigurator.new(@config_file,@logger).configuration
644
240
  @configuration.context[:config_file]=File.basename(@config_file)
645
241
  @configuration.use_step_by_step=@step
646
242
  Dir.chdir(File.dirname(@config_file)) do
@@ -721,5 +317,4 @@ module Rutema
721
317
  end
722
318
  end
723
319
  end
724
-
725
320
  end