patir 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING.txt +340 -0
- data/History.txt +8 -0
- data/Manifest.txt +12 -0
- data/README.txt +88 -0
- data/Rakefile +18 -0
- data/lib/patir/base.rb +46 -0
- data/lib/patir/command.rb +486 -0
- data/lib/patir/configuration.rb +84 -0
- data/test/samples/empty.cfg +0 -0
- data/test/test_patir_base.rb +26 -0
- data/test/test_patir_command.rb +261 -0
- data/test/test_patir_configuration.rb +19 -0
- metadata +76 -0
@@ -0,0 +1,84 @@
|
|
1
|
+
# Copyright (c) 2007 Vassilis Rizopoulos. All rights reserved.
|
2
|
+
|
3
|
+
require 'patir/base'
|
4
|
+
module Patir
|
5
|
+
#This exception is thrown when encountering a configuration error
|
6
|
+
class ConfigurationException<RuntimeError
|
7
|
+
end
|
8
|
+
|
9
|
+
#Configurator is the base class for all the Patir configuration classes.
|
10
|
+
#
|
11
|
+
#The idea behind the configurator is that the developer creates a module that contains as methods
|
12
|
+
#all the configuration directives.
|
13
|
+
#He then derives a class from Configurator and includes the directives module.
|
14
|
+
#The Configurator loads the configuration file and evals it with itself as context (variable configuration), so the directives become methods in the configuration file:
|
15
|
+
# configuration.directive="some value"
|
16
|
+
# configuration.other_directive={:key=>"way to group values together",:other_key=>"omg"}
|
17
|
+
#
|
18
|
+
#The Configurator instance contains all the configuration data.
|
19
|
+
#Configurator#configuration method is provided as a post-processing step. It should be overriden to return the configuration data in the desired format and perform any overall validation steps (single element validation steps should be done in the directives module).
|
20
|
+
#==Example
|
21
|
+
# module SimpleConfiguration
|
22
|
+
# def name= tool_name
|
23
|
+
# raise Patir::ConfigurationException,"Inappropriate language not allowed" if tool_name=="@#!&@&$}"
|
24
|
+
# @name=tool_name
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# class SimpleConfigurator
|
29
|
+
# include SimpleConfiguration
|
30
|
+
#
|
31
|
+
# def configuration
|
32
|
+
# return @name
|
33
|
+
# end
|
34
|
+
# end
|
35
|
+
#The configuration file would then be
|
36
|
+
# configuration.name="really polite name"
|
37
|
+
#To use it you would do
|
38
|
+
# cfg=SimpleConfigurator.new("config.cfg").configuration
|
39
|
+
class Configurator
|
40
|
+
attr_reader :logger,:config_file
|
41
|
+
def initialize config_file,logger=nil
|
42
|
+
@logger=logger
|
43
|
+
@logger||=Patir.setup_logger
|
44
|
+
@config_file=config_file
|
45
|
+
load_configuration(@config_file)
|
46
|
+
end
|
47
|
+
|
48
|
+
#Returns self. This should be overriden in the actual implementations
|
49
|
+
def configuration
|
50
|
+
return self
|
51
|
+
end
|
52
|
+
private
|
53
|
+
#loads the configuration from a file
|
54
|
+
def load_configuration filename
|
55
|
+
begin
|
56
|
+
#change into the directory of the configuration file to make requiring easy
|
57
|
+
prev_dir=Dir.pwd
|
58
|
+
Dir.chdir(File.dirname(filename))
|
59
|
+
cfg_txt=File.readlines(File.basename(filename))
|
60
|
+
configuration=self
|
61
|
+
eval(cfg_txt.join(),binding())
|
62
|
+
#load File.basename(filename)
|
63
|
+
@logger.info("Configuration loaded from #{filename}") if @logger
|
64
|
+
rescue ConfigurationException
|
65
|
+
#pass it on, do not wrap again
|
66
|
+
raise
|
67
|
+
rescue SyntaxError
|
68
|
+
#Just wrap the exception so we can differentiate
|
69
|
+
@logger.debug($!)
|
70
|
+
raise ConfigurationException.new,"Syntax error in the configuration file '#{filename}':\n#{$!.message}"
|
71
|
+
rescue NoMethodError
|
72
|
+
@logger.debug($!)
|
73
|
+
raise ConfigurationException.new,"Encountered an unknown directive in configuration file '#{filename}':\n#{$!.message}"
|
74
|
+
rescue
|
75
|
+
@logger.debug($!)
|
76
|
+
#Just wrap the exception so we can differentiate
|
77
|
+
raise ConfigurationException.new,"#{$!.message}"
|
78
|
+
ensure
|
79
|
+
#ensure we go back to our previous dir
|
80
|
+
Dir.chdir(prev_dir)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
+
require 'test/unit'
|
3
|
+
require 'patir/base.rb'
|
4
|
+
|
5
|
+
class TestBase<Test::Unit::TestCase
|
6
|
+
def teardown
|
7
|
+
#clean up
|
8
|
+
File.delete("temp.log") if File.exists?("temp.log")
|
9
|
+
end
|
10
|
+
#simple match test
|
11
|
+
def test_drb_service
|
12
|
+
assert_equal("druby://service.host:7000",Patir.drb_service("service.host",7000))
|
13
|
+
end
|
14
|
+
#This is not actually testing anything meaningfull but can be expanded when we learn more about
|
15
|
+
#the logger
|
16
|
+
def test_setup_logger
|
17
|
+
logger=Patir.setup_logger
|
18
|
+
assert_not_nil(logger)
|
19
|
+
logger=Patir.setup_logger(nil,:silent)
|
20
|
+
assert_not_nil(logger)
|
21
|
+
logger=Patir.setup_logger("temp.log",:silent)
|
22
|
+
assert_not_nil(logger)
|
23
|
+
logger.close
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
+
require 'test/unit'
|
3
|
+
require 'patir/command.rb'
|
4
|
+
|
5
|
+
class MockCommandObject
|
6
|
+
include Patir::Command
|
7
|
+
end
|
8
|
+
|
9
|
+
class MockCommandWarning
|
10
|
+
include Patir::Command
|
11
|
+
def run
|
12
|
+
@status=:warning
|
13
|
+
return :warning
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class MockCommandError
|
18
|
+
include Patir::Command
|
19
|
+
def run
|
20
|
+
@status=:error
|
21
|
+
return :error
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class TestCommand<Test::Unit::TestCase
|
26
|
+
#tests the default values set by the module
|
27
|
+
def test_module
|
28
|
+
obj=MockCommandObject.new
|
29
|
+
assert_equal("",obj.name)
|
30
|
+
assert_equal(:not_executed,obj.status)
|
31
|
+
assert(!obj.run?)
|
32
|
+
assert_nothing_raised{obj.run}
|
33
|
+
assert(obj.run?)
|
34
|
+
assert_equal(:success,obj.status)
|
35
|
+
assert_equal("",obj.output)
|
36
|
+
assert_equal("",obj.error)
|
37
|
+
assert_equal(0,obj.exec_time)
|
38
|
+
assert_nothing_raised{obj.reset}
|
39
|
+
assert_equal(:not_executed,obj.status)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class TestShellCommand<Test::Unit::TestCase
|
44
|
+
include Patir
|
45
|
+
def teardown
|
46
|
+
Dir.delete("missing/") if File.exists?("missing/")
|
47
|
+
end
|
48
|
+
#test the expected behaviour of a succesfull command
|
49
|
+
def test_echo
|
50
|
+
cmd=nil
|
51
|
+
assert_nothing_raised(){cmd=ShellCommand.new(:cmd=>"echo hello")}
|
52
|
+
assert_not_nil(cmd)
|
53
|
+
assert(!cmd.run?)
|
54
|
+
assert(!cmd.success?)
|
55
|
+
assert_nothing_raised(){cmd.run}
|
56
|
+
assert(cmd.run?)
|
57
|
+
assert(cmd.success?)
|
58
|
+
assert_equal("hello\n",cmd.output)
|
59
|
+
assert_equal("",cmd.error)
|
60
|
+
assert_equal(:success,cmd.status)
|
61
|
+
end
|
62
|
+
#test that error status is reported correctly, by testing a command that fails.
|
63
|
+
def test_error
|
64
|
+
cmd=nil
|
65
|
+
assert_nothing_raised(){cmd=ShellCommand.new(:cmd=>"cd /missing")}
|
66
|
+
assert(!cmd.run?)
|
67
|
+
assert(!cmd.success?)
|
68
|
+
assert_nothing_raised(){cmd.run}
|
69
|
+
assert(cmd.run?)
|
70
|
+
assert(!cmd.success?)
|
71
|
+
assert_equal(:error,cmd.status)
|
72
|
+
end
|
73
|
+
#when passed a wroking directory, the command should change into that directory
|
74
|
+
def test_cwd
|
75
|
+
cmd=nil
|
76
|
+
assert_nothing_raised(){cmd=ShellCommand.new(:cmd=>"echo", :working_directory=>"samples/")}
|
77
|
+
assert_nothing_raised(){cmd.run}
|
78
|
+
assert(cmd.success?)
|
79
|
+
end
|
80
|
+
|
81
|
+
#when the working directory is missing, it should be created when the command is run
|
82
|
+
def test_missing_cwd
|
83
|
+
cmd=nil
|
84
|
+
assert_nothing_raised(){cmd=ShellCommand.new(:cmd=>"echo hello", :working_directory=>"missing/")}
|
85
|
+
assert_not_nil(cmd)
|
86
|
+
assert_equal(:success,cmd.run)
|
87
|
+
assert(cmd.success?)
|
88
|
+
assert(File.exists?("missing/"))
|
89
|
+
end
|
90
|
+
#an exception should be thrown when :cmd is nil
|
91
|
+
def test_missing_cmd
|
92
|
+
assert_raise(ParameterException){cmd=ShellCommand.new(:working_directory=>"missing/")}
|
93
|
+
end
|
94
|
+
#an exception should be thrown when no parameters are passed
|
95
|
+
def test_missing_params
|
96
|
+
assert_raise(ParameterException){cmd=ShellCommand.new()}
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
class TestCommandSequence<Test::Unit::TestCase
|
102
|
+
include Patir
|
103
|
+
def setup
|
104
|
+
@echo=ShellCommand.new(:cmd=>"echo hello")
|
105
|
+
@void=MockCommandObject.new
|
106
|
+
@error=MockCommandError.new
|
107
|
+
@warning=MockCommandWarning.new
|
108
|
+
end
|
109
|
+
def test_normal
|
110
|
+
seq=CommandSequence.new("test")
|
111
|
+
assert(seq.steps.empty?)
|
112
|
+
assert_nothing_raised{seq.run}
|
113
|
+
assert(!seq.state.success?)
|
114
|
+
assert_equal(:warning,seq.state.status)
|
115
|
+
assert_nothing_raised{seq.add_step(@echo)}
|
116
|
+
assert_nothing_raised{seq.add_step(@void)}
|
117
|
+
assert_nothing_raised{seq.run}
|
118
|
+
assert(seq.state.success?)
|
119
|
+
end
|
120
|
+
def test_flunk_on_error
|
121
|
+
seq=CommandSequence.new("test")
|
122
|
+
assert(seq.steps.empty?)
|
123
|
+
assert_nothing_raised{seq.add_step(@echo,:flunk_on_error)}
|
124
|
+
assert_nothing_raised{seq.add_step(@error,:flunk_on_error)}
|
125
|
+
assert_nothing_raised{seq.add_step(@void,:flunk_on_error)}
|
126
|
+
assert(:not_executed==seq.state.step_state(0)[:status])
|
127
|
+
assert(:not_executed==seq.state.step_state(1)[:status])
|
128
|
+
assert(:not_executed==seq.state.step_state(2)[:status])
|
129
|
+
assert_nothing_raised{seq.run}
|
130
|
+
assert(!seq.state.success?)
|
131
|
+
#all three steps should have been run
|
132
|
+
assert(:not_executed!=seq.state.step_state(0)[:status])
|
133
|
+
assert(:not_executed!=seq.state.step_state(1)[:status])
|
134
|
+
assert(:not_executed!=seq.state.step_state(2)[:status])
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_fail_on_error
|
138
|
+
seq=CommandSequence.new("test")
|
139
|
+
assert(seq.steps.empty?)
|
140
|
+
assert_nothing_raised{seq.add_step(@echo)}
|
141
|
+
assert_nothing_raised{seq.add_step(@error,:fail_on_error)}
|
142
|
+
assert_nothing_raised{seq.add_step(@void)}
|
143
|
+
assert(:not_executed==seq.state.step_state(0)[:status])
|
144
|
+
assert(:not_executed==seq.state.step_state(1)[:status])
|
145
|
+
assert(:not_executed==seq.state.step_state(2)[:status])
|
146
|
+
assert_nothing_raised{seq.run}
|
147
|
+
assert(!seq.state.success?)
|
148
|
+
#only two steps should have been run
|
149
|
+
assert(:not_executed!=seq.state.step_state(0)[:status])
|
150
|
+
assert(:not_executed!=seq.state.step_state(1)[:status])
|
151
|
+
assert(:not_executed==seq.state.step_state(2)[:status])
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_flunk_on_warning
|
155
|
+
seq=CommandSequence.new("test")
|
156
|
+
assert(seq.steps.empty?)
|
157
|
+
assert_nothing_raised{seq.add_step(@echo)}
|
158
|
+
assert_nothing_raised{seq.add_step(@warning,:flunk_on_warning)}
|
159
|
+
assert_nothing_raised{seq.add_step(@void)}
|
160
|
+
assert(:not_executed==seq.state.step_state(0)[:status])
|
161
|
+
assert(:not_executed==seq.state.step_state(1)[:status])
|
162
|
+
assert(:not_executed==seq.state.step_state(2)[:status])
|
163
|
+
assert_nothing_raised{seq.run}
|
164
|
+
assert(!seq.state.success?)
|
165
|
+
#all three steps should have been run
|
166
|
+
assert(:not_executed!=seq.state.step_state(0)[:status])
|
167
|
+
assert(:not_executed!=seq.state.step_state(1)[:status])
|
168
|
+
assert(:not_executed!=seq.state.step_state(2)[:status])
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_fail_on_warning
|
172
|
+
seq=CommandSequence.new("test")
|
173
|
+
assert(seq.steps.empty?)
|
174
|
+
assert_nothing_raised{seq.add_step(@echo)}
|
175
|
+
assert_nothing_raised{seq.add_step(@warning,:fail_on_warning)}
|
176
|
+
assert_nothing_raised{seq.add_step(@void)}
|
177
|
+
assert(:not_executed==seq.state.step_state(0)[:status])
|
178
|
+
assert(:not_executed==seq.state.step_state(1)[:status])
|
179
|
+
assert(:not_executed==seq.state.step_state(2)[:status])
|
180
|
+
assert_nothing_raised{seq.run}
|
181
|
+
assert(!seq.state.success?)
|
182
|
+
#only two steps should have been run
|
183
|
+
assert(:not_executed!=seq.state.step_state(0)[:status])
|
184
|
+
assert(:not_executed!=seq.state.step_state(1)[:status])
|
185
|
+
assert(:not_executed==seq.state.step_state(2)[:status])
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
class TestCommandSequenceStatus<Test::Unit::TestCase
|
190
|
+
def test_new
|
191
|
+
st=Patir::CommandSequenceStatus.new("sequence")
|
192
|
+
assert(!st.running?)
|
193
|
+
assert(!st.success?)
|
194
|
+
assert_equal(:not_executed, st.status)
|
195
|
+
assert_nil(st.step_state(3))
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_step=
|
199
|
+
st=Patir::CommandSequenceStatus.new("sequence")
|
200
|
+
step1=MockCommandObject.new
|
201
|
+
step2=MockCommandWarning.new
|
202
|
+
step3=MockCommandError.new
|
203
|
+
step1.run
|
204
|
+
step1.number=1
|
205
|
+
step2.run
|
206
|
+
step2.number=2
|
207
|
+
step3.run
|
208
|
+
step3.number=3
|
209
|
+
st.step=step1
|
210
|
+
assert_equal(:success, st.status)
|
211
|
+
assert_equal(step1.status, st.step_state(1)[:status])
|
212
|
+
st.step=step2
|
213
|
+
assert_equal(:warning, st.status)
|
214
|
+
st.step=step3
|
215
|
+
assert_equal(:error, st.status)
|
216
|
+
step2.number=1
|
217
|
+
st.step=step2
|
218
|
+
assert_equal(step2.status, st.step_state(1)[:status])
|
219
|
+
assert_equal(:error, st.status)
|
220
|
+
st.step=step1
|
221
|
+
assert_equal(:error, st.status)
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_completed?
|
225
|
+
st=Patir::CommandSequenceStatus.new("sequence")
|
226
|
+
step1=MockCommandObject.new
|
227
|
+
step1.number=1
|
228
|
+
step2=MockCommandWarning.new
|
229
|
+
step2.number=2
|
230
|
+
step3=MockCommandError.new
|
231
|
+
step3.number=3
|
232
|
+
step4=MockCommandObject.new
|
233
|
+
st.step=step1
|
234
|
+
st.step=step2
|
235
|
+
st.step=step3
|
236
|
+
st.step=step4
|
237
|
+
assert(!st.completed?, "should not be complete.")
|
238
|
+
step1.run
|
239
|
+
st.step=step1
|
240
|
+
assert(!st.completed?, "should not be complete.")
|
241
|
+
step2.run
|
242
|
+
st.step=step2
|
243
|
+
assert(!st.completed?, "should not be complete.")
|
244
|
+
step2.strategy=:fail_on_warning
|
245
|
+
st.step=step2
|
246
|
+
assert(st.completed?, "should be complete.")
|
247
|
+
step2.strategy=nil
|
248
|
+
st.step=step2
|
249
|
+
assert(!st.completed?, "should not be complete.")
|
250
|
+
step3.run
|
251
|
+
step3.strategy=:fail_on_error
|
252
|
+
st.step=step3
|
253
|
+
assert(st.completed?, "should be complete.")
|
254
|
+
step3.strategy=nil
|
255
|
+
st.step=step3
|
256
|
+
assert(!st.completed?, "should not be complete.")
|
257
|
+
step4.run
|
258
|
+
st.step=step4
|
259
|
+
assert(st.completed?, "should be complete.")
|
260
|
+
end
|
261
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__),"..","lib")
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
require 'patir/configuration'
|
5
|
+
module Patir
|
6
|
+
class TestConfigurator<Test::Unit::TestCase
|
7
|
+
def setup
|
8
|
+
@prev_dir=Dir.pwd
|
9
|
+
Dir.chdir(File.dirname(__FILE__))
|
10
|
+
end
|
11
|
+
def teardown
|
12
|
+
Dir.chdir(@prev_dir)
|
13
|
+
end
|
14
|
+
def test_configuration
|
15
|
+
c=Patir::Configurator.new("samples/empty.cfg")
|
16
|
+
assert_equal(c.configuration,c)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.1
|
3
|
+
specification_version: 1
|
4
|
+
name: patir
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: "0.2"
|
7
|
+
date: 2007-05-17 00:00:00 +02:00
|
8
|
+
summary: patir (Project Automation Tools in Ruby) provides libraries for use in automation tools
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: riva@braveworld.net
|
12
|
+
homepage: http://patir.rubyforge.org
|
13
|
+
rubyforge_project: patir
|
14
|
+
description: "== SYNOPSIS: patir is the library of common functionality used in the patir projects. This includes a class that allows you to build configuration files in Ruby and a library for command abstraction. == REQUIREMENTS: * systemu"
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Vassilis Rizopoulos
|
31
|
+
files:
|
32
|
+
- History.txt
|
33
|
+
- Manifest.txt
|
34
|
+
- README.txt
|
35
|
+
- COPYING.txt
|
36
|
+
- Rakefile
|
37
|
+
- lib/patir/base.rb
|
38
|
+
- lib/patir/command.rb
|
39
|
+
- lib/patir/configuration.rb
|
40
|
+
- test/test_patir_base.rb
|
41
|
+
- test/test_patir_command.rb
|
42
|
+
- test/test_patir_configuration.rb
|
43
|
+
- test/samples/empty.cfg
|
44
|
+
test_files:
|
45
|
+
- test/test_patir_base.rb
|
46
|
+
- test/test_patir_command.rb
|
47
|
+
- test/test_patir_configuration.rb
|
48
|
+
rdoc_options: []
|
49
|
+
|
50
|
+
extra_rdoc_files: []
|
51
|
+
|
52
|
+
executables: []
|
53
|
+
|
54
|
+
extensions: []
|
55
|
+
|
56
|
+
requirements: []
|
57
|
+
|
58
|
+
dependencies:
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: systemu
|
61
|
+
version_requirement:
|
62
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 0.0.0
|
67
|
+
version:
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: hoe
|
70
|
+
version_requirement:
|
71
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.2.0
|
76
|
+
version:
|