spectre-core 1.8.4 → 1.12.0

Sign up to get free protection for your applications and to get access to all the features.
data/exe/spectre CHANGED
@@ -1,494 +1,516 @@
1
- #! /usr/bin/ruby
2
- # frozen_string_literal: true
3
-
4
- require 'yaml'
5
- require 'ostruct'
6
- require 'optparse'
7
- require 'fileutils'
8
- require 'ectoplasm'
9
-
10
- require_relative '../lib/spectre'
11
-
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
- DEFAULT_CONFIG = {
22
- 'config_file' => './spectre.yml',
23
- 'environment' => 'default',
24
- 'specs' => [],
25
- 'tags' => [],
26
- 'colored' => true,
27
- 'verbose' => false,
28
- 'reporters' => [
29
- 'Spectre::Reporter::Console',
30
- ],
31
- 'loggers' => [
32
- 'Spectre::Logger::Console',
33
- 'Spectre::Logger::File',
34
- ],
35
- 'log_file' => './logs/spectre_<date>.log',
36
- 'log_format' => {
37
- 'console' => {
38
- 'indent' => 2,
39
- 'width' => 80,
40
- 'end_context' => nil,
41
- 'separator' => '<indent><desc>',
42
- },
43
- 'file' => {
44
- 'separator' => '-- <desc>',
45
- 'start_group' => "-- Start '<desc>'",
46
- 'end_group' => "-- End '<desc>'",
47
- }
48
- },
49
- 'debug' => false,
50
- 'out_path' => './reports',
51
- 'spec_patterns' => ['./specs/**/*.spec.rb'],
52
- 'mixin_patterns' => ['../common/mixins/**/*.mixin.rb', './mixins/**/*.mixin.rb'],
53
- 'env_patterns' => ['./environments/**/*.env.yml'],
54
- 'env_partial_patterns' => ['./environments/**/*.env.secret.yml'],
55
- 'resource_paths' => ['../common/resources', './resources'],
56
- 'modules' => [
57
- 'spectre/helpers',
58
- 'spectre/reporter/console',
59
- 'spectre/reporter/junit',
60
- 'spectre/logger/console',
61
- 'spectre/logger/file',
62
- 'spectre/assertion',
63
- 'spectre/diagnostic',
64
- 'spectre/environment',
65
- 'spectre/mixin',
66
- 'spectre/bag',
67
- 'spectre/http',
68
- 'spectre/http/basic_auth',
69
- 'spectre/http/keystone',
70
- 'spectre/resources',
71
- 'spectre/ssh',
72
- 'spectre/ftp',
73
- 'spectre/mysql',
74
- # 'spectre/postgres',
75
- ],
76
- 'include' => [
77
-
78
- ],
79
- 'exclude' => [
80
-
81
- ]
82
- }
83
-
84
-
85
- cmd_options = {}
86
-
87
- opt_parser = OptionParser.new do |opts|
88
- opts.banner = %{Spectre #{Spectre::VERSION}
89
-
90
- Usage: spectre [command] [options]
91
-
92
- Commands:
93
- list List specs
94
- run Run specs (default)
95
- show Print current environment settings
96
- dump Dumps the given environment in YAML format to console
97
- init Initializes a new spectre project
98
-
99
- Specific options:}
100
-
101
- opts.on('-s SPEC,SPEC', '--specs SPEC,SPEC', Array, 'The specs to run') do |specs|
102
- cmd_options['specs'] = specs
103
- end
104
-
105
- opts.on('-t TAG,TAG', '--tags TAG,TAG', Array, 'Run only specs with given tags') do |tags|
106
- cmd_options['tags'] = tags
107
- end
108
-
109
- opts.on('-e NAME', '--env NAME', 'Name of the environment to load') do |env_name|
110
- cmd_options['environment'] = env_name
111
- end
112
-
113
- opts.on('-c FILE', '--config FILE', 'Config file to load') do |file_path|
114
- cmd_options['config_file'] = file_path
115
- end
116
-
117
- opts.on('--spec-pattern PATTERN', Array, 'File pattern for spec files') do |spec_pattern|
118
- cmd_options['spec_patterns'] = spec_pattern
119
- end
120
-
121
- opts.on('--env-pattern PATTERN', Array, 'File pattern for environment files') do |env_patterns|
122
- cmd_options['env_patterns'] = env_patterns
123
- end
124
-
125
- opts.on('--no-color', 'Disable colored output') do
126
- cmd_options['colored'] = false
127
- end
128
-
129
- opts.on('-o PATH', '--out PATH', 'Output directory path') do |path|
130
- cmd_options['out_path'] = path
131
- end
132
-
133
- opts.on('-r NAME', '--reporter NAME', Array, "A list of reporters to use") do |reporters|
134
- cmd_options['reporters'] = reporters
135
- end
136
-
137
- opts.on('-d', '--debug', "Run in debug mode") do
138
- cmd_options['debug'] = true
139
- end
140
-
141
- opts.on('-p KEY=VAL', '--property KEY=VAL', "Override config option. Use `spectre show` to get list of available options") do |option|
142
- key, val = option.split '='
143
- val = val.split ',' if DEFAULT_CONFIG[key].is_a? Array
144
- val = ['true', '1'].include? val if [true, false].include? DEFAULT_CONFIG[key]
145
- val = val.to_i if DEFAULT_CONFIG[key].is_a? Integer
146
- cmd_options[key] = val
147
-
148
- curr_opt = cmd_options
149
- (key.split '.').each do |k|
150
- curr_opt[k] = {} if not curr_opt.key? k
151
- end
152
- curr_opt = val
153
-
154
- end
155
-
156
- opts.separator "\nCommon options:"
157
-
158
- opts.on_tail('--version', 'Print current installed version') do
159
- puts Spectre::VERSION
160
- exit
161
- end
162
-
163
- opts.on_tail('-h', '--help', 'Print this help') do
164
- puts opts
165
- exit
166
- end
167
- end.parse!
168
-
169
-
170
- action = ARGV[0] || 'run'
171
-
172
-
173
- ###########################################
174
- # Load Config
175
- ###########################################
176
-
177
-
178
- cfg = {}
179
- cfg.deep_merge! DEFAULT_CONFIG
180
-
181
- global_config_file = File.join File.expand_path('~'), '.spectre'
182
-
183
- if File.exists? global_config_file
184
- global_options = YAML.load_file(global_config_file)
185
- cfg.deep_merge! global_options if global_options
186
- end
187
-
188
- config_file = cmd_options['config_file'] || cfg['config_file']
189
-
190
- if File.exists? config_file
191
- file_options = YAML.load_file(config_file)
192
- cfg.deep_merge! file_options
193
- Dir.chdir File.dirname(config_file)
194
- end
195
-
196
- cfg.deep_merge! cmd_options
197
-
198
-
199
- ###########################################
200
- # Load Environment
201
- ###########################################
202
-
203
-
204
- envs = {}
205
- read_env_files = {}
206
- cfg['env_patterns'].each do |pattern|
207
- Dir.glob(pattern).each do|f|
208
- spec_env = YAML.load_file(f)
209
- name = spec_env.delete('name') || 'default'
210
-
211
- if envs.key? name
212
- existing_env_file = read_env_files[name]
213
- puts "Duplicate environment definition detected with name #{name} in '#{f}'. Previously defined in '#{existing_env_file}'"
214
- exit 1
215
- end
216
-
217
- read_env_files[name] = f
218
- envs[name] = spec_env
219
- end
220
- end
221
-
222
- # Merge partial environment configs with existing environments
223
- cfg['env_partial_patterns'].each do |pattern|
224
- Dir.glob(pattern).each do|f|
225
- partial_env = YAML.load_file(f)
226
- name = partial_env.delete('name') || 'default'
227
- next if not envs.key? name
228
-
229
- envs[name].deep_merge! partial_env
230
- end
231
- end
232
-
233
- env = envs[cfg['environment']]
234
- cfg.merge! env if env
235
-
236
-
237
- String.colored! if cfg['colored']
238
-
239
-
240
- ###########################################
241
- # Load Specs
242
- ###########################################
243
-
244
-
245
- cfg['spec_patterns'].each do |pattern|
246
- Dir.glob(pattern).each do|f|
247
- require_relative File.join(Dir.pwd, f)
248
- end
249
- end
250
-
251
-
252
- ###########################################
253
- # List specs
254
- ###########################################
255
-
256
-
257
- if action == 'list'
258
- colors = [:blue, :magenta, :yellow, :green]
259
- specs = Spectre.specs(cfg['specs'], cfg['tags'])
260
-
261
- exit 1 if specs.length == 0
262
-
263
- counter = 0
264
-
265
- specs.group_by { |x| x.subject }.each do |subject, spec_group|
266
- spec_group.each do |spec|
267
- tags = spec.tags.map { |x| '#' + x.to_s }.join ' '
268
- desc = subject.desc
269
- desc += ' - ' + spec.context.__desc + ' -' if spec.context.__desc
270
- desc += ' ' + spec.desc
271
- puts "[#{spec.name}]".send(colors[counter % colors.length]) + " #{desc} #{tags.cyan}"
272
- end
273
-
274
- counter += 1
275
- end
276
-
277
- exit 0
278
- end
279
-
280
-
281
- ###########################################
282
- # Run
283
- ###########################################
284
-
285
-
286
- if action == 'run'
287
- # Initialize logger
288
- now = Time.now
289
-
290
- cfg['log_file'] = cfg['log_file'].frmt({
291
- shortdate: now.strftime('%Y-%m-%d'),
292
- date: now.strftime('%Y-%m-%d_%H%M%S'),
293
- timestamp: now.strftime('%s'),
294
- subject: 'spectre',
295
- })
296
-
297
- log_dir = File.dirname cfg['log_file']
298
- FileUtils.makedirs log_dir if !Dir.exists? log_dir
299
-
300
- # Load Modules
301
- cfg['modules']
302
- .concat(cfg['include'])
303
- .select { |mod| !cfg['exclude'].include? mod }
304
- .each do |mod|
305
- begin
306
- spectre_lib_mod = File.join('../lib', mod)
307
-
308
- if File.exists? mod
309
- require_relative mod
310
-
311
- elsif File.exists? spectre_lib_mod
312
- require_relative spectre_lib_mod
313
-
314
- else
315
- require mod
316
- end
317
-
318
- rescue LoadError => e
319
- puts "Unable to load module #{mod}. Check if the module exists or remove it from your spectre config:\n#{e.message}"
320
- exit 1
321
- end
322
- end
323
-
324
- Spectre.configure(cfg)
325
-
326
- Spectre::Logger.debug! if cfg['debug']
327
-
328
- cfg['loggers'].each do |logger_name|
329
- logger = Kernel.const_get(logger_name).new(cfg)
330
- Spectre::Logger.add(logger)
331
- end if cfg['loggers']
332
-
333
- specs = Spectre.specs(cfg['specs'], cfg['tags'])
334
-
335
- if specs.length == 0
336
- puts "No specs found in #{Dir.pwd}"
337
- exit 1
338
- end
339
-
340
- run_infos = Spectre::Runner.new.run(specs)
341
-
342
- cfg['reporters'].each do |reporter|
343
- reporter = Kernel.const_get(reporter).new(cfg)
344
- reporter.report(run_infos)
345
- end
346
-
347
- exit 0
348
- end
349
-
350
-
351
- ###########################################
352
- # Envs
353
- ###########################################
354
-
355
-
356
- if action == 'envs'
357
- exit 1 if envs.length == 0
358
- puts envs.pretty
359
- exit 0
360
- end
361
-
362
-
363
- ###########################################
364
- # Show
365
- ###########################################
366
-
367
-
368
- if action == 'show'
369
- puts cfg.pretty
370
- exit 0
371
- end
372
-
373
-
374
- ###########################################
375
- # Dump
376
- ###########################################
377
-
378
-
379
- if action == 'dump'
380
- puts YAML.dump(cfg)
381
- end
382
-
383
-
384
- ###########################################
385
- # Init
386
- ###########################################
387
-
388
- DEFAULT_SPECTRE_CFG = %{log_file: ./logs/spectre_<date>.log
389
- env_patterns:
390
- - './environments/**/*.env.yml'
391
- env_partial_patterns:
392
- - './environments/**/*.env.secret.yml'
393
- spec_patterns:
394
- - './specs/**/*.spec.rb'
395
- mixin_patterns:
396
- - '../common/**/*.mixin.rb'
397
- - './mixins/**/*.mixin.rb'
398
- resource_paths:
399
- - '../common/resources'
400
- - './resources'
401
- }
402
-
403
-
404
- DEFAULT_ENV_CFG = %{cert: &cert ./resources/<root_cert>.cer
405
- http:
406
- <http_client_name>:
407
- base_url: http://localhost:5000/api/v1/
408
- # basic_auth:
409
- # username: <username>
410
- # password: <password>
411
- # keystone:
412
- # url: https://<keystone_url>/main/v3/
413
- # username: <username>
414
- # password: <password>
415
- # project: <project>
416
- # domain: <domain>
417
- # cert: *cert
418
- # ssh:
419
- # <ssh_client_name>:
420
- # host: <hostname>
421
- # username: <username>
422
- # password: <password>
423
- }
424
-
425
- DEFAULT_ENV_SECRET_CFG = %{http:
426
- <http_client_name>:
427
- # basic_auth:
428
- # username: <username>
429
- # password: <password>
430
- # keystone:
431
- # username: <username>
432
- # password: <password>
433
- # ssh:
434
- # <ssh_client_name>:
435
- # username: <username>
436
- # password: <password>
437
- }
438
-
439
- SAMPLE_SPEC = %[describe '<subject>' do
440
- it 'does some http requests', tags: [:sample] do
441
- log 'doing some http request'
442
-
443
- http '<http_client_name>' do
444
- auth 'basic'
445
- # auth 'keystone'
446
- method 'GET'
447
- path 'path/to/resource'
448
- param 'id', 4295118773
449
- param 'foo', 'bar'
450
- header 'X-Correlation-Id', '4c2367b1-bfee-4cc2-bdc5-ed17a6a9dd4b'
451
- header 'Range', 'bytes=500-999'
452
- json({
453
- "message": "Hello Spectre!"
454
- })
455
- end
456
-
457
- expect 'the response code to be 200' do
458
- response.code.should_be 200
459
- end
460
-
461
- expect 'a message to exist' do
462
- response.json.message.should_not_be nil
463
- end
464
- end
465
- end
466
- ]
467
-
468
- DEFAULT_GITIGNORE = %[*.code-workspace
469
- logs/
470
- reports/
471
- **/environments/*.env.secret.yml
472
- ]
473
-
474
- if action == 'init'
475
- DEFAULT_FILES = [
476
- ['./environments/default.env.yml', DEFAULT_ENV_CFG],
477
- ['./environments/default.env.secret.yml', DEFAULT_ENV_SECRET_CFG],
478
- ['./specs/sample.spec.rb', SAMPLE_SPEC],
479
- ['./spectre.yml', DEFAULT_SPECTRE_CFG],
480
- ['./.gitignore', DEFAULT_GITIGNORE],
481
- ]
482
-
483
- %w(environments logs specs).each do |dir_name|
484
- Dir.mkdir(dir_name) unless File.directory? dir_name
485
- end
486
-
487
- DEFAULT_FILES.each do |file, content|
488
- if not File.exists? file
489
- File.write(file, content)
490
- end
491
- end
492
-
493
- exit 0
494
- end
1
+ #! /usr/bin/ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'yaml'
5
+ require 'ostruct'
6
+ require 'optparse'
7
+ require 'fileutils'
8
+ require 'ectoplasm'
9
+
10
+ require_relative '../lib/spectre'
11
+
12
+
13
+ DEFAULT_CONFIG = {
14
+ 'config_file' => './spectre.yml',
15
+ 'environment' => 'default',
16
+ 'specs' => [],
17
+ 'tags' => [],
18
+ 'colored' => true,
19
+ 'verbose' => false,
20
+ 'reporters' => [
21
+ 'Spectre::Reporter::Console',
22
+ ],
23
+ 'loggers' => [
24
+ 'Spectre::Logger::Console',
25
+ 'Spectre::Logger::File',
26
+ ],
27
+ 'log_file' => './logs/spectre_<date>.log',
28
+ 'log_format' => {
29
+ 'console' => {
30
+ 'indent' => 2,
31
+ 'width' => 80,
32
+ 'end_context' => nil,
33
+ 'separator' => '<indent><desc>',
34
+ },
35
+ 'file' => {
36
+ 'separator' => '-- <desc>',
37
+ 'start_group' => "-- Start '<desc>'",
38
+ 'end_group' => "-- End '<desc>'",
39
+ },
40
+ },
41
+ 'debug' => false,
42
+ 'out_path' => './reports',
43
+ 'secure_keys' => ['password', 'secret', 'token', 'secure', 'authorization'],
44
+ 'spec_patterns' => ['./specs/**/*.spec.rb'],
45
+ 'mixin_patterns' => ['../common/mixins/**/*.mixin.rb', './mixins/**/*.mixin.rb'],
46
+ 'env_patterns' => ['./environments/**/*.env.yml'],
47
+ 'env_partial_patterns' => ['./environments/**/*.env.secret.yml'],
48
+ 'resource_paths' => ['../common/resources', './resources'],
49
+ 'modules' => [
50
+ 'spectre/helpers',
51
+ 'spectre/reporter/console',
52
+ 'spectre/reporter/junit',
53
+ 'spectre/logger/console',
54
+ 'spectre/logger/file',
55
+ 'spectre/assertion',
56
+ 'spectre/diagnostic',
57
+ 'spectre/environment',
58
+ 'spectre/mixin',
59
+ 'spectre/bag',
60
+ 'spectre/http',
61
+ 'spectre/http/basic_auth',
62
+ 'spectre/http/keystone',
63
+ 'spectre/resources',
64
+ ],
65
+ 'include' => [
66
+
67
+ ],
68
+ 'exclude' => [
69
+
70
+ ],
71
+ }
72
+
73
+
74
+ cmd_options = {}
75
+
76
+ opt_parser = OptionParser.new do |opts|
77
+ opts.banner = %{Spectre #{Spectre::VERSION}
78
+
79
+ Usage: spectre [command] [options]
80
+
81
+ Commands:
82
+ list List specs
83
+ run Run specs (default)
84
+ show Print current environment settings
85
+ dump Dumps the given environment in YAML format to console
86
+ init Initializes a new spectre project
87
+
88
+ Specific options:}
89
+
90
+ opts.on('-s SPEC,SPEC', '--specs SPEC,SPEC', Array, 'The specs to run') do |specs|
91
+ cmd_options['specs'] = specs
92
+ end
93
+
94
+ opts.on('-t TAG,TAG', '--tags TAG,TAG', Array, 'Run only specs with given tags') do |tags|
95
+ cmd_options['tags'] = tags
96
+ end
97
+
98
+ opts.on('-e NAME', '--env NAME', 'Name of the environment to load') do |env_name|
99
+ cmd_options['environment'] = env_name
100
+ end
101
+
102
+ opts.on('-c FILE', '--config FILE', 'Config file to load') do |file_path|
103
+ cmd_options['config_file'] = file_path
104
+ end
105
+
106
+ opts.on('--spec-pattern PATTERN', Array, 'File pattern for spec files') do |spec_pattern|
107
+ cmd_options['spec_patterns'] = spec_pattern
108
+ end
109
+
110
+ opts.on('--env-pattern PATTERN', Array, 'File pattern for environment files') do |env_patterns|
111
+ cmd_options['env_patterns'] = env_patterns
112
+ end
113
+
114
+ opts.on('--no-color', 'Disable colored output') do
115
+ cmd_options['colored'] = false
116
+ end
117
+
118
+ opts.on('--ignore-failure', 'Always exit with code 0') do
119
+ cmd_options['ignore_failure'] = true
120
+ end
121
+
122
+ opts.on('-o PATH', '--out PATH', 'Output directory path') do |path|
123
+ cmd_options['out_path'] = File.absolute_path(path)
124
+ end
125
+
126
+ opts.on('-r NAME', '--reporters NAME', Array, "A list of reporters to use") do |reporters|
127
+ cmd_options['reporters'] = reporters
128
+ end
129
+
130
+ opts.on('-d', '--debug', "Run in debug mode") do
131
+ cmd_options['debug'] = true
132
+ end
133
+
134
+ opts.on('-p KEY=VAL', '--property KEY=VAL', "Override config option. Use `spectre show` to get list of available options") do |option|
135
+ key, val = option.split '='
136
+ val = val.split ',' if DEFAULT_CONFIG[key].is_a? Array
137
+ val = ['true', '1'].include? val if [true, false].include? DEFAULT_CONFIG[key]
138
+ val = val.to_i if DEFAULT_CONFIG[key].is_a? Integer
139
+ cmd_options[key] = val
140
+
141
+ curr_opt = cmd_options
142
+ (key.split '.').each do |k|
143
+ curr_opt[k] = {} unless curr_opt.key? k
144
+ end
145
+ curr_opt = val
146
+ end
147
+
148
+ opts.separator "\nCommon options:"
149
+
150
+ opts.on_tail('--version', 'Print current installed version') do
151
+ puts Spectre::VERSION
152
+ exit
153
+ end
154
+
155
+ opts.on_tail('-h', '--help', 'Print this help') do
156
+ puts opts
157
+ exit
158
+ end
159
+ end.parse!
160
+
161
+
162
+ action = ARGV[0] || 'run'
163
+
164
+
165
+ ###########################################
166
+ # Load Config
167
+ ###########################################
168
+
169
+
170
+ cfg = {}
171
+ cfg.deep_merge! DEFAULT_CONFIG
172
+
173
+ global_config_file = File.join File.expand_path('~'), '.spectre'
174
+
175
+ if File.exists? global_config_file
176
+ global_options = YAML.load_file(global_config_file)
177
+ cfg.deep_merge! global_options if global_options
178
+ end
179
+
180
+ config_file = cmd_options['config_file'] || cfg['config_file']
181
+
182
+ if File.exists? config_file
183
+ file_options = YAML.load_file(config_file)
184
+ cfg.deep_merge! file_options
185
+ Dir.chdir File.dirname(config_file)
186
+ end
187
+
188
+ cfg.deep_merge! cmd_options
189
+
190
+
191
+ ###########################################
192
+ # Load Environment
193
+ ###########################################
194
+
195
+
196
+ envs = {}
197
+ read_env_files = {}
198
+ cfg['env_patterns'].each do |pattern|
199
+ Dir.glob(pattern).each do|f|
200
+ spec_env = YAML.load_file(f) || {}
201
+
202
+ name = spec_env['name'] || 'default'
203
+
204
+ if envs.key? name
205
+ existing_env_file = read_env_files[name]
206
+ puts "Duplicate environment definition detected with name #{name} in '#{f}'. Previously defined in '#{existing_env_file}'"
207
+ exit 1
208
+ end
209
+
210
+ read_env_files[name] = f
211
+ envs[name] = spec_env
212
+ end
213
+ end
214
+
215
+ # Merge partial environment configs with existing environments
216
+ cfg['env_partial_patterns'].each do |pattern|
217
+ Dir.glob(pattern).each do|f|
218
+ partial_env = YAML.load_file(f)
219
+ name = partial_env.delete('name') || 'default'
220
+ next unless envs.key? name
221
+
222
+ envs[name].deep_merge! partial_env
223
+ end
224
+ end
225
+
226
+ env = envs[cfg['environment']]
227
+ cfg.merge! env if env
228
+
229
+
230
+ String.colored! if cfg['colored']
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
+
236
+
237
+ ###########################################
238
+ # Load Specs
239
+ ###########################################
240
+
241
+
242
+ cfg['spec_patterns'].each do |pattern|
243
+ Dir.glob(pattern).each do|f|
244
+ require_relative File.join(Dir.pwd, f)
245
+ end
246
+ end
247
+
248
+
249
+ ###########################################
250
+ # List specs
251
+ ###########################################
252
+
253
+
254
+ if 'list' == action
255
+ colors = [:blue, :magenta, :yellow, :green]
256
+ specs = Spectre.specs(cfg['specs'], cfg['tags'])
257
+
258
+ exit 1 unless specs.any?
259
+
260
+ counter = 0
261
+
262
+ specs.group_by { |x| x.subject }.each do |subject, spec_group|
263
+ spec_group.each do |spec|
264
+ tags = spec.tags.map { |x| '#' + x.to_s }.join ' '
265
+ desc = subject.desc
266
+ desc += ' - ' + spec.context.__desc + ' -' if spec.context.__desc
267
+ desc += ' ' + spec.desc
268
+ puts "[#{spec.name}]".send(colors[counter % colors.length]) + " #{desc} #{tags.cyan}"
269
+ end
270
+
271
+ counter += 1
272
+ end
273
+
274
+ exit 0
275
+ end
276
+
277
+
278
+ ###########################################
279
+ # Run
280
+ ###########################################
281
+
282
+
283
+ if 'run' == action
284
+ # Initialize logger
285
+ now = Time.now
286
+
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
+ })
294
+
295
+ log_dir = File.dirname cfg['log_file']
296
+ FileUtils.makedirs log_dir unless Dir.exists? log_dir
297
+
298
+ # Load Modules
299
+
300
+ cfg['modules']
301
+ .concat(cfg['include'])
302
+ .select { |mod| !cfg['exclude'].include? mod }
303
+ .each do |mod|
304
+ begin
305
+ mod_file = mod + '.rb'
306
+ spectre_lib_mod = File.join(File.dirname(__dir__), 'lib', mod_file)
307
+
308
+ if File.exists? mod_file
309
+ require_relative mod_file
310
+
311
+ elsif File.exists? spectre_lib_mod
312
+ require_relative spectre_lib_mod
313
+
314
+ else
315
+ require mod
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
329
+ end
330
+
331
+ Spectre.configure(cfg)
332
+
333
+ Spectre::Logger.debug! if cfg['debug']
334
+
335
+ cfg['loggers'].each do |logger_name|
336
+ logger = Kernel.const_get(logger_name).new(cfg)
337
+ Spectre::Logger.add(logger)
338
+ end if cfg['loggers']
339
+
340
+ specs = Spectre.specs(cfg['specs'], cfg['tags'])
341
+
342
+ unless specs.any?
343
+ puts "No specs found in #{Dir.pwd}"
344
+ exit 1
345
+ end
346
+
347
+ run_infos = Spectre::Runner.new.run(specs)
348
+
349
+ cfg['reporters'].each do |reporter|
350
+ reporter = Kernel.const_get(reporter).new(cfg)
351
+ reporter.report(run_infos)
352
+ end
353
+
354
+ errors = run_infos.select { |x| nil != x.error or nil != x.failure }
355
+
356
+ exit 0 if cfg['ignore_failure'] or not errors.any?
357
+
358
+ exit 1
359
+ end
360
+
361
+
362
+ ###########################################
363
+ # Envs
364
+ ###########################################
365
+
366
+
367
+ if 'envs' == action
368
+ exit 1 unless envs.any?
369
+ puts envs.pretty
370
+ exit 0
371
+ end
372
+
373
+
374
+ ###########################################
375
+ # Show
376
+ ###########################################
377
+
378
+
379
+ if 'show' == action
380
+ puts cfg.pretty
381
+ exit 0
382
+ end
383
+
384
+
385
+ ###########################################
386
+ # Dump
387
+ ###########################################
388
+
389
+
390
+ if 'dump' == action
391
+ puts YAML.dump(cfg)
392
+ end
393
+
394
+
395
+ ###########################################
396
+ # Init
397
+ ###########################################
398
+
399
+ DEFAULT_SPECTRE_CFG = %{log_file: ./logs/spectre_<date>.log
400
+ env_patterns:
401
+ - './environments/**/*.env.yml'
402
+ env_partial_patterns:
403
+ - './environments/**/*.env.secret.yml'
404
+ spec_patterns:
405
+ - './specs/**/*.spec.rb'
406
+ mixin_patterns:
407
+ - '../common/**/*.mixin.rb'
408
+ - './mixins/**/*.mixin.rb'
409
+ resource_paths:
410
+ - '../common/resources'
411
+ - './resources'
412
+ }
413
+
414
+
415
+ DEFAULT_ENV_CFG = %{cert: &cert ./resources/<root_cert>.cer
416
+ http:
417
+ <http_client_name>:
418
+ base_url: http://localhost:5000/api/v1/
419
+ # basic_auth:
420
+ # username: <username>
421
+ # password: <password>
422
+ # keystone:
423
+ # url: https://<keystone_url>/main/v3/
424
+ # username: <username>
425
+ # password: <password>
426
+ # project: <project>
427
+ # domain: <domain>
428
+ # cert: *cert
429
+ # ssh:
430
+ # <ssh_client_name>:
431
+ # host: <hostname>
432
+ # username: <username>
433
+ # password: <password>
434
+ }
435
+
436
+ DEFAULT_ENV_SECRET_CFG = %{http:
437
+ <http_client_name>:
438
+ # basic_auth:
439
+ # username: <username>
440
+ # password: <password>
441
+ # keystone:
442
+ # username: <username>
443
+ # password: <password>
444
+ # ssh:
445
+ # <ssh_client_name>:
446
+ # username: <username>
447
+ # password: <password>
448
+ }
449
+
450
+ SAMPLE_SPEC = %[describe '<subject>' do
451
+ it 'does some http requests', tags: [:sample] do
452
+ log 'doing some http request'
453
+
454
+ http '<http_client_name>' do
455
+ auth 'basic'
456
+ # auth 'keystone'
457
+ method 'GET'
458
+ path 'path/to/resource'
459
+ param 'id', 4295118773
460
+ param 'foo', 'bar'
461
+ header 'X-Correlation-Id', '4c2367b1-bfee-4cc2-bdc5-ed17a6a9dd4b'
462
+ header 'Range', 'bytes=500-999'
463
+ json({
464
+ "message": "Hello Spectre!"
465
+ })
466
+ end
467
+
468
+ expect 'the response code to be 200' do
469
+ response.code.should_be 200
470
+ end
471
+
472
+ expect 'a message to exist' do
473
+ response.json.message.should_not_be nil
474
+ end
475
+ end
476
+ end
477
+ ]
478
+
479
+ DEFAULT_GITIGNORE = %[*.code-workspace
480
+ logs/
481
+ reports/
482
+ **/environments/*.env.secret.yml
483
+ ]
484
+
485
+ DEFAULT_GEMFILE = %[source 'https://rubygems.org'
486
+
487
+ gem 'spectre-core', '>= #{Spectre::VERSION}'
488
+ # gem 'spectre-mysql', '>= 1.0.0'
489
+ # gem 'spectre-ssh', '>= 1.0.0'
490
+ # gem 'spectre-ftp', '>= 1.0.0'
491
+ # gem 'spectre-curl', '>= 1.0.0'
492
+ # gem 'spectre-git', '>= 0.1.0'
493
+ ]
494
+
495
+ if 'init' == action
496
+ DEFAULT_FILES = [
497
+ ['./environments/default.env.yml', DEFAULT_ENV_CFG],
498
+ ['./environments/default.env.secret.yml', DEFAULT_ENV_SECRET_CFG],
499
+ ['./specs/sample.spec.rb', SAMPLE_SPEC],
500
+ ['./spectre.yml', DEFAULT_SPECTRE_CFG],
501
+ ['./.gitignore', DEFAULT_GITIGNORE],
502
+ ['./Gemfile', DEFAULT_GEMFILE],
503
+ ]
504
+
505
+ %w(environments logs specs).each do |dir_name|
506
+ Dir.mkdir(dir_name) unless File.directory? dir_name
507
+ end
508
+
509
+ DEFAULT_FILES.each do |file, content|
510
+ unless File.exists? file
511
+ File.write(file, content)
512
+ end
513
+ end
514
+
515
+ exit 0
516
+ end