spectre-core 1.10.0 → 1.12.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/exe/spectre +51 -46
- data/lib/spectre/assertion.rb +39 -20
- data/lib/spectre/bag.rb +4 -2
- data/lib/spectre/curl.rb +62 -33
- data/lib/spectre/diagnostic.rb +12 -2
- data/lib/spectre/environment.rb +9 -5
- data/lib/spectre/helpers.rb +68 -27
- data/lib/spectre/http/basic_auth.rb +5 -2
- data/lib/spectre/http/keystone.rb +76 -73
- data/lib/spectre/http.rb +379 -358
- data/lib/spectre/logger/console.rb +7 -6
- data/lib/spectre/logger/file.rb +96 -96
- data/lib/spectre/logger.rb +146 -144
- data/lib/spectre/mixin.rb +35 -18
- data/lib/spectre/reporter/console.rb +2 -5
- data/lib/spectre/reporter/junit.rb +5 -3
- data/lib/spectre/resources.rb +7 -4
- data/lib/spectre.rb +58 -45
- metadata +12 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b85338c15a8c29d520ed02d2e6816a64c579b6edd654f3d047fbeddb4a5c0ea3
|
4
|
+
data.tar.gz: 7be4646412f7dd3a971b21269215cddff5398cc12a50cd42dcd78a6bb70bf012
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 043d7b2bda42acf5687f09ce9468c8b3ce01566c5a61d3d1c753b9d61a126898b883f00b67be67d6d61600a85143475e8b041b31fdf42f02dee5aca48260037c
|
7
|
+
data.tar.gz: 890154e9fabf2664d50289f5eeb212cd9ea508a967341d9b27a2ad5dd329600542a168352274d4a0ca09dbe9aa91f3bc22e6c855d36a80e1219ccac9132dd047
|
data/exe/spectre
CHANGED
@@ -10,14 +10,6 @@ require 'ectoplasm'
|
|
10
10
|
require_relative '../lib/spectre'
|
11
11
|
|
12
12
|
|
13
|
-
class ::Hash
|
14
|
-
def deep_merge!(second)
|
15
|
-
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge!(v2, &merger) : v2 }
|
16
|
-
self.merge!(second, &merger)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
13
|
DEFAULT_CONFIG = {
|
22
14
|
'config_file' => './spectre.yml',
|
23
15
|
'environment' => 'default',
|
@@ -44,7 +36,7 @@ DEFAULT_CONFIG = {
|
|
44
36
|
'separator' => '-- <desc>',
|
45
37
|
'start_group' => "-- Start '<desc>'",
|
46
38
|
'end_group' => "-- End '<desc>'",
|
47
|
-
}
|
39
|
+
},
|
48
40
|
},
|
49
41
|
'debug' => false,
|
50
42
|
'out_path' => './reports',
|
@@ -75,7 +67,7 @@ DEFAULT_CONFIG = {
|
|
75
67
|
],
|
76
68
|
'exclude' => [
|
77
69
|
|
78
|
-
]
|
70
|
+
],
|
79
71
|
}
|
80
72
|
|
81
73
|
|
@@ -148,10 +140,9 @@ Specific options:}
|
|
148
140
|
|
149
141
|
curr_opt = cmd_options
|
150
142
|
(key.split '.').each do |k|
|
151
|
-
curr_opt[k] = {}
|
143
|
+
curr_opt[k] = {} unless curr_opt.key? k
|
152
144
|
end
|
153
145
|
curr_opt = val
|
154
|
-
|
155
146
|
end
|
156
147
|
|
157
148
|
opts.separator "\nCommon options:"
|
@@ -226,7 +217,7 @@ cfg['env_partial_patterns'].each do |pattern|
|
|
226
217
|
Dir.glob(pattern).each do|f|
|
227
218
|
partial_env = YAML.load_file(f)
|
228
219
|
name = partial_env.delete('name') || 'default'
|
229
|
-
next
|
220
|
+
next unless envs.key? name
|
230
221
|
|
231
222
|
envs[name].deep_merge! partial_env
|
232
223
|
end
|
@@ -238,6 +229,10 @@ cfg.merge! env if env
|
|
238
229
|
|
239
230
|
String.colored! if cfg['colored']
|
240
231
|
|
232
|
+
# Load environment exlicitly before loading specs to make it available in spec definition
|
233
|
+
require_relative '../lib/spectre/environment' unless cfg['exclude'].include? 'spectre/environment'
|
234
|
+
Spectre.configure(cfg)
|
235
|
+
|
241
236
|
|
242
237
|
###########################################
|
243
238
|
# Load Specs
|
@@ -256,11 +251,11 @@ end
|
|
256
251
|
###########################################
|
257
252
|
|
258
253
|
|
259
|
-
if
|
254
|
+
if 'list' == action
|
260
255
|
colors = [:blue, :magenta, :yellow, :green]
|
261
256
|
specs = Spectre.specs(cfg['specs'], cfg['tags'])
|
262
257
|
|
263
|
-
exit 1
|
258
|
+
exit 1 unless specs.any?
|
264
259
|
|
265
260
|
counter = 0
|
266
261
|
|
@@ -285,42 +280,52 @@ end
|
|
285
280
|
###########################################
|
286
281
|
|
287
282
|
|
288
|
-
if
|
283
|
+
if 'run' == action
|
289
284
|
# Initialize logger
|
290
285
|
now = Time.now
|
291
286
|
|
292
|
-
cfg['log_file'] = cfg['log_file'].frmt(
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
287
|
+
cfg['log_file'] = cfg['log_file'].frmt(
|
288
|
+
{
|
289
|
+
shortdate: now.strftime('%Y-%m-%d'),
|
290
|
+
date: now.strftime('%Y-%m-%d_%H%M%S'),
|
291
|
+
timestamp: now.strftime('%s'),
|
292
|
+
subject: 'spectre',
|
293
|
+
})
|
298
294
|
|
299
295
|
log_dir = File.dirname cfg['log_file']
|
300
|
-
FileUtils.makedirs log_dir
|
296
|
+
FileUtils.makedirs log_dir unless Dir.exists? log_dir
|
301
297
|
|
302
298
|
# Load Modules
|
299
|
+
|
303
300
|
cfg['modules']
|
304
301
|
.concat(cfg['include'])
|
305
302
|
.select { |mod| !cfg['exclude'].include? mod }
|
306
303
|
.each do |mod|
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
if File.exists? mod
|
311
|
-
require_relative mod
|
304
|
+
begin
|
305
|
+
mod_file = mod + '.rb'
|
306
|
+
spectre_lib_mod = File.join(File.dirname(__dir__), 'lib', mod_file)
|
312
307
|
|
313
|
-
|
314
|
-
|
308
|
+
if File.exists? mod_file
|
309
|
+
require_relative mod_file
|
315
310
|
|
316
|
-
|
317
|
-
|
318
|
-
end
|
311
|
+
elsif File.exists? spectre_lib_mod
|
312
|
+
require_relative spectre_lib_mod
|
319
313
|
|
320
|
-
|
321
|
-
|
322
|
-
exit 1
|
314
|
+
else
|
315
|
+
require mod
|
323
316
|
end
|
317
|
+
rescue LoadError => e
|
318
|
+
puts "Unable to load module #{mod}. Check if the module exists or remove it from your spectre config:\n#{e.message}"
|
319
|
+
exit 1
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
# Load mixins
|
324
|
+
|
325
|
+
cfg['mixin_patterns'].each do |pattern|
|
326
|
+
Dir.glob(pattern).each do|f|
|
327
|
+
require_relative File.join(Dir.pwd, f)
|
328
|
+
end
|
324
329
|
end
|
325
330
|
|
326
331
|
Spectre.configure(cfg)
|
@@ -334,7 +339,7 @@ if action == 'run'
|
|
334
339
|
|
335
340
|
specs = Spectre.specs(cfg['specs'], cfg['tags'])
|
336
341
|
|
337
|
-
|
342
|
+
unless specs.any?
|
338
343
|
puts "No specs found in #{Dir.pwd}"
|
339
344
|
exit 1
|
340
345
|
end
|
@@ -346,9 +351,9 @@ if action == 'run'
|
|
346
351
|
reporter.report(run_infos)
|
347
352
|
end
|
348
353
|
|
349
|
-
errors = run_infos.select { |x| x.error
|
354
|
+
errors = run_infos.select { |x| nil != x.error or nil != x.failure }
|
350
355
|
|
351
|
-
exit 0 if cfg['ignore_failure'] or errors.
|
356
|
+
exit 0 if cfg['ignore_failure'] or not errors.any?
|
352
357
|
|
353
358
|
exit 1
|
354
359
|
end
|
@@ -359,8 +364,8 @@ end
|
|
359
364
|
###########################################
|
360
365
|
|
361
366
|
|
362
|
-
if
|
363
|
-
exit 1
|
367
|
+
if 'envs' == action
|
368
|
+
exit 1 unless envs.any?
|
364
369
|
puts envs.pretty
|
365
370
|
exit 0
|
366
371
|
end
|
@@ -371,7 +376,7 @@ end
|
|
371
376
|
###########################################
|
372
377
|
|
373
378
|
|
374
|
-
if
|
379
|
+
if 'show' == action
|
375
380
|
puts cfg.pretty
|
376
381
|
exit 0
|
377
382
|
end
|
@@ -382,7 +387,7 @@ end
|
|
382
387
|
###########################################
|
383
388
|
|
384
389
|
|
385
|
-
if
|
390
|
+
if 'dump' == action
|
386
391
|
puts YAML.dump(cfg)
|
387
392
|
end
|
388
393
|
|
@@ -487,7 +492,7 @@ gem 'spectre-core', '>= #{Spectre::VERSION}'
|
|
487
492
|
# gem 'spectre-git', '>= 0.1.0'
|
488
493
|
]
|
489
494
|
|
490
|
-
if
|
495
|
+
if 'init' == action
|
491
496
|
DEFAULT_FILES = [
|
492
497
|
['./environments/default.env.yml', DEFAULT_ENV_CFG],
|
493
498
|
['./environments/default.env.secret.yml', DEFAULT_ENV_SECRET_CFG],
|
@@ -502,10 +507,10 @@ if action == 'init'
|
|
502
507
|
end
|
503
508
|
|
504
509
|
DEFAULT_FILES.each do |file, content|
|
505
|
-
|
510
|
+
unless File.exists? file
|
506
511
|
File.write(file, content)
|
507
512
|
end
|
508
513
|
end
|
509
514
|
|
510
515
|
exit 0
|
511
|
-
end
|
516
|
+
end
|
data/lib/spectre/assertion.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative '../spectre'
|
2
|
+
|
1
3
|
require 'ostruct'
|
2
4
|
require_relative 'logger'
|
3
5
|
|
@@ -10,7 +12,7 @@ module Spectre
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def should_be_empty
|
13
|
-
raise AssertionFailure.new("The value '#{self.to_s.trim}' should be empty", nil, self) unless self
|
15
|
+
raise AssertionFailure.new("The value '#{self.to_s.trim}' should be empty", nil, self) unless self.nil?
|
14
16
|
end
|
15
17
|
|
16
18
|
def should_not_be(val)
|
@@ -22,7 +24,7 @@ module Spectre
|
|
22
24
|
end
|
23
25
|
|
24
26
|
def should_not_be_empty
|
25
|
-
raise AssertionFailure.new('The value
|
27
|
+
raise AssertionFailure.new('The value is empty', 'nothing', self) unless self != nil
|
26
28
|
end
|
27
29
|
|
28
30
|
def or other
|
@@ -34,7 +36,6 @@ module Spectre
|
|
34
36
|
end
|
35
37
|
end
|
36
38
|
|
37
|
-
|
38
39
|
class ::NilClass
|
39
40
|
def should_be(val)
|
40
41
|
raise AssertionFailure.new("There is nothing, but the value should be '#{val.to_s.trim}'", val, nil) unless val == nil
|
@@ -51,11 +52,10 @@ module Spectre
|
|
51
52
|
end
|
52
53
|
|
53
54
|
def should_not_be_empty
|
54
|
-
raise AssertionFailure.new('
|
55
|
+
raise AssertionFailure.new('The list is empty', 'nil')
|
55
56
|
end
|
56
57
|
end
|
57
58
|
|
58
|
-
|
59
59
|
class ::Hash
|
60
60
|
def should_contain(other)
|
61
61
|
raise AssertionFailure.new(other, self) unless self.merge(other) == self
|
@@ -64,8 +64,25 @@ module Spectre
|
|
64
64
|
def should_not_contain(other)
|
65
65
|
raise AssertionFailure.new(other, self) unless self.merge(other) != self
|
66
66
|
end
|
67
|
+
|
68
|
+
def should_be_empty
|
69
|
+
raise AssertionFailure.new('The object should be empty', nil, self) unless self.empty?
|
70
|
+
end
|
71
|
+
|
72
|
+
def should_not_be_empty
|
73
|
+
raise AssertionFailure.new('The object should not be empty', nil, self) if self.empty?
|
74
|
+
end
|
67
75
|
end
|
68
76
|
|
77
|
+
class ::OpenStruct
|
78
|
+
def should_be_empty
|
79
|
+
raise AssertionFailure.new('The object should be empty', nil, self) unless self.to_h.empty?
|
80
|
+
end
|
81
|
+
|
82
|
+
def should_not_be_empty
|
83
|
+
raise AssertionFailure.new('The object should not be empty', nil, self) if self.to_h.empty?
|
84
|
+
end
|
85
|
+
end
|
69
86
|
|
70
87
|
class ::Array
|
71
88
|
def should_contain(val)
|
@@ -91,15 +108,14 @@ module Spectre
|
|
91
108
|
end
|
92
109
|
|
93
110
|
def should_be_empty
|
94
|
-
raise AssertionFailure.new('
|
111
|
+
raise AssertionFailure.new('The list is not empty', self) unless self.empty?
|
95
112
|
end
|
96
113
|
|
97
114
|
def should_not_be_empty
|
98
|
-
raise AssertionFailure.new('
|
115
|
+
raise AssertionFailure.new('The list is empty', self) if self.empty?
|
99
116
|
end
|
100
117
|
end
|
101
118
|
|
102
|
-
|
103
119
|
class ::String
|
104
120
|
def should_be(val)
|
105
121
|
raise AssertionFailure.new("The text '#{self.trim}' should be '#{val.to_s.trim}'", val, self) unless self == val
|
@@ -118,7 +134,7 @@ module Spectre
|
|
118
134
|
end
|
119
135
|
|
120
136
|
def should_contain(value)
|
121
|
-
raise AssertionFailure.new("
|
137
|
+
raise AssertionFailure.new("The value is nil") if value.nil?
|
122
138
|
|
123
139
|
predicate = proc { |x| self.include? x.to_s }
|
124
140
|
evaluation = SingleEvaluation.new(value)
|
@@ -145,7 +161,6 @@ module Spectre
|
|
145
161
|
alias :& :and
|
146
162
|
end
|
147
163
|
|
148
|
-
|
149
164
|
class Evaluation
|
150
165
|
def initialize value, other
|
151
166
|
@value = value
|
@@ -164,7 +179,6 @@ module Spectre
|
|
164
179
|
alias :& :and
|
165
180
|
end
|
166
181
|
|
167
|
-
|
168
182
|
class SingleEvaluation < Evaluation
|
169
183
|
def initialize value
|
170
184
|
super(value, nil)
|
@@ -179,7 +193,6 @@ module Spectre
|
|
179
193
|
end
|
180
194
|
end
|
181
195
|
|
182
|
-
|
183
196
|
class OrEvaluation < Evaluation
|
184
197
|
def initialize value, other
|
185
198
|
super(value, other)
|
@@ -194,7 +207,6 @@ module Spectre
|
|
194
207
|
end
|
195
208
|
end
|
196
209
|
|
197
|
-
|
198
210
|
class AndEvaluation < Evaluation
|
199
211
|
def initialize value, other
|
200
212
|
super(value, other)
|
@@ -209,7 +221,6 @@ module Spectre
|
|
209
221
|
end
|
210
222
|
end
|
211
223
|
|
212
|
-
|
213
224
|
class AssertionFailure < ExpectationFailure
|
214
225
|
attr_reader :expected, :actual
|
215
226
|
|
@@ -229,14 +240,11 @@ module Spectre
|
|
229
240
|
Logger.log_process("expect #{desc}")
|
230
241
|
yield
|
231
242
|
Logger.log_status(desc, Logger::Status::OK)
|
232
|
-
|
233
243
|
rescue Interrupt => e
|
234
244
|
raise e
|
235
|
-
|
236
245
|
rescue AssertionFailure => e
|
237
246
|
Logger.log_status(desc, Logger::Status::FAILED)
|
238
247
|
raise AssertionFailure.new(e.message, e.expected, e.actual, desc), cause: nil
|
239
|
-
|
240
248
|
rescue Exception => e
|
241
249
|
Logger.log_status(desc, Logger::Status::ERROR)
|
242
250
|
raise AssertionFailure.new("An unexpected error occured during expectation: #{e.message}", nil, nil, desc), cause: e
|
@@ -244,15 +252,21 @@ module Spectre
|
|
244
252
|
end
|
245
253
|
|
246
254
|
def observe desc = nil
|
255
|
+
prefix = 'observing'
|
256
|
+
prefix += " '#{desc}'" if desc
|
257
|
+
|
247
258
|
begin
|
248
|
-
Logger.log_info(
|
259
|
+
Logger.log_info(prefix) if desc
|
249
260
|
yield
|
250
261
|
@@success = true
|
251
|
-
|
262
|
+
@@logger.info("#{prefix} finished with success")
|
252
263
|
rescue Interrupt => e
|
253
264
|
raise e
|
254
|
-
|
255
265
|
rescue Exception => e
|
266
|
+
error_message = "#{prefix} finished with failure: #{e.message}"
|
267
|
+
error_message += "\n" + e.backtrace.join("\n") if @@debug
|
268
|
+
|
269
|
+
@@logger.info(error_message)
|
256
270
|
@@success = false
|
257
271
|
end
|
258
272
|
end
|
@@ -266,6 +280,11 @@ module Spectre
|
|
266
280
|
end
|
267
281
|
end
|
268
282
|
|
283
|
+
Spectre.register do |config|
|
284
|
+
@@logger = ::Logger.new(config['log_file'], progname: 'spectre/assertion')
|
285
|
+
@@debug = config['debug']
|
286
|
+
end
|
287
|
+
|
269
288
|
Spectre.delegate :expect, :observe, :success?, :fail_with, to: self
|
270
289
|
end
|
271
290
|
end
|
data/lib/spectre/bag.rb
CHANGED
data/lib/spectre/curl.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative '../spectre'
|
2
|
+
|
1
3
|
require 'open3'
|
2
4
|
require 'ostruct'
|
3
5
|
|
@@ -21,17 +23,17 @@ module Spectre::Curl
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def header name, value
|
24
|
-
@__req['headers'] = []
|
26
|
+
@__req['headers'] = [] unless @__req['headers']
|
25
27
|
@__req['headers'].append [name, value.to_s.strip]
|
26
28
|
end
|
27
29
|
|
28
30
|
def param name, value
|
29
|
-
@__req['query'] = []
|
31
|
+
@__req['query'] = [] unless @__req['query']
|
30
32
|
@__req['query'].append [name, value.to_s.strip]
|
31
33
|
end
|
32
34
|
|
33
35
|
def content_type media_type
|
34
|
-
@__req['headers'] = []
|
36
|
+
@__req['headers'] = [] unless @__req['headers']
|
35
37
|
@__req['headers'].append ['Content-Type', media_type]
|
36
38
|
end
|
37
39
|
|
@@ -111,7 +113,7 @@ module Spectre::Curl
|
|
111
113
|
end
|
112
114
|
|
113
115
|
def json
|
114
|
-
return nil
|
116
|
+
return nil unless @res[:body]
|
115
117
|
|
116
118
|
if @data == nil
|
117
119
|
begin
|
@@ -161,28 +163,31 @@ module Spectre::Curl
|
|
161
163
|
|
162
164
|
if @@http_cfg.key? name
|
163
165
|
req.merge! @@http_cfg[name]
|
164
|
-
raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment."
|
166
|
+
raise "No `base_url' set for HTTP client '#{name}'. Check your HTTP config in your environment." unless req['base_url']
|
165
167
|
else
|
166
168
|
req['base_url'] = name
|
167
169
|
end
|
168
170
|
|
169
|
-
SpectreHttpRequest.new(req).
|
171
|
+
SpectreHttpRequest.new(req)._evaluate(&block) if block_given?
|
170
172
|
|
171
173
|
invoke(req)
|
172
174
|
end
|
173
175
|
|
174
176
|
def curl_request
|
175
177
|
raise 'No request has been invoked yet' unless @@request
|
178
|
+
|
176
179
|
@@request
|
177
180
|
end
|
178
181
|
|
179
182
|
def curl_response
|
180
183
|
raise 'There is no response. No request has been invoked yet.' unless @@response
|
184
|
+
|
181
185
|
@@response
|
182
186
|
end
|
183
187
|
|
184
188
|
def register mod
|
185
189
|
raise 'Module must not be nil' unless mod
|
190
|
+
|
186
191
|
@@modules << mod
|
187
192
|
end
|
188
193
|
|
@@ -192,7 +197,8 @@ module Spectre::Curl
|
|
192
197
|
return str unless str or str.empty?
|
193
198
|
|
194
199
|
begin
|
195
|
-
json = JSON.parse
|
200
|
+
json = JSON.parse(str)
|
201
|
+
json.obfuscate!(@@secure_keys) unless @@debug
|
196
202
|
|
197
203
|
if pretty
|
198
204
|
str = JSON.pretty_generate(json)
|
@@ -206,6 +212,25 @@ module Spectre::Curl
|
|
206
212
|
str
|
207
213
|
end
|
208
214
|
|
215
|
+
def secure? key
|
216
|
+
@@secure_keys.any? { |x| key.to_s.downcase.include? x.downcase }
|
217
|
+
end
|
218
|
+
|
219
|
+
def header_to_s headers
|
220
|
+
s = ''
|
221
|
+
|
222
|
+
return s unless headers
|
223
|
+
|
224
|
+
headers.each do |header|
|
225
|
+
key = header[0].to_s
|
226
|
+
value = header[1].to_s
|
227
|
+
value = '*****' if secure?(key) and not @@debug
|
228
|
+
s += "#{key.ljust(30, '.')}: #{value}\n"
|
229
|
+
end
|
230
|
+
|
231
|
+
s
|
232
|
+
end
|
233
|
+
|
209
234
|
def invoke req
|
210
235
|
cmd = [@@curl_path]
|
211
236
|
|
@@ -217,12 +242,12 @@ module Spectre::Curl
|
|
217
242
|
|
218
243
|
uri = req['base_url']
|
219
244
|
|
220
|
-
|
245
|
+
unless uri.match /http(?:s)?:\/\//
|
221
246
|
uri = scheme + '://' + uri
|
222
247
|
end
|
223
248
|
|
224
249
|
if req['path']
|
225
|
-
uri += '/'
|
250
|
+
uri += '/' unless uri.end_with? '/'
|
226
251
|
uri += req['path']
|
227
252
|
end
|
228
253
|
|
@@ -230,11 +255,11 @@ module Spectre::Curl
|
|
230
255
|
uri += '?'
|
231
256
|
uri += req['query']
|
232
257
|
.map { |x| x.join '='}
|
233
|
-
.join
|
258
|
+
.join('&')
|
234
259
|
end
|
235
260
|
|
236
|
-
cmd.append
|
237
|
-
cmd.append
|
261
|
+
cmd.append('"' + uri + '"')
|
262
|
+
cmd.append('-X', req['method']) unless req['method'] == 'GET' or (req['body'] and req['method'] == 'POST')
|
238
263
|
|
239
264
|
# Call all registered modules
|
240
265
|
@@modules.each do |mod|
|
@@ -243,43 +268,42 @@ module Spectre::Curl
|
|
243
268
|
|
244
269
|
# Add headers to curl command
|
245
270
|
req['headers'].each do |header|
|
246
|
-
cmd.append
|
271
|
+
cmd.append('-H', '"' + header.join(':') + '"')
|
247
272
|
end if req['headers']
|
248
273
|
|
249
274
|
# Add request body
|
250
275
|
if req['body'] != nil and not req['body'].empty?
|
251
276
|
req_body = try_format_json(req['body']).gsub(/"/, '\\"')
|
252
|
-
cmd.append
|
277
|
+
cmd.append('-d', '"' + req_body + '"')
|
253
278
|
elsif ['POST', 'PUT', 'PATCH'].include? req['method'].upcase
|
254
|
-
cmd.append
|
279
|
+
cmd.append('-d', '"\n"')
|
255
280
|
end
|
256
281
|
|
257
282
|
# Add certificate path if one if given
|
258
283
|
if req['cert']
|
259
284
|
raise "Certificate '#{req['cert']}' does not exist" unless File.exists? req['cert']
|
260
|
-
|
285
|
+
|
286
|
+
cmd.append('--cacert', req['cert'])
|
261
287
|
elsif req['use_ssl'] or uri.start_with? 'https'
|
262
|
-
cmd.append
|
288
|
+
cmd.append('-k')
|
263
289
|
end
|
264
290
|
|
265
|
-
cmd.append
|
266
|
-
cmd.append
|
291
|
+
cmd.append('-i')
|
292
|
+
cmd.append('-v')
|
267
293
|
|
268
|
-
@@request = OpenStruct.new
|
294
|
+
@@request = OpenStruct.new(req)
|
269
295
|
|
270
|
-
sys_cmd = cmd.join
|
296
|
+
sys_cmd = cmd.join(' ')
|
271
297
|
|
272
|
-
@@logger.debug
|
298
|
+
@@logger.debug(sys_cmd)
|
273
299
|
|
274
300
|
req_id = SecureRandom.uuid()[0..5]
|
275
301
|
|
276
302
|
req_log = "[>] #{req_id} #{req['method']} #{uri}\n"
|
277
|
-
req['headers']
|
278
|
-
|
279
|
-
end if req['headers']
|
280
|
-
req_log += req['body'] if req['body'] != nil and not req['body'].empty?
|
303
|
+
req_log += header_to_s(req['headers'])
|
304
|
+
req_log += try_format_json(req['body'], pretty: true)
|
281
305
|
|
282
|
-
@@logger.info
|
306
|
+
@@logger.info(req_log)
|
283
307
|
|
284
308
|
start_time = Time.now
|
285
309
|
|
@@ -295,9 +319,9 @@ module Spectre::Curl
|
|
295
319
|
|
296
320
|
# debug_log.lines.each { |x| @@logger.debug x unless x.empty? }
|
297
321
|
|
298
|
-
raise "Unable to request #{uri}. Please check if this
|
322
|
+
raise "Unable to request #{uri}. Please check if this URL is correctly configured and reachable." unless output
|
299
323
|
|
300
|
-
@@logger.debug
|
324
|
+
@@logger.debug("[<] #{req_id} stdout:\n#{output}")
|
301
325
|
|
302
326
|
header, body = output.split /\r?\n\r?\n/
|
303
327
|
|
@@ -323,7 +347,7 @@ module Spectre::Curl
|
|
323
347
|
code: match[:code].to_i,
|
324
348
|
message: match[:message],
|
325
349
|
headers: Hash[res_headers],
|
326
|
-
body: body
|
350
|
+
body: body,
|
327
351
|
}
|
328
352
|
|
329
353
|
# Call all registered modules
|
@@ -342,7 +366,7 @@ module Spectre::Curl
|
|
342
366
|
|
343
367
|
@@logger.info res_log
|
344
368
|
|
345
|
-
@@response = SpectreHttpResponse.new
|
369
|
+
@@response = SpectreHttpResponse.new(res)
|
346
370
|
|
347
371
|
raise "Response did not indicate success: #{@@response.code} #{@@response.message}" if req['ensure_success'] and not @@response.success?
|
348
372
|
|
@@ -351,7 +375,12 @@ module Spectre::Curl
|
|
351
375
|
end
|
352
376
|
|
353
377
|
Spectre.register do |config|
|
354
|
-
@@
|
378
|
+
@@debug = config['debug']
|
379
|
+
|
380
|
+
@@logger = ::Logger.new(config['log_file'], progname: 'spectre/curl')
|
381
|
+
@@logger.level = @@debug ? Logger::DEBUG : Logger::INFO
|
382
|
+
|
383
|
+
@@secure_keys = config['secure_keys'] || []
|
355
384
|
|
356
385
|
@@curl_path = config['curl_path'] || 'curl'
|
357
386
|
|
@@ -365,4 +394,4 @@ module Spectre::Curl
|
|
365
394
|
end
|
366
395
|
|
367
396
|
Spectre.delegate :curl, :curl_response, :curl_request, to: self
|
368
|
-
end
|
397
|
+
end
|
data/lib/spectre/diagnostic.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative '../spectre'
|
2
|
+
|
1
3
|
module Spectre
|
2
4
|
module Diagnostic
|
3
5
|
module Stopwatch
|
@@ -21,9 +23,17 @@ module Spectre
|
|
21
23
|
def duration
|
22
24
|
@@end_time - @@start_time
|
23
25
|
end
|
26
|
+
|
27
|
+
def started_at
|
28
|
+
@@start_time
|
29
|
+
end
|
30
|
+
|
31
|
+
def finished_at
|
32
|
+
@@end_time
|
33
|
+
end
|
24
34
|
end
|
25
35
|
|
26
|
-
Spectre.delegate :start_watch, :stop_watch, :duration, :measure, to:
|
36
|
+
Spectre.delegate :start_watch, :stop_watch, :duration, :measure, to: self
|
27
37
|
end
|
28
38
|
end
|
29
|
-
end
|
39
|
+
end
|