resat 0.7.4 → 0.7.5
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/api_request.rb +24 -22
- data/lib/config.rb +6 -8
- data/lib/engine.rb +8 -1
- data/lib/filter.rb +9 -8
- data/lib/guard.rb +3 -3
- data/lib/resat.rb +1 -1
- data/lib/scenario_runner.rb +13 -13
- data/lib/variables.rb +24 -44
- metadata +2 -2
data/lib/api_request.rb
CHANGED
@@ -13,34 +13,36 @@ module Resat
|
|
13
13
|
attr_reader :request, :response, :send_count, :failures
|
14
14
|
|
15
15
|
# Prepare request so 'send' can be called
|
16
|
-
def prepare
|
16
|
+
def prepare(variables, config)
|
17
17
|
@format ||= 'xml'
|
18
18
|
@failures = []
|
19
19
|
@send_count = 0
|
20
|
+
@config_delay = config.delay
|
21
|
+
@config_use_ssl = config.use_ssl
|
20
22
|
|
21
23
|
# 1. Normalize call fields
|
22
24
|
@headers ||= []
|
23
25
|
@params ||= []
|
24
26
|
# Clone config values so we don't mess with them when expanding variables
|
25
|
-
|
27
|
+
config.headers.each do |h|
|
26
28
|
@headers << { 'name' => h['name'].dup, 'value' => h['value'].dup }
|
27
|
-
end if
|
28
|
-
|
29
|
+
end if config.headers
|
30
|
+
config.params.each do |p|
|
29
31
|
@params << { 'name' => p['name'].dup, 'value' => p['value'].dup }
|
30
|
-
end if
|
31
|
-
|
32
|
-
|
32
|
+
end if config.params && request_class.REQUEST_HAS_BODY
|
33
|
+
variables.substitute!(@params)
|
34
|
+
variables.substitute!(@headers)
|
33
35
|
|
34
36
|
# 2. Build URI
|
35
|
-
|
36
|
-
uri_class = (@use_ssl || @use_ssl.nil? &&
|
37
|
-
port = @port ||
|
38
|
-
|
39
|
-
host = @host ||
|
40
|
-
|
37
|
+
variables.substitute!(@id) if @id
|
38
|
+
uri_class = (@use_ssl || @use_ssl.nil? && config.use_ssl) ? URI::HTTPS : URI::HTTP
|
39
|
+
port = @port || config.port || uri_class::DEFAULT_PORT
|
40
|
+
variables.substitute!(port)
|
41
|
+
host = @host || config.host
|
42
|
+
variables.substitute!(host)
|
41
43
|
@uri = uri_class.build( :host => host, :port => port )
|
42
|
-
base_url = "/#{@base_url ||
|
43
|
-
|
44
|
+
base_url = "/#{@base_url || config.base_url}/".squeeze('/')
|
45
|
+
variables.substitute!(base_url)
|
44
46
|
path = @path
|
45
47
|
unless path
|
46
48
|
path = "#{base_url}#{@resource}"
|
@@ -48,7 +50,7 @@ module Resat
|
|
48
50
|
path = "#{path}.#{@format}" if @format && !@format.empty? && !@custom
|
49
51
|
path = "#{path}#{@custom.separator}#{@custom.name}" if @custom
|
50
52
|
end
|
51
|
-
|
53
|
+
variables.substitute!(path)
|
52
54
|
@uri.merge!(path)
|
53
55
|
|
54
56
|
# 3. Build request
|
@@ -71,10 +73,10 @@ module Resat
|
|
71
73
|
end
|
72
74
|
end
|
73
75
|
@request = request_class.new(@uri.to_s)
|
74
|
-
username = @username ||
|
75
|
-
|
76
|
-
password = @password ||
|
77
|
-
|
76
|
+
username = @username || config.username
|
77
|
+
variables.substitute!(username) if username
|
78
|
+
password = @password || config.password
|
79
|
+
variables.substitute!(password) if password
|
78
80
|
if username && password
|
79
81
|
@request.basic_auth(username, password)
|
80
82
|
end
|
@@ -93,7 +95,7 @@ module Resat
|
|
93
95
|
def send
|
94
96
|
sleep(delay_seconds) # Delay request if needed
|
95
97
|
http = Net::HTTP.new(@uri.host, @uri.port)
|
96
|
-
http.use_ssl =
|
98
|
+
http.use_ssl = @config_use_ssl
|
97
99
|
begin
|
98
100
|
res = http.start { |http| @response = http.request(@request) }
|
99
101
|
rescue Exception => e
|
@@ -134,7 +136,7 @@ module Resat
|
|
134
136
|
# Calculate number of seconds to wait before sending request
|
135
137
|
def delay_seconds
|
136
138
|
seconds = nil
|
137
|
-
if delay = @delay ||
|
139
|
+
if delay = @delay || @config_delay
|
138
140
|
min_delay = max_delay = nil
|
139
141
|
if delay =~ /([\d]+)\.\.([\d]+)/
|
140
142
|
min_delay = Regexp.last_match[1].to_i
|
data/lib/config.rb
CHANGED
@@ -43,8 +43,8 @@ module Resat
|
|
43
43
|
'variables' => {}
|
44
44
|
}
|
45
45
|
|
46
|
-
def
|
47
|
-
(
|
46
|
+
def initialize(filename, schemasdir)
|
47
|
+
(self.methods - (Object.instance_methods + [ 'init', 'valid?', 'method_missing' ])).each { |m| self.class.send(:remove_method, m.to_sym) }
|
48
48
|
schemafile = File.join(schemasdir || DEFAULT_SCHEMA_DIR, 'config.yaml')
|
49
49
|
unless File.exists?(schemafile)
|
50
50
|
Log.error("Missing configuration file schema '#{schemafile}'")
|
@@ -66,10 +66,8 @@ module Resat
|
|
66
66
|
@config.merge!(config)
|
67
67
|
# Dynamically define the methods to forward to the config hash
|
68
68
|
@config.each_key do |meth|
|
69
|
-
(
|
70
|
-
|
71
|
-
@config[meth] || DEFAULTS[meth]
|
72
|
-
end
|
69
|
+
self.class.send(:define_method, meth) do |*args|
|
70
|
+
@config[meth] || DEFAULTS[meth]
|
73
71
|
end
|
74
72
|
end
|
75
73
|
end
|
@@ -82,11 +80,11 @@ module Resat
|
|
82
80
|
end
|
83
81
|
end
|
84
82
|
|
85
|
-
def
|
83
|
+
def valid?
|
86
84
|
@valid
|
87
85
|
end
|
88
86
|
|
89
|
-
def
|
87
|
+
def method_missing(*args)
|
90
88
|
nil
|
91
89
|
end
|
92
90
|
|
data/lib/engine.rb
CHANGED
@@ -17,6 +17,8 @@ module Resat
|
|
17
17
|
attr_accessor :skipped_count # Total number of skipped YAML files
|
18
18
|
attr_accessor :failures # Hash of error messages (string arrays)
|
19
19
|
# indexed by scenario filename
|
20
|
+
attr_accessor :variables # Hash of variables hashes indexed by
|
21
|
+
# scenario filename
|
20
22
|
|
21
23
|
def initialize(options)
|
22
24
|
@options = options
|
@@ -25,6 +27,7 @@ module Resat
|
|
25
27
|
@ignored_count = 0
|
26
28
|
@requests_count = 0
|
27
29
|
@skipped_count = 0
|
30
|
+
@variables = Hash.new
|
28
31
|
end
|
29
32
|
|
30
33
|
# Was test run successful?
|
@@ -55,7 +58,11 @@ module Resat
|
|
55
58
|
runner.run
|
56
59
|
@run_count += 1
|
57
60
|
@requests_count += runner.requests_count
|
58
|
-
|
61
|
+
if runner.succeeded?
|
62
|
+
@variables[file] = runner.variables
|
63
|
+
else
|
64
|
+
@failures[file] = runner.failures
|
65
|
+
end
|
59
66
|
else
|
60
67
|
unless runner.valid?
|
61
68
|
Log.info "Skipping '#{file}' (#{runner.parser_errors})"
|
data/lib/filter.rb
CHANGED
@@ -11,9 +11,10 @@ module Resat
|
|
11
11
|
include Kwalify::Util::HashLike
|
12
12
|
attr_accessor :failures
|
13
13
|
|
14
|
-
def prepare
|
14
|
+
def prepare(variables)
|
15
15
|
@is_empty ||= false
|
16
16
|
@failures = []
|
17
|
+
@variables = variables
|
17
18
|
Log.info("Running filter '#{@name}'")
|
18
19
|
end
|
19
20
|
|
@@ -55,7 +56,7 @@ module Resat
|
|
55
56
|
if @request.has_response_field?(v.field, @target)
|
56
57
|
field = @request.get_response_field(v.field, @target)
|
57
58
|
if v.pattern
|
58
|
-
|
59
|
+
@variables.substitute!(v.pattern)
|
59
60
|
unless Regexp.new(v.pattern).match(field)
|
60
61
|
@failures << "Validator /#{v.pattern} failed on '#{field}' from #{@target} field '#{v.field}'."
|
61
62
|
end
|
@@ -72,22 +73,22 @@ module Resat
|
|
72
73
|
# Extract elements from response
|
73
74
|
def extract
|
74
75
|
@extractors.each do |ex|
|
75
|
-
|
76
|
+
@variables.substitute!(ex.field)
|
76
77
|
if @request.has_response_field?(ex.field, @target)
|
77
78
|
field = @request.get_response_field(ex.field, @target)
|
78
79
|
if ex.pattern
|
79
|
-
|
80
|
+
@variables.substitute!(ex.pattern)
|
80
81
|
Regexp.new(ex.pattern).match(field)
|
81
82
|
if Regexp.last_match
|
82
|
-
|
83
|
+
@variables[ex.variable] = Regexp.last_match(1)
|
83
84
|
else
|
84
85
|
Log.warn("Extraction from response #{@target} field '#{ex.field}' ('#{field}') with pattern '#{ex.pattern}' failed.")
|
85
86
|
end
|
86
87
|
else
|
87
|
-
|
88
|
+
@variables[ex.variable] = field
|
88
89
|
end
|
89
|
-
|
90
|
-
|
90
|
+
@variables.mark_for_save(ex.variable) if ex.save
|
91
|
+
@variables.export(ex.variable) if ex.export
|
91
92
|
else
|
92
93
|
Log.warn("Extraction from response #{@target} field '#{ex.field}' failed: field not found.")
|
93
94
|
end
|
data/lib/guard.rb
CHANGED
@@ -11,11 +11,11 @@ module Resat
|
|
11
11
|
include Kwalify::Util::HashLike
|
12
12
|
attr_accessor :failures
|
13
13
|
|
14
|
-
def prepare
|
14
|
+
def prepare(variables)
|
15
15
|
@timeout ||= 120
|
16
16
|
@period ||= 5
|
17
17
|
@failures = []
|
18
|
-
|
18
|
+
variables.substitute!(@pattern)
|
19
19
|
Log.info("Waiting for guard #{@name} with pattern /#{@pattern.to_s}/")
|
20
20
|
end
|
21
21
|
|
@@ -33,4 +33,4 @@ module Resat
|
|
33
33
|
end
|
34
34
|
|
35
35
|
end
|
36
|
-
|
36
|
+
|
data/lib/resat.rb
CHANGED
data/lib/scenario_runner.rb
CHANGED
@@ -15,7 +15,7 @@ module Resat
|
|
15
15
|
|
16
16
|
class ScenarioRunner
|
17
17
|
|
18
|
-
attr_accessor :requests_count, :parser_errors, :failures
|
18
|
+
attr_accessor :requests_count, :parser_errors, :failures, :variables
|
19
19
|
|
20
20
|
# Instantiate new scenario runner with given YAML definition document and
|
21
21
|
# schemas directory.
|
@@ -32,13 +32,13 @@ module Resat
|
|
32
32
|
@dry_run = dry_run
|
33
33
|
parse(doc)
|
34
34
|
if @valid
|
35
|
-
Config.
|
36
|
-
@valid =
|
35
|
+
@config = Config.new(config || @cfg_file, schemasdir)
|
36
|
+
@valid = @config.valid?
|
37
37
|
if @valid
|
38
|
-
Variables.
|
39
|
-
|
40
|
-
|
41
|
-
variables.each { |k, v|
|
38
|
+
@variables = Variables.new
|
39
|
+
@variables.load(@config.input, schemasdir) if @config.input && File.readable?(@config.input)
|
40
|
+
@config.variables.each { |v| @variables[v['name']] = v['value'] } if @config.variables
|
41
|
+
variables.each { |k, v| @variables[k] = v } if variables
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -53,8 +53,8 @@ module Resat
|
|
53
53
|
def run
|
54
54
|
return if @ignored || !@valid
|
55
55
|
Log.info("-" * 80 + "\nRunning scenario #{@name}")
|
56
|
-
unless
|
57
|
-
info_msg =
|
56
|
+
unless @variables.empty?
|
57
|
+
info_msg = @variables.all.inject("Using variables:") do |msg, (k, v)|
|
58
58
|
msg << "\n - #{k}: #{v}"
|
59
59
|
end
|
60
60
|
Log.info(info_msg)
|
@@ -67,13 +67,13 @@ module Resat
|
|
67
67
|
when ApiRequest
|
68
68
|
@requests_count += @request.send_count if @request # Last request
|
69
69
|
@request = step
|
70
|
-
@request.prepare
|
70
|
+
@request.prepare(@variables, @config)
|
71
71
|
@request.send unless @dry_run
|
72
72
|
when Guard
|
73
|
-
step.prepare
|
73
|
+
step.prepare(@variables)
|
74
74
|
step.wait(@request) unless @dry_run
|
75
75
|
when Filter, Handler
|
76
|
-
step.prepare
|
76
|
+
step.prepare(@variables)
|
77
77
|
step.run(@request) unless @dry_run
|
78
78
|
end
|
79
79
|
puts step.inspect if step.failures.nil?
|
@@ -82,7 +82,7 @@ module Resat
|
|
82
82
|
end
|
83
83
|
|
84
84
|
@requests_count += @request.send_count
|
85
|
-
|
85
|
+
@variables.save(@config.output) if @config.output
|
86
86
|
end
|
87
87
|
|
88
88
|
protected
|
data/lib/variables.rb
CHANGED
@@ -8,14 +8,16 @@ require 'singleton'
|
|
8
8
|
module Resat
|
9
9
|
|
10
10
|
class Variables
|
11
|
-
include Singleton
|
12
11
|
|
13
12
|
attr_reader :vars, :marked_for_save, :exported
|
14
13
|
|
15
|
-
#
|
16
|
-
def
|
17
|
-
|
14
|
+
# Initialize instance
|
15
|
+
def initialize
|
16
|
+
@@exported = Hash.new unless defined? @@exported
|
17
|
+
@vars = @@exported.dup
|
18
18
|
end
|
19
|
+
|
20
|
+
# Replace occurrences of environment variables in +raw+ with their value
|
19
21
|
def substitute!(raw)
|
20
22
|
if raw.kind_of?(String)
|
21
23
|
scans = Array.new
|
@@ -32,27 +34,28 @@ module Resat
|
|
32
34
|
end
|
33
35
|
end
|
34
36
|
|
35
|
-
def
|
36
|
-
|
37
|
+
def [](key)
|
38
|
+
vars[key]
|
37
39
|
end
|
38
40
|
|
39
|
-
def
|
40
|
-
|
41
|
+
def []=(key, value)
|
42
|
+
vars[key] = value
|
41
43
|
end
|
42
44
|
|
43
|
-
def
|
44
|
-
|
45
|
+
def include?(key)
|
46
|
+
vars.include?(key)
|
45
47
|
end
|
46
48
|
|
47
|
-
def
|
48
|
-
|
49
|
+
def empty?
|
50
|
+
vars.empty?
|
49
51
|
end
|
50
52
|
|
51
|
-
def
|
52
|
-
|
53
|
+
def all
|
54
|
+
vars.sort
|
53
55
|
end
|
54
56
|
|
55
|
-
|
57
|
+
# Load variables from given file
|
58
|
+
def load(file, schemasdir)
|
56
59
|
schemafile = File.join(schemasdir, 'variables.yaml')
|
57
60
|
schema = Kwalify::Yaml.load_file(schemafile)
|
58
61
|
validator = Kwalify::Validator.new(schema)
|
@@ -60,18 +63,17 @@ module Resat
|
|
60
63
|
serialized_vars = parser.parse_file(file)
|
61
64
|
parser.errors.push(Kwalify::ValidationError.new("No variables defined")) unless serialized_vars
|
62
65
|
if parser.errors.empty?
|
63
|
-
vars = instance().vars
|
64
66
|
serialized_vars.each { |v| vars[v['name']] = v['value'] }
|
65
67
|
else
|
66
68
|
Log.warn("Error loading variables from '#{file}': #{KwalifyHelper.parser_error(parser)}")
|
67
69
|
end
|
68
70
|
end
|
69
71
|
|
70
|
-
|
72
|
+
# Save variables to given file
|
73
|
+
def save(file)
|
71
74
|
serialized_vars = []
|
72
|
-
|
73
|
-
|
74
|
-
if i.marked_for_save.include?(k)
|
75
|
+
vars.each do |k, v|
|
76
|
+
if marked_for_save.include?(k)
|
75
77
|
serialized_vars << { 'name' => k, 'value' => v }
|
76
78
|
end
|
77
79
|
end
|
@@ -80,37 +82,15 @@ module Resat
|
|
80
82
|
end
|
81
83
|
end
|
82
84
|
|
83
|
-
def Variables.mark_for_save(key)
|
84
|
-
instance().mark_for_save(key)
|
85
|
-
end
|
86
85
|
def mark_for_save(key)
|
87
86
|
@marked_for_save << key
|
88
87
|
end
|
89
88
|
|
90
|
-
# Exported values will be kept even after
|
91
|
-
def Variables.export(key)
|
92
|
-
instance().export(key)
|
93
|
-
end
|
89
|
+
# Exported values will be kept even after new instance is initialized
|
94
90
|
def export(key)
|
95
|
-
|
91
|
+
@@exported[key] = @vars[key]
|
96
92
|
end
|
97
93
|
|
98
|
-
def Variables.reset
|
99
|
-
instance().reset
|
100
|
-
end
|
101
|
-
def reset
|
102
|
-
@vars = @exported.clone
|
103
|
-
@marked_for_save = Array.new
|
104
|
-
end
|
105
|
-
|
106
|
-
protected
|
107
|
-
|
108
|
-
def initialize
|
109
|
-
@exported = Hash.new
|
110
|
-
reset
|
111
|
-
super
|
112
|
-
end
|
113
|
-
|
114
94
|
end
|
115
95
|
|
116
96
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: resat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Raphael Simon
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-05-19 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|