spectre-core 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ module Spectre::Http
2
+ class SpectreHttpRequest
3
+ def basic_auth username, password
4
+ @__req['basic_auth'] = {} if not @__req.has_key? 'basic_auth'
5
+
6
+ @__req['basic_auth']['username'] = username
7
+ @__req['basic_auth']['password'] = password
8
+
9
+ @__req['auth'] = 'basic_auth'
10
+ end
11
+ end
12
+
13
+ module BasicAuth
14
+ def self.on_req http, net_req, req
15
+ return unless req.has_key? 'basic_auth' and req['auth'] == 'basic_auth'
16
+ basic_auth_cfg = req['basic_auth']
17
+ net_req.basic_auth(basic_auth_cfg['username'], basic_auth_cfg['password'])
18
+ end
19
+
20
+ Spectre::Http.register(self)
21
+ end
22
+ end
@@ -0,0 +1,98 @@
1
+ class HttpRequest
2
+ def keystone url, username, password, project, domain, cert
3
+ @__req['keystone'] = {} if not @__req.has_key? 'keystone'
4
+
5
+ @__req['keystone']['url'] = url
6
+ @__req['keystone']['username'] = username
7
+ @__req['keystone']['password'] = password
8
+ @__req['keystone']['project'] = project
9
+ @__req['keystone']['domain'] = domain
10
+ @__req['keystone']['cert'] = cert
11
+
12
+ @__req.config['auth'] = 'keystone'
13
+ end
14
+ end
15
+
16
+
17
+ module Spectre::Http::Keystone
18
+ @@cache = {}
19
+
20
+ def self.on_req http, net_req, req
21
+ return unless req.has_key? 'keystone' and req['auth'] == 'keystone'
22
+
23
+ keystone_cfg = req['keystone']
24
+
25
+ if @@cache.has_key? keystone_cfg
26
+ token = @@cache[keystone_cfg]
27
+ else
28
+ token, _ = authenticate(
29
+ keystone_cfg['url'],
30
+ keystone_cfg['username'],
31
+ keystone_cfg['password'],
32
+ keystone_cfg['project'],
33
+ keystone_cfg['domain'],
34
+ keystone_cfg['cert'],
35
+ )
36
+
37
+ @@cache[keystone_cfg] = token
38
+ end
39
+
40
+ net_req['X-Auth-Token'] = token
41
+ end
42
+
43
+ private
44
+
45
+ def self.authenticate keystone_url, username, password, project, domain, cert
46
+ auth_data = {
47
+ auth: {
48
+ identity: {
49
+ methods: ['password'],
50
+ password: {
51
+ user: {
52
+ name: username,
53
+ password: password,
54
+ domain: {
55
+ name: domain,
56
+ },
57
+ },
58
+ },
59
+ },
60
+ scope: {
61
+ project: {
62
+ name: project,
63
+ domain: {
64
+ name: domain,
65
+ },
66
+ },
67
+ },
68
+ },
69
+ }
70
+
71
+ keystone_url = keystone_url + '/' if !keystone_url.end_with? '/'
72
+
73
+ base_uri = URI(keystone_url)
74
+ uri = URI.join(base_uri, 'auth/tokens?nocatalog=true')
75
+
76
+ http = Net::HTTP.new(base_uri.host, base_uri.port)
77
+
78
+ if cert
79
+ http.use_ssl = true
80
+ http.ca_file = cert
81
+ end
82
+
83
+ req = Net::HTTP::Post.new(uri)
84
+ req.body = JSON.pretty_generate(auth_data)
85
+ req.content_type = 'application/json'
86
+
87
+ res = http.request(req)
88
+
89
+ raise "error while authenticating: #{res.code} #{res.message}\n#{res.body}" if res.code != '201'
90
+
91
+ [
92
+ res['X-Subject-Token'],
93
+ JSON.parse(res.body),
94
+ ]
95
+ end
96
+
97
+ Spectre::Http.register(self)
98
+ end
@@ -0,0 +1,144 @@
1
+ require 'date'
2
+
3
+ module Spectre
4
+ module Logger
5
+ module Status
6
+ OK = '[ok]'
7
+ FAILED = '[failed]'
8
+ ERROR = '[error]'
9
+ INFO = '[info]'
10
+ SKIPPED = '[skipped]'
11
+ DEBUG = '[debug]'
12
+ end
13
+
14
+ class << self
15
+ @@debug = false
16
+ @@logger = []
17
+
18
+ def debug!
19
+ @@debug = true
20
+ end
21
+
22
+ def debug?
23
+ @@debug
24
+ end
25
+
26
+ def add logger
27
+ @@logger.append logger
28
+ end
29
+
30
+ def start_subject subject
31
+ delegate(:start_subject, subject)
32
+ end
33
+
34
+ def end_subject subject
35
+ delegate(:end_subject, subject)
36
+ end
37
+
38
+ def start_context context
39
+ delegate(:start_context, context)
40
+ end
41
+
42
+ def end_context context
43
+ delegate(:end_context, context)
44
+ end
45
+
46
+ def start_spec spec, data=nil
47
+ delegate(:start_spec, spec, data)
48
+ end
49
+
50
+ def end_spec spec, data=nil
51
+ delegate(:end_spec, spec, data)
52
+ end
53
+
54
+ def log_subject subject
55
+ begin
56
+ start_subject(subject)
57
+ yield
58
+ ensure
59
+ end_subject(subject)
60
+ end
61
+ end
62
+
63
+ def log_context context
64
+ begin
65
+ start_context(context)
66
+ yield
67
+ ensure
68
+ end_context(context)
69
+ end
70
+ end
71
+
72
+ def log_spec spec, data=nil
73
+ start_spec(spec, data)
74
+ yield
75
+ end_spec(spec, data)
76
+ end
77
+
78
+ def log_separator desc
79
+ delegate(:log_separator, desc)
80
+ end
81
+
82
+ def start_group desc
83
+ delegate(:start_group, desc)
84
+ end
85
+
86
+ def end_group desc
87
+ delegate(:end_group, desc)
88
+ end
89
+
90
+ def log_process desc
91
+ delegate(:log_process, desc)
92
+ end
93
+
94
+ def log_info message
95
+ add_log(message)
96
+ delegate(:log_info, message)
97
+ end
98
+
99
+ def log_debug message
100
+ return unless @@debug
101
+ add_log(message)
102
+ delegate(:log_debug, message)
103
+ end
104
+
105
+ def log_error spec, exception
106
+ add_log(exception)
107
+ delegate(:log_error, spec, exception)
108
+ end
109
+
110
+ def log_skipped spec
111
+ delegate(:log_skipped, spec)
112
+ end
113
+
114
+ def log_status desc, status, annotation=nil
115
+ delegate(:log_status, desc, status, annotation)
116
+ end
117
+
118
+ def group desc
119
+ Logger.start_group desc
120
+ yield
121
+ Logger.end_group desc
122
+ end
123
+
124
+ alias_method :info, :log_info
125
+ alias_method :log, :log_info
126
+ alias_method :debug, :log_debug
127
+ alias_method :separate, :log_separator
128
+
129
+ private
130
+
131
+ def delegate method, *args
132
+ @@logger.each do |logger|
133
+ logger.send(method, *args) if logger.respond_to? method
134
+ end
135
+ end
136
+
137
+ def add_log message
138
+ Spectre::Runner.current.log.append([DateTime.now, message])
139
+ end
140
+ end
141
+
142
+ Spectre.delegate :log, :info, :debug, :group, :separate, to: self
143
+ end
144
+ end
@@ -0,0 +1,142 @@
1
+ require 'ectoplasm'
2
+
3
+ module Spectre
4
+ module Logger
5
+ class Console
6
+ def initialize config
7
+ raise 'No log format section in config for console logger' unless config.has_key? 'log_format' and config['log_format'].has_key? 'console'
8
+
9
+ @config = config['log_format']['console']
10
+ @indent = @config['indent'] || 2
11
+ @width = @config['width'] || 80
12
+ @fmt_end_context = @config['end_context']
13
+ @fmt_sep = @config['separator']
14
+ @fmt_start_group = @config['start_group']
15
+ @fmt_end_group = @config['end_group']
16
+
17
+ @process = nil
18
+ @level = 0
19
+ end
20
+
21
+ def start_subject subject
22
+ puts subject.desc.blue
23
+ end
24
+
25
+ def start_context context
26
+ return unless context.__desc
27
+ puts (' ' * indent) + context.__desc.magenta
28
+ @level += 1
29
+ end
30
+
31
+ def end_context context
32
+ return unless context.__desc
33
+ @level -= 1
34
+ puts (' ' * indent) + @fmt_end_context.gsub('<desc>', context.__desc).magenta if @fmt_end_context
35
+ end
36
+
37
+ def start_spec spec, data=nil
38
+ text = spec.desc
39
+ text += " with #{data}" if data
40
+ puts (' ' * indent) + text.cyan
41
+
42
+ @level += 1
43
+ end
44
+
45
+ def end_spec spec, data
46
+ @level -= 1
47
+ end
48
+
49
+ def log_separator desc
50
+ if desc
51
+ desc = @fmt_sep.gsub('<indent>', ' ' * indent).gsub('<desc>', desc) if @fmt_sep
52
+ puts desc.blue
53
+ else
54
+ puts
55
+ end
56
+ end
57
+
58
+ def start_group desc
59
+ desc = @fmt_start_group.gsub('<desc>', desc) if @fmt_start_group
60
+ puts (' ' * indent) + desc.blue
61
+ @level += 1
62
+ end
63
+
64
+ def end_group desc
65
+ if desc and @fmt_start_group
66
+ desc = @fmt_start_group.gsub('<desc>', desc) if @fmt_start_group
67
+ puts (' ' * indent) + desc.blue
68
+ end
69
+
70
+ @level -= 1
71
+ end
72
+
73
+ def log_process desc
74
+ print_line(desc)
75
+ @process = desc
76
+ @level += 1
77
+ end
78
+
79
+ def log_status desc, status, annotation=nil
80
+ status = status.green if status == Status::OK
81
+ status = status.blue if status == Status::INFO
82
+ status = status.grey if status == Status::DEBUG
83
+ status = status.red if status == Status::FAILED
84
+ status = status.red if status == Status::ERROR
85
+ status = status.grey if status == Status::SKIPPED
86
+
87
+ txt = status
88
+ txt += ' ' + annotation if annotation
89
+
90
+ @level -= 1
91
+
92
+ if @process
93
+ puts txt
94
+ else
95
+ print_line('', status)
96
+ end
97
+
98
+ @process = nil
99
+ end
100
+
101
+ def log_info message
102
+ print_line(message, Status::INFO.blue)
103
+ end
104
+
105
+ def log_debug message
106
+ print_line(message, Status::DEBUG.grey)
107
+ end
108
+
109
+ def log_error spec, exception
110
+ txt = (Status::ERROR + ' - ' + exception.class.name).red
111
+ print_line('', txt)
112
+ end
113
+
114
+ def log_skipped spec
115
+ print_line('', Status::SKIPPED.grey)
116
+ end
117
+
118
+ private
119
+
120
+ def indent
121
+ (@level+1) * @indent
122
+ end
123
+
124
+ def print_line text='', status=nil
125
+ puts if @process
126
+
127
+ ind = indent
128
+ line = (' ' * indent) + text
129
+ remaining = @width - text.length - ind
130
+ line += '.' * (@width - text.length - ind) if remaining > 0
131
+
132
+ print line
133
+
134
+ if status
135
+ puts status
136
+ @process = nil
137
+ end
138
+ end
139
+
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,96 @@
1
+ module Spectre
2
+ module Logger
3
+ class File
4
+ def initialize config
5
+ raise 'No log format section in config for console logger' unless config.has_key? 'log_format' and config['log_format'].has_key? 'file'
6
+
7
+ @config = config['log_format']['file']
8
+ @fmt_start_group = @config['start_group']
9
+ @fmt_end_group = @config['end_group']
10
+ @fmt_sep = @config['separator']
11
+
12
+ @file_log = ::Logger.new config['log_file'], progname: 'spectre'
13
+ @file_log.level = config['debug'] ? 'DEBUG' : 'INFO'
14
+ end
15
+
16
+ def start_subject subject
17
+ @file_log.debug "start running subject '#{subject.desc}'"
18
+ end
19
+
20
+ def end_subject subject
21
+ @file_log.debug "subject '#{subject.desc}' finished"
22
+ end
23
+
24
+ def start_context context
25
+ if context and context.__desc
26
+ @file_log.debug "start running context '#{context.__desc}'"
27
+ else
28
+ @file_log.debug "start running main context of #{context.__subject.desc}"
29
+ end
30
+ end
31
+
32
+ def end_context context
33
+ if context and context.__desc
34
+ @file_log.debug "context '#{context.__desc}' finished"
35
+ else
36
+ @file_log.debug "main context finished of #{context.__subject.desc}"
37
+ end
38
+ end
39
+
40
+ def start_spec spec, data=nil
41
+ log_msg = "start running spec [#{spec.name}] '#{spec.desc}'"
42
+ log_msg += " with data #{data}" if data
43
+ @file_log.debug log_msg
44
+ end
45
+
46
+ def end_spec spec, data=nil
47
+ log_msg = "running spec [#{spec.name}] '#{spec.desc}'"
48
+ log_msg += " with data #{data}" if data
49
+ log_msg += " finished"
50
+ @file_log.debug log_msg
51
+ end
52
+
53
+ def log_separator desc
54
+ desc = @fmt_sep.gsub('<desc>', desc) if @fmt_sep
55
+ @file_log.info desc
56
+ end
57
+
58
+ def start_group desc
59
+ desc = @fmt_start_group.gsub('<desc>', desc) if @fmt_start_group
60
+ @file_log.info desc
61
+ end
62
+
63
+ def end_group desc
64
+ desc = @fmt_end_group.gsub('<desc>', desc) if @fmt_end_group
65
+ @file_log.info desc
66
+ end
67
+
68
+ def log_process desc
69
+ @file_log.debug desc
70
+ end
71
+
72
+ def log_info message
73
+ @file_log.info "#{Status::INFO} #{message}"
74
+ end
75
+
76
+ def log_debug message
77
+ @file_log.debug "#{Status::DEBUG} #{message}"
78
+ end
79
+
80
+ def log_error spec, exception
81
+ file, line = exception.backtrace[0].match(/(.*\.rb):(\d+)/).captures
82
+ @file_log.error "An unexpected error occured at '#{file}:#{line}' while running spec '#{spec.name}': [#{exception.class}] #{exception.message}\n#{exception.backtrace.join "\n"}"
83
+ end
84
+
85
+ def log_skipped spec
86
+ @file_log.warn "spec '#{spec.desc}' canceled by user"
87
+ end
88
+
89
+ def log_status desc, status, annotation=nil
90
+ msg = "expected #{desc}...#{status.upcase}"
91
+ msg += " - #{annotation}" if annotation
92
+ @file_log.debug msg
93
+ end
94
+ end
95
+ end
96
+ end