resat 0.7.4 → 0.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|