inspec 0.25.0 → 0.26.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ee0308ac7f5c85399e7ad0a3854ff85bbc94d765
4
- data.tar.gz: 85d09ad742b7744f075b8aa8326192d6fc09cc35
3
+ metadata.gz: 24a4519c426bef0955b532d458a7436c172ee78e
4
+ data.tar.gz: 94fa93e202174527e9d40cbf1f174cc37a879492
5
5
  SHA512:
6
- metadata.gz: db34bc62e3bb9789ed7974617814a5249ff4ebc0175e70275b87b398bc2ffc47c63ac665d6ee1ac34059c4041c7a0dc57c1a57b1913a9e2e4893d34ecaf0cad4
7
- data.tar.gz: d7490e64740e145aa8fafeb1d821988d841c7d05542ba1fa73a57f88f171b5bf349c961140c04804344b9edaeecfa5e08609e2b50b033d4e794df6fdf8ba28b0
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.25.0](https://github.com/chef/inspec/tree/0.25.0) (2016-06-14)
4
- [Full Changelog](https://github.com/chef/inspec/compare/v0.24.0...0.25.0)
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 'r-train', '~> 0.12'
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] = 'mock'
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, profiles, missing)
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
- dump_one_example(example, profiles, missing)
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
@@ -48,6 +48,7 @@ module Inspec
48
48
 
49
49
  def configure_transport
50
50
  @backend = Inspec::Backend.create(@conf)
51
+ @test_collector.backend = @backend
51
52
  end
52
53
 
53
54
  # determine all attributes before the execution, fetch data from secrets backend
@@ -5,6 +5,7 @@
5
5
  module Inspec
6
6
  class RunnerMock
7
7
  attr_reader :tests, :profiles
8
+ attr_writer :backend
8
9
  def initialize
9
10
  @tests = []
10
11
  @profiles = []
@@ -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'] || 'progress'
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
 
@@ -3,5 +3,5 @@
3
3
  # author: Christoph Hartmann
4
4
 
5
5
  module Inspec
6
- VERSION = '0.25.0'.freeze
6
+ VERSION = '0.26.0'.freeze
7
7
  end
@@ -232,7 +232,7 @@ end
232
232
  RSpec::Matchers.define :cmp do |first_expected|
233
233
 
234
234
  def integer?(value)
235
- !(value =~ /\A\d+\Z/).nil?
235
+ !(value =~ /\A[1-9]\d*\Z/).nil?
236
236
  end
237
237
 
238
238
  def float?(value)
@@ -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.must_match /^Pending: /
15
- out.stdout.must_include '5 examples, 0 failures, 1 pending'
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 specified controls' do
19
- out = inspec('exec ' + example_profile + ' --controls tmp-1.0')
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.must_include '1 example, 0 failures'
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 'can execute the profile with the mini json formatter' do
26
- out = inspec('exec ' + example_profile + ' --format json-min')
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
- JSON.load(out.stdout).must_be_kind_of Hash
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 'can execute a simple file with the default formatter' do
33
- out = inspec('exec ' + example_control)
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 0
36
- out.stdout.must_include '2 examples, 0 failures'
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 'can execute a simple file with the mini json formatter' do
40
- out = inspec('exec ' + example_control + ' --format json-min')
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
- JSON.load(out.stdout).must_be_kind_of Hash
77
+ out.stdout.must_include "\nSummary: 1 successful 0 failures 0 skipped\n"
44
78
  end
45
79
 
46
- describe 'execute a profile with mini json formatting' do
47
- let(:json) { JSON.load(inspec('exec ' + example_profile + ' --format json-min').stdout) }
48
- let(:controls) { json['controls'] }
49
- let(:ex1) { controls.find{|x| x['id'] == 'tmp-1.0'} }
50
- let(:ex2) { controls.find{|x| x['id'] =~ /generated/} }
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
@@ -71,6 +71,11 @@ if os.linux?
71
71
  it { should_not cmp >= 13 }
72
72
  end
73
73
 
74
+ # Don't compare octal to number
75
+ describe '07' do
76
+ it { should_not cmp 7 }
77
+ end
78
+
74
79
  describe 'some 123' do
75
80
  it { should cmp 'some 123' }
76
81
  it { should cmp /^SOME\s\d+(1|2|3)3/i }
@@ -0,0 +1,11 @@
1
+ describe 'working' do
2
+ it { should eq 'working' }
3
+ end
4
+
5
+ describe 'skippy' do
6
+ skip 'This will be skipped intentionally.'
7
+ end
8
+
9
+ describe 'failing' do
10
+ it { should eq 'as intended' }
11
+ end
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.25.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-14 00:00:00.000000000 Z
11
+ date: 2016-06-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: r-train
14
+ name: train
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '0.12'
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.12'
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