inspec 0.25.0 → 0.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -2
- data/inspec.gemspec +1 -1
- data/lib/inspec/cli.rb +2 -1
- data/lib/inspec/rspec_json_formatter.rb +249 -10
- data/lib/inspec/runner.rb +1 -0
- data/lib/inspec/runner_mock.rb +1 -0
- data/lib/inspec/runner_rspec.rb +14 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +1 -1
- data/lib/utils/base_cli.rb +1 -1
- data/test/functional/inspec_exec_jsonmin_test.rb +59 -0
- data/test/functional/inspec_exec_test.rb +54 -48
- data/test/integration/default/compare_matcher_spec.rb +5 -0
- data/test/unit/mock/profiles/spec_only/specfile.rb +11 -0
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 24a4519c426bef0955b532d458a7436c172ee78e
|
4
|
+
data.tar.gz: 94fa93e202174527e9d40cbf1f174cc37a879492
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afa1eeb884e110fd29387f621aa29ff8a90f428257a96f657fba4001520bb893e23af8f94d583cb73579c9eb6a4f95986a4df842f81aea5513fd7eb7c450a944
|
7
|
+
data.tar.gz: 7cb77d205bdf7ebadae0b376aefb35d03ee1ab444b8d95a30f8042eb5ab139bc2f6112d2557ded9bdbfbff07cb68998bf86b7d8884d4b15554b64f6dd827a925
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,30 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [0.
|
4
|
-
[Full Changelog](https://github.com/chef/inspec/compare/v0.
|
3
|
+
## [0.26.0](https://github.com/chef/inspec/tree/0.26.0) (2016-06-16)
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.25.0...0.26.0)
|
5
|
+
|
6
|
+
**Implemented enhancements:**
|
7
|
+
|
8
|
+
- use train instead of r-train [\#795](https://github.com/chef/inspec/pull/795) ([chris-rock](https://github.com/chris-rock))
|
9
|
+
|
10
|
+
**Fixed bugs:**
|
11
|
+
|
12
|
+
- Transport error while trying to ssh to mac osx [\#788](https://github.com/chef/inspec/issues/788)
|
13
|
+
|
14
|
+
**Closed issues:**
|
15
|
+
|
16
|
+
- Can't upload inherited profile [\#789](https://github.com/chef/inspec/issues/789)
|
17
|
+
|
18
|
+
**Merged pull requests:**
|
19
|
+
|
20
|
+
- provide target info in cli output [\#796](https://github.com/chef/inspec/pull/796) ([arlimus](https://github.com/arlimus))
|
21
|
+
- multi-profile reporting in cli formatter [\#794](https://github.com/chef/inspec/pull/794) ([arlimus](https://github.com/arlimus))
|
22
|
+
- use utf-8 characters for default cli formatter [\#792](https://github.com/chef/inspec/pull/792) ([arlimus](https://github.com/arlimus))
|
23
|
+
- integer?\("0300"\) should not be true [\#791](https://github.com/chef/inspec/pull/791) ([srenatus](https://github.com/srenatus))
|
24
|
+
- introduce cli report formatter [\#790](https://github.com/chef/inspec/pull/790) ([arlimus](https://github.com/arlimus))
|
25
|
+
|
26
|
+
## [v0.25.0](https://github.com/chef/inspec/tree/v0.25.0) (2016-06-14)
|
27
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v0.24.0...v0.25.0)
|
5
28
|
|
6
29
|
**Closed issues:**
|
7
30
|
|
data/inspec.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
25
25
|
spec.require_paths = ['lib']
|
26
26
|
|
27
|
-
spec.add_dependency '
|
27
|
+
spec.add_dependency 'train', '~> 0.13'
|
28
28
|
spec.add_dependency 'thor', '~> 0.19'
|
29
29
|
spec.add_dependency 'json', '~> 1.8'
|
30
30
|
spec.add_dependency 'rainbow', '~> 2'
|
data/lib/inspec/cli.rb
CHANGED
@@ -9,6 +9,7 @@ require 'json'
|
|
9
9
|
require 'pp'
|
10
10
|
require 'utils/base_cli'
|
11
11
|
require 'utils/json_log'
|
12
|
+
require 'inspec/runner_mock'
|
12
13
|
|
13
14
|
class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
14
15
|
class_option :diagnose, type: :boolean,
|
@@ -160,7 +161,7 @@ class Inspec::InspecCLI < Inspec::BaseCLI # rubocop:disable Metrics/ClassLength
|
|
160
161
|
private
|
161
162
|
|
162
163
|
def run_command(opts)
|
163
|
-
opts[:test_collector] =
|
164
|
+
opts[:test_collector] = Inspec::RunnerMock.new
|
164
165
|
runner = Inspec::Runner.new(opts)
|
165
166
|
runner.create_context.load(opts[:command])
|
166
167
|
end
|
@@ -73,19 +73,19 @@ end
|
|
73
73
|
|
74
74
|
class InspecRspecJson < InspecRspecMiniJson
|
75
75
|
RSpec::Core::Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :close
|
76
|
+
attr_writer :backend
|
77
|
+
|
78
|
+
def initialize(*args)
|
79
|
+
super(*args)
|
80
|
+
@profiles = []
|
81
|
+
@backend = nil
|
82
|
+
end
|
76
83
|
|
77
84
|
def add_profile(profile)
|
78
|
-
@profiles ||= []
|
79
85
|
@profiles.push(profile)
|
80
86
|
end
|
81
87
|
|
82
|
-
def dump_one_example(example,
|
83
|
-
profile = profiles[example[:profile_id]]
|
84
|
-
return missing.push(example) if profile.nil? || profile[:controls].nil?
|
85
|
-
|
86
|
-
control = profile[:controls][example[:id]]
|
87
|
-
return missing.push(example) if control.nil?
|
88
|
-
|
88
|
+
def dump_one_example(example, control)
|
89
89
|
control[:results] ||= []
|
90
90
|
example.delete(:id)
|
91
91
|
example.delete(:profile_id)
|
@@ -99,13 +99,14 @@ class InspecRspecJson < InspecRspecMiniJson
|
|
99
99
|
|
100
100
|
def dump_summary(summary)
|
101
101
|
super(summary)
|
102
|
-
@profiles ||= []
|
103
102
|
examples = @output_hash.delete(:controls)
|
104
103
|
profiles = Hash[@profiles.map { |x| profile_info(x) }]
|
105
104
|
missing = []
|
106
105
|
|
107
106
|
examples.each do |example|
|
108
|
-
|
107
|
+
control = example2control(example, profiles)
|
108
|
+
next missing.push(example) if control.nil?
|
109
|
+
dump_one_example(example, control)
|
109
110
|
end
|
110
111
|
|
111
112
|
@output_hash[:profiles] = profiles
|
@@ -114,6 +115,12 @@ class InspecRspecJson < InspecRspecMiniJson
|
|
114
115
|
|
115
116
|
private
|
116
117
|
|
118
|
+
def example2control(example, profiles)
|
119
|
+
profile = profiles[example[:profile_id]]
|
120
|
+
return nil if profile.nil? || profile[:controls].nil?
|
121
|
+
profile[:controls][example[:id]]
|
122
|
+
end
|
123
|
+
|
117
124
|
def format_example(example)
|
118
125
|
super(example).tap do |res|
|
119
126
|
res[:run_time] = example.execution_result.run_time
|
@@ -121,3 +128,235 @@ class InspecRspecJson < InspecRspecMiniJson
|
|
121
128
|
end
|
122
129
|
end
|
123
130
|
end
|
131
|
+
|
132
|
+
class InspecRspecCli < InspecRspecJson # rubocop:disable Metrics/ClassLength
|
133
|
+
RSpec::Core::Formatters.register self, :message, :dump_summary, :dump_profile, :stop, :close
|
134
|
+
|
135
|
+
STATUS_TYPES = {
|
136
|
+
'unknown' => -3,
|
137
|
+
'passed' => -2,
|
138
|
+
'skipped' => -1,
|
139
|
+
'minor' => 1,
|
140
|
+
'major' => 2,
|
141
|
+
'failed' => 2.5,
|
142
|
+
'critical' => 3,
|
143
|
+
}.freeze
|
144
|
+
|
145
|
+
COLORS = {
|
146
|
+
'critical' => "\033[31;1m",
|
147
|
+
'major' => "\033[31m",
|
148
|
+
'minor' => "\033[33m",
|
149
|
+
'failed' => "\033[31m",
|
150
|
+
'passed' => "\033[32m",
|
151
|
+
'skipped' => "\033[37m",
|
152
|
+
'reset' => "\033[0m",
|
153
|
+
}.freeze
|
154
|
+
|
155
|
+
INDICATORS = {
|
156
|
+
'critical' => ' ✖ ',
|
157
|
+
'major' => ' ✖ ',
|
158
|
+
'minor' => ' ✖ ',
|
159
|
+
'failed' => ' ✖ ',
|
160
|
+
'skipped' => ' ○ ',
|
161
|
+
'passed' => ' ✔ ',
|
162
|
+
'unknown' => ' ? ',
|
163
|
+
'empty' => ' ',
|
164
|
+
}.freeze
|
165
|
+
|
166
|
+
TEST_INDICATORS = {
|
167
|
+
'failed' => ' fail: ',
|
168
|
+
'skipped' => ' skip: ',
|
169
|
+
'empty' => ' ',
|
170
|
+
}.freeze
|
171
|
+
|
172
|
+
def initialize(*args)
|
173
|
+
@colors = COLORS
|
174
|
+
@indicators = INDICATORS
|
175
|
+
@test_indicators = TEST_INDICATORS
|
176
|
+
|
177
|
+
@format = '%color%indicator%id%summary'
|
178
|
+
@current_control = nil
|
179
|
+
@current_profile = nil
|
180
|
+
@missing_controls = []
|
181
|
+
super(*args)
|
182
|
+
end
|
183
|
+
|
184
|
+
def start(_notification)
|
185
|
+
@profiles_info ||= Hash[@profiles.map { |x| profile_info(x) }]
|
186
|
+
end
|
187
|
+
|
188
|
+
def close(_notification)
|
189
|
+
flush_current_control
|
190
|
+
output.puts('') unless @current_control.nil?
|
191
|
+
|
192
|
+
@profiles_info.each do |_id, profile|
|
193
|
+
next if profile[:already_printed]
|
194
|
+
@current_profile = profile
|
195
|
+
next unless print_current_profile
|
196
|
+
print_line(
|
197
|
+
color: '', indicator: @indicators['empty'], id: '', profile: '',
|
198
|
+
summary: 'No tests executed.'
|
199
|
+
)
|
200
|
+
output.puts('')
|
201
|
+
end
|
202
|
+
|
203
|
+
res = @output_hash[:summary]
|
204
|
+
passed = res[:example_count] - res[:failure_count] - res[:skip_count]
|
205
|
+
s = format('Summary: %3d successful %3d failures %3d skipped',
|
206
|
+
passed, res[:failure_count], res[:skip_count])
|
207
|
+
output.puts(s)
|
208
|
+
end
|
209
|
+
|
210
|
+
private
|
211
|
+
|
212
|
+
def status_type(data, control)
|
213
|
+
status = data[:status]
|
214
|
+
return status if status != 'failed' || control[:impact].nil?
|
215
|
+
if control[:impact] > 0.7
|
216
|
+
'critical'
|
217
|
+
elsif control[:impact] > 0.4
|
218
|
+
'major'
|
219
|
+
elsif control[:impact] > 0.0
|
220
|
+
'minor'
|
221
|
+
else
|
222
|
+
'failed'
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def current_control_infos
|
227
|
+
summary_status = STATUS_TYPES['unknown']
|
228
|
+
skips = []
|
229
|
+
fails = []
|
230
|
+
@current_control[:results].each do |r|
|
231
|
+
i = STATUS_TYPES[r[:status_type]]
|
232
|
+
summary_status = i if i > summary_status
|
233
|
+
fails.push(r) if i > 0
|
234
|
+
skips.push(r) if i == STATUS_TYPES['skipped']
|
235
|
+
end
|
236
|
+
[fails, skips, STATUS_TYPES.key(summary_status)]
|
237
|
+
end
|
238
|
+
|
239
|
+
def current_control_summary(fails, skips)
|
240
|
+
sum_info = [
|
241
|
+
(fails.length > 0) ? "#{fails.length} failed" : nil,
|
242
|
+
(skips.length > 0) ? "#{skips.length} skipped" : nil,
|
243
|
+
].compact
|
244
|
+
|
245
|
+
summary = @current_control[:title]
|
246
|
+
unless summary.nil?
|
247
|
+
return summary + ' (' + sum_info.join(' ') + ')' unless sum_info.empty?
|
248
|
+
return summary
|
249
|
+
end
|
250
|
+
|
251
|
+
return sum_info.join(' ') if @current_control[:results].length != 1
|
252
|
+
|
253
|
+
fails.clear
|
254
|
+
skips.clear
|
255
|
+
c = @current_control[:results][0]
|
256
|
+
c[:code_desc].to_s + c[:message].to_s
|
257
|
+
end
|
258
|
+
|
259
|
+
def format_line(fields)
|
260
|
+
@format.gsub(/%\w+/) do |x|
|
261
|
+
term = x[1..-1]
|
262
|
+
fields.key?(term.to_sym) ? fields[term.to_sym].to_s : x
|
263
|
+
end + @colors['reset']
|
264
|
+
end
|
265
|
+
|
266
|
+
def print_line(fields)
|
267
|
+
output.puts(format_line(fields))
|
268
|
+
end
|
269
|
+
|
270
|
+
def format_lines(lines, indentation)
|
271
|
+
lines.gsub(/\n/, "\n" + indentation)
|
272
|
+
end
|
273
|
+
|
274
|
+
def print_fails_and_skips(all, color)
|
275
|
+
all.each do |x|
|
276
|
+
indicator = @test_indicators[x[:status]]
|
277
|
+
indicator = @test_indicators['empty'] if all.length == 1 || indicator.nil?
|
278
|
+
msg = x[:message] || x[:skip_message] || x[:code_desc]
|
279
|
+
print_line(
|
280
|
+
color: color,
|
281
|
+
indicator: indicator,
|
282
|
+
summary: format_lines(msg, @test_indicators['empty']),
|
283
|
+
id: nil, profile: nil
|
284
|
+
)
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
def flush_current_control
|
289
|
+
return if @current_control.nil?
|
290
|
+
|
291
|
+
prev_profile = @current_profile
|
292
|
+
@current_profile = @profiles_info[@current_control[:profile_id]]
|
293
|
+
print_current_profile if prev_profile != @current_profile
|
294
|
+
|
295
|
+
fails, skips, summary_indicator = current_control_infos
|
296
|
+
summary = current_control_summary(fails, skips)
|
297
|
+
|
298
|
+
control_id = @current_control[:id].to_s
|
299
|
+
control_id += ': '
|
300
|
+
control_id = '' if control_id.start_with? '(generated from '
|
301
|
+
|
302
|
+
print_line(
|
303
|
+
color: @colors[summary_indicator] || '',
|
304
|
+
indicator: @indicators[summary_indicator] || @indicators['unknown'],
|
305
|
+
summary: format_lines(summary, @indicators['empty']),
|
306
|
+
id: control_id,
|
307
|
+
profile: @current_control[:profile_id],
|
308
|
+
)
|
309
|
+
|
310
|
+
print_fails_and_skips(fails + skips, @colors[summary_indicator] || '')
|
311
|
+
end
|
312
|
+
|
313
|
+
def print_target(before, after)
|
314
|
+
return if @backend.nil?
|
315
|
+
connection = @backend.backend
|
316
|
+
return unless connection.respond_to?(:uri)
|
317
|
+
output.puts(before + connection.uri + after)
|
318
|
+
end
|
319
|
+
|
320
|
+
def print_current_profile
|
321
|
+
profile = @current_profile
|
322
|
+
return false if profile.nil?
|
323
|
+
|
324
|
+
output.puts ''
|
325
|
+
profile[:already_printed] = true
|
326
|
+
if profile[:name].nil?
|
327
|
+
print_target('Target: ', "\n\n")
|
328
|
+
return true
|
329
|
+
end
|
330
|
+
|
331
|
+
if profile[:title].nil?
|
332
|
+
output.puts "Profile: #{profile[:name] || 'unknown'}"
|
333
|
+
else
|
334
|
+
output.puts "Profile: #{profile[:title]} (#{profile[:name] || 'unknown'})"
|
335
|
+
end
|
336
|
+
|
337
|
+
output.puts 'Version: ' + (profile[:version] || 'unknown')
|
338
|
+
print_target('Target: ', "\n")
|
339
|
+
output.puts
|
340
|
+
true
|
341
|
+
end
|
342
|
+
|
343
|
+
def format_example(example)
|
344
|
+
data = super(example)
|
345
|
+
control = example2control(data, @profiles_info) || {}
|
346
|
+
control[:id] = data[:id]
|
347
|
+
control[:profile_id] = data[:profile_id]
|
348
|
+
|
349
|
+
data[:status_type] = status_type(data, control)
|
350
|
+
dump_one_example(data, control)
|
351
|
+
|
352
|
+
@current_control ||= control
|
353
|
+
if control[:id].nil?
|
354
|
+
@missing_controls.push(data)
|
355
|
+
elsif @current_control[:id] != control[:id]
|
356
|
+
flush_current_control
|
357
|
+
@current_control = control
|
358
|
+
end
|
359
|
+
|
360
|
+
data
|
361
|
+
end
|
362
|
+
end
|
data/lib/inspec/runner.rb
CHANGED
data/lib/inspec/runner_mock.rb
CHANGED
data/lib/inspec/runner_rspec.rb
CHANGED
@@ -40,6 +40,18 @@ module Inspec
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
+
# Configure the backend of the runner.
|
44
|
+
#
|
45
|
+
# @param [Inspec::Backend] backend
|
46
|
+
# @return [nil]
|
47
|
+
def backend=(backend)
|
48
|
+
RSpec.configuration.formatters
|
49
|
+
.find_all { |c| c.is_a? InspecRspecJson }
|
50
|
+
.each do |fmt|
|
51
|
+
fmt.backend = backend
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
43
55
|
# Add an example group to the list of registered tests.
|
44
56
|
#
|
45
57
|
# @param [RSpecExampleGroup] example test
|
@@ -90,6 +102,7 @@ module Inspec
|
|
90
102
|
'json-min' => 'InspecRspecMiniJson',
|
91
103
|
'json' => 'InspecRspecJson',
|
92
104
|
'json-rspec' => 'InspecRspecVanilla',
|
105
|
+
'cli' => 'InspecRspecCli',
|
93
106
|
}.freeze
|
94
107
|
|
95
108
|
# Configure the output formatter and stream to be used with RSpec.
|
@@ -102,7 +115,7 @@ module Inspec
|
|
102
115
|
RSpec.configuration.output_stream = @conf['output']
|
103
116
|
end
|
104
117
|
|
105
|
-
format = FORMATTERS[@conf['format']] || @conf['format'] || '
|
118
|
+
format = FORMATTERS[@conf['format']] || @conf['format'] || FORMATTERS['cli']
|
106
119
|
@formatter = RSpec.configuration.add_formatter(format)
|
107
120
|
RSpec.configuration.color = @conf['color']
|
108
121
|
|
data/lib/inspec/version.rb
CHANGED
data/lib/matchers/matchers.rb
CHANGED
data/lib/utils/base_cli.rb
CHANGED
@@ -52,7 +52,7 @@ module Inspec
|
|
52
52
|
option :controls, type: :array,
|
53
53
|
desc: 'A list of controls to run. Ignore all other tests.'
|
54
54
|
option :format, type: :string,
|
55
|
-
desc: 'Which formatter to use: progress, documentation, json'
|
55
|
+
desc: 'Which formatter to use: cli, progress, documentation, json, json-min'
|
56
56
|
option :color, type: :boolean, default: true,
|
57
57
|
desc: 'Use colors in output.'
|
58
58
|
option :attrs, type: :array,
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# author: Dominik Richter
|
3
|
+
# author: Christoph Hartmann
|
4
|
+
|
5
|
+
require 'functional/helper'
|
6
|
+
|
7
|
+
describe 'inspec exec' do
|
8
|
+
include FunctionalHelper
|
9
|
+
|
10
|
+
it 'can execute the profile with the mini json formatter' do
|
11
|
+
out = inspec('exec ' + example_profile + ' --format json-min')
|
12
|
+
out.stderr.must_equal ''
|
13
|
+
out.exit_status.must_equal 0
|
14
|
+
JSON.load(out.stdout).must_be_kind_of Hash
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'can execute a simple file with the mini json formatter' do
|
18
|
+
out = inspec('exec ' + example_control + ' --format json-min')
|
19
|
+
out.stderr.must_equal ''
|
20
|
+
out.exit_status.must_equal 0
|
21
|
+
JSON.load(out.stdout).must_be_kind_of Hash
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'execute a profile with mini json formatting' do
|
25
|
+
let(:json) { JSON.load(inspec('exec ' + example_profile + ' --format json-min').stdout) }
|
26
|
+
let(:controls) { json['controls'] }
|
27
|
+
let(:ex1) { controls.find{|x| x['id'] == 'tmp-1.0'} }
|
28
|
+
let(:ex2) { controls.find{|x| x['id'] =~ /generated/} }
|
29
|
+
let(:ex3) { controls.find{|x| x['id'] == 'gordon-1.0'} }
|
30
|
+
|
31
|
+
it 'must have 5 examples' do
|
32
|
+
json['controls'].length.must_equal 5
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'has an id' do
|
36
|
+
controls.find { |ex| !ex.key? 'id' }.must_be :nil?
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'has a profile_id' do
|
40
|
+
controls.find { |ex| !ex.key? 'profile_id' }.must_be :nil?
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'has a code_desc' do
|
44
|
+
ex1['code_desc'].must_equal 'File /tmp should be directory'
|
45
|
+
controls.find { |ex| !ex.key? 'code_desc' }.must_be :nil?
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'has a status' do
|
49
|
+
ex1['status'].must_equal 'passed'
|
50
|
+
ex3['status'].must_equal 'skipped'
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'has a skip_message' do
|
54
|
+
ex1['skip_message'].must_be :nil?
|
55
|
+
ex3['skip_message'].must_equal "Can't find file \"/tmp/gordon/config.yaml\""
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
@@ -11,71 +11,77 @@ describe 'inspec exec' do
|
|
11
11
|
out = inspec('exec ' + example_profile)
|
12
12
|
out.stderr.must_equal ''
|
13
13
|
out.exit_status.must_equal 0
|
14
|
-
out.stdout.
|
15
|
-
|
14
|
+
stdout = out.stdout.force_encoding(Encoding::UTF_8)
|
15
|
+
stdout.must_include "\n\e[32m ✔ ssh-1: Allow only SSH Protocol 2\e[0m\n"
|
16
|
+
stdout.must_include "\n\e[32m ✔ tmp-1.0: Create /tmp directory\e[0m\n"
|
17
|
+
stdout.must_include "
|
18
|
+
\e[37m ○ gordon-1.0: Verify the version number of Gordon (1 skipped)\e[0m
|
19
|
+
\e[37m Can't find file \"/tmp/gordon/config.yaml\"\e[0m
|
20
|
+
"
|
21
|
+
stdout.must_include "\nSummary: 4 successful 0 failures 1 skipped\n"
|
16
22
|
end
|
17
23
|
|
18
|
-
it 'executes only
|
19
|
-
out = inspec('exec ' +
|
24
|
+
it 'executes a minimum metadata-only profile' do
|
25
|
+
out = inspec('exec ' + File.join(profile_path, 'simple-metadata'))
|
20
26
|
out.stderr.must_equal ''
|
21
27
|
out.exit_status.must_equal 0
|
22
|
-
out.stdout.
|
28
|
+
out.stdout.must_equal "
|
29
|
+
Profile: yumyum profile
|
30
|
+
Version: unknown
|
31
|
+
Target: local://
|
32
|
+
|
33
|
+
No tests executed.\e[0m
|
34
|
+
|
35
|
+
Summary: 0 successful 0 failures 0 skipped
|
36
|
+
"
|
23
37
|
end
|
24
38
|
|
25
|
-
it '
|
26
|
-
out = inspec('exec ' +
|
39
|
+
it 'executes a metadata-only profile' do
|
40
|
+
out = inspec('exec ' + File.join(profile_path, 'complete-metadata'))
|
27
41
|
out.stderr.must_equal ''
|
28
42
|
out.exit_status.must_equal 0
|
29
|
-
|
43
|
+
out.stdout.must_equal "
|
44
|
+
Profile: title (name)
|
45
|
+
Version: 1.2.3
|
46
|
+
Target: local://
|
47
|
+
|
48
|
+
No tests executed.\e[0m
|
49
|
+
|
50
|
+
Summary: 0 successful 0 failures 0 skipped
|
51
|
+
"
|
30
52
|
end
|
31
53
|
|
32
|
-
it '
|
33
|
-
out = inspec('exec ' +
|
54
|
+
it 'executes a specs-only profile' do
|
55
|
+
out = inspec('exec ' + File.join(profile_path, 'spec_only'))
|
34
56
|
out.stderr.must_equal ''
|
35
|
-
out.exit_status.must_equal
|
36
|
-
out.stdout.
|
57
|
+
out.exit_status.must_equal 1
|
58
|
+
out.stdout.force_encoding(Encoding::UTF_8).must_equal "
|
59
|
+
Target: local://
|
60
|
+
|
61
|
+
\e[32m ✔ working should eq \"working\"\e[0m
|
62
|
+
\e[37m ○ skippy This will be skipped intentionally.\e[0m
|
63
|
+
\e[31m ✖ failing should eq \"as intended\"
|
64
|
+
expected: \"as intended\"
|
65
|
+
got: \"failing\"
|
66
|
+
\n (compared using ==)
|
67
|
+
\e[0m
|
68
|
+
|
69
|
+
Summary: 1 successful 1 failures 1 skipped
|
70
|
+
"
|
37
71
|
end
|
38
72
|
|
39
|
-
it '
|
40
|
-
out = inspec('exec ' +
|
73
|
+
it 'executes only specified controls' do
|
74
|
+
out = inspec('exec ' + example_profile + ' --controls tmp-1.0')
|
41
75
|
out.stderr.must_equal ''
|
42
76
|
out.exit_status.must_equal 0
|
43
|
-
|
77
|
+
out.stdout.must_include "\nSummary: 1 successful 0 failures 0 skipped\n"
|
44
78
|
end
|
45
79
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
let(:ex3) { controls.find{|x| x['id'] == 'gordon-1.0'} }
|
52
|
-
|
53
|
-
it 'must have 5 examples' do
|
54
|
-
json['controls'].length.must_equal 5
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'has an id' do
|
58
|
-
controls.find { |ex| !ex.key? 'id' }.must_be :nil?
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'has a profile_id' do
|
62
|
-
controls.find { |ex| !ex.key? 'profile_id' }.must_be :nil?
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'has a code_desc' do
|
66
|
-
ex1['code_desc'].must_equal 'File /tmp should be directory'
|
67
|
-
controls.find { |ex| !ex.key? 'code_desc' }.must_be :nil?
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'has a status' do
|
71
|
-
ex1['status'].must_equal 'passed'
|
72
|
-
ex3['status'].must_equal 'skipped'
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'has a skip_message' do
|
76
|
-
ex1['skip_message'].must_be :nil?
|
77
|
-
ex3['skip_message'].must_equal "Can't find file \"/tmp/gordon/config.yaml\""
|
78
|
-
end
|
80
|
+
it 'can execute a simple file with the default formatter' do
|
81
|
+
out = inspec('exec ' + example_control)
|
82
|
+
out.stderr.must_equal ''
|
83
|
+
out.exit_status.must_equal 0
|
84
|
+
out.stdout.must_include 'Summary: 2 successful 0 failures 0 skipped'
|
79
85
|
end
|
80
86
|
|
81
87
|
describe 'with a profile that is not supported on this OS/platform' do
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dominik Richter
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-06-
|
11
|
+
date: 2016-06-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: train
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.13'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.13'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: thor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -404,6 +404,7 @@ files:
|
|
404
404
|
- test/functional/inspec_archive_test.rb
|
405
405
|
- test/functional/inspec_compliance_test.rb
|
406
406
|
- test/functional/inspec_exec_json_test.rb
|
407
|
+
- test/functional/inspec_exec_jsonmin_test.rb
|
407
408
|
- test/functional/inspec_exec_test.rb
|
408
409
|
- test/functional/inspec_json_profile_test.rb
|
409
410
|
- test/functional/inspec_test.rb
|
@@ -567,6 +568,7 @@ files:
|
|
567
568
|
- test/unit/mock/profiles/simple-metadata/inspec.yml
|
568
569
|
- test/unit/mock/profiles/skippy-profile-os/controls/one.rb
|
569
570
|
- test/unit/mock/profiles/skippy-profile-os/inspec.yml
|
571
|
+
- test/unit/mock/profiles/spec_only/specfile.rb
|
570
572
|
- test/unit/mock/profiles/supported_inspec/inspec.yml
|
571
573
|
- test/unit/mock/profiles/unsupported_inspec/inspec.yml
|
572
574
|
- test/unit/objects_test.rb
|
@@ -686,6 +688,7 @@ test_files:
|
|
686
688
|
- test/functional/inspec_archive_test.rb
|
687
689
|
- test/functional/inspec_compliance_test.rb
|
688
690
|
- test/functional/inspec_exec_json_test.rb
|
691
|
+
- test/functional/inspec_exec_jsonmin_test.rb
|
689
692
|
- test/functional/inspec_exec_test.rb
|
690
693
|
- test/functional/inspec_json_profile_test.rb
|
691
694
|
- test/functional/inspec_test.rb
|
@@ -849,6 +852,7 @@ test_files:
|
|
849
852
|
- test/unit/mock/profiles/simple-metadata/inspec.yml
|
850
853
|
- test/unit/mock/profiles/skippy-profile-os/controls/one.rb
|
851
854
|
- test/unit/mock/profiles/skippy-profile-os/inspec.yml
|
855
|
+
- test/unit/mock/profiles/spec_only/specfile.rb
|
852
856
|
- test/unit/mock/profiles/supported_inspec/inspec.yml
|
853
857
|
- test/unit/mock/profiles/unsupported_inspec/inspec.yml
|
854
858
|
- test/unit/objects_test.rb
|