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 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