inspec 0.16.3 → 0.16.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,80 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'functional/helper'
6
+
7
+ describe 'inspec archive' do
8
+ include FunctionalHelper
9
+
10
+ it 'archive is successful' do
11
+ out = inspec('archive ' + example_profile + ' --overwrite')
12
+ out.exit_status.must_equal 0
13
+ out.stdout.must_match /Generate archive [^ ]*profile.tar.gz/
14
+ out.stdout.must_include 'Finished archive generation.'
15
+ end
16
+
17
+ it 'archives to output file' do
18
+ out = inspec('archive ' + example_profile + ' --output ' + dst.path)
19
+ out.stderr.must_equal ''
20
+ out.stdout.must_include 'Generate archive '+dst.path
21
+ out.stdout.must_include 'Finished archive generation.'
22
+ out.exit_status.must_equal 0
23
+ File.exist?(dst.path).must_equal true
24
+ end
25
+
26
+ it 'auto-archives when no --output is given' do
27
+ auto_dst = File.join(repo_path, 'profile.tar.gz')
28
+ out = inspec('archive ' + example_profile + ' --overwrite')
29
+ out.stderr.must_equal ''
30
+ out.stdout.must_include 'Generate archive '+auto_dst
31
+ out.stdout.must_include 'Finished archive generation.'
32
+ out.exit_status.must_equal 0
33
+ File.exist?(auto_dst).must_equal true
34
+ end
35
+
36
+ it 'archive on invalid archive' do
37
+ out = inspec('archive /proc --output ' + dst.path)
38
+ # out.stdout.must_equal '' => we have partial stdout output right now
39
+ out.stderr.must_include "Don't understand inspec profile in \"/proc\""
40
+ out.exit_status.must_equal 1
41
+ File.exist?(dst.path).must_equal false
42
+ end
43
+
44
+ it 'archive wont overwrite existing files' do
45
+ x = rand.to_s
46
+ File.write(dst.path, x)
47
+ out = inspec('archive ' + example_profile + ' --output ' + dst.path)
48
+ out.stderr.must_equal '' # uh...
49
+ out.stdout.must_include "Archive #{dst.path} exists already. Use --overwrite."
50
+ out.exit_status.must_equal 1
51
+ File.read(dst.path).must_equal x
52
+ end
53
+
54
+ it 'archive will overwrite files if necessary' do
55
+ x = rand.to_s
56
+ File.write(dst.path, x)
57
+ out = inspec('archive ' + example_profile + ' --output ' + dst.path + ' --overwrite')
58
+ out.stderr.must_equal ''
59
+ out.stdout.must_include 'Generate archive '+dst.path
60
+ out.exit_status.must_equal 0
61
+ File.read(dst.path).wont_equal x
62
+ end
63
+
64
+ it 'creates valid tar.gz archives' do
65
+ out = inspec('archive ' + example_profile + ' --output ' + dst.path + ' --tar')
66
+ out.stderr.must_equal ''
67
+ out.stdout.must_include 'Generate archive '+dst.path
68
+ out.exit_status.must_equal 0
69
+ t = Zlib::GzipReader.open(dst.path)
70
+ Gem::Package::TarReader.new(t).entries.map(&:header).map(&:name).must_include 'inspec.yml'
71
+ end
72
+
73
+ it 'creates valid zip archives' do
74
+ out = inspec('archive ' + example_profile + ' --output ' + dst.path + ' --zip')
75
+ out.stderr.must_equal ''
76
+ out.stdout.must_include 'Generate archive '+dst.path
77
+ out.exit_status.must_equal 0
78
+ Zip::File.new(dst.path).entries.map(&:name).must_include 'inspec.yml'
79
+ end
80
+ end
@@ -0,0 +1,141 @@
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' do
11
+ out = inspec('exec ' + example_profile)
12
+ out.stderr.must_equal ''
13
+ out.exit_status.must_equal 0
14
+ out.stdout.must_match /^Pending: /
15
+ out.stdout.must_include '4 examples, 0 failures, 1 pending'
16
+ end
17
+
18
+ it 'executes only specified controls' do
19
+ out = inspec('exec ' + example_profile + ' --controls tmp-1.0')
20
+ out.stderr.must_equal ''
21
+ out.exit_status.must_equal 0
22
+ out.stdout.must_include '1 example, 0 failures'
23
+ end
24
+
25
+ it 'can execute the profile with the json formatter' do
26
+ out = inspec('exec ' + example_profile + ' --format json')
27
+ out.stderr.must_equal ''
28
+ out.exit_status.must_equal 0
29
+ JSON.load(out.stdout).must_be_kind_of Hash
30
+ end
31
+
32
+ describe 'execute a profile with json formatting' do
33
+ let(:json) { JSON.load(inspec('exec ' + example_profile + ' --format json').stdout) }
34
+ let(:examples) { json['examples'] }
35
+ let(:ex1) { examples.find{|x| x['id'] == 'tmp-1.0'} }
36
+ let(:ex2) { examples.find{|x| x['id'] =~ /generated/} }
37
+ let(:ex3) { examples.find{|x| x['id'] == 'gordon-1.0'} }
38
+
39
+ it 'must have 4 examples' do
40
+ json['examples'].length.must_equal 4
41
+ end
42
+
43
+ it 'id in json' do
44
+ examples.find { |ex| !ex.key? 'id' }.must_be :nil?
45
+ end
46
+
47
+ it 'impact in json' do
48
+ ex1['impact'].must_equal 0.7
49
+ ex2['impact'].must_be :nil?
50
+ end
51
+
52
+ it 'status in json' do
53
+ ex1['status'].must_equal 'passed'
54
+ ex3['status'].must_equal 'pending'
55
+ end
56
+
57
+ it 'pending message in json' do
58
+ ex1['pending_message'].must_be :nil?
59
+ ex3['pending_message'].must_equal 'Not yet implemented'
60
+ end
61
+ end
62
+
63
+ describe 'execute a profile with fulljson formatting' do
64
+ let(:json) { JSON.load(inspec('exec ' + example_profile + ' --format fulljson').stdout) }
65
+ let(:examples) { json['examples'] }
66
+ let(:metadata) { json['profiles'][0] }
67
+ let(:ex1) { examples.find{|x| x['id'] == 'tmp-1.0'} }
68
+ let(:ex2) { examples.find{|x| x['id'] =~ /generated/} }
69
+ let(:ex3) { examples.find{|x| x['id'] == 'gordon-1.0'} }
70
+
71
+ it 'has all the metadata' do
72
+ metadata.must_equal({
73
+ "name" => "profile",
74
+ "title" => "InSpec Example Profile",
75
+ "maintainer" => "Chef Software, Inc.",
76
+ "copyright" => "Chef Software, Inc.",
77
+ "copyright_email" => "support@chef.io",
78
+ "license" => "Apache 2 license",
79
+ "summary" => "Demonstrates the use of InSpec Compliance Profile",
80
+ "version" => "1.0.0",
81
+ "supports" => [{"os-family" => "unix"}]
82
+ })
83
+ end
84
+
85
+ it 'must have 4 examples' do
86
+ json['examples'].length.must_equal 4
87
+ end
88
+
89
+ it 'id in json' do
90
+ examples.find { |ex| !ex.key? 'id' }.must_be :nil?
91
+ end
92
+
93
+ it 'title in json' do
94
+ ex3['title'].must_equal 'Verify the version number of Gordon'
95
+ end
96
+
97
+ it 'desc in json' do
98
+ ex3['desc'].must_equal 'An optional description...'
99
+ end
100
+
101
+ it 'code in json' do
102
+ ex3['code'].wont_be :nil?
103
+ end
104
+
105
+ it 'code_desc in json' do
106
+ ex3['code_desc'].wont_be :nil?
107
+ end
108
+
109
+ it 'impact in json' do
110
+ ex1['impact'].must_equal 0.7
111
+ ex2['impact'].must_be :nil?
112
+ end
113
+
114
+ it 'status in json' do
115
+ ex1['status'].must_equal 'passed'
116
+ ex3['status'].must_equal 'pending'
117
+ end
118
+
119
+ it 'ref in json' do
120
+ ex1['ref'].must_match %r{examples/profile/controls/example.rb$}
121
+ end
122
+
123
+ it 'ref_line in json' do
124
+ ex1['ref_line'].must_equal 14
125
+ end
126
+
127
+ it 'run_time in json' do
128
+ ex1['run_time'].wont_be :nil?
129
+ end
130
+
131
+ it 'start_time in json' do
132
+ ex1['start_time'].wont_be :nil?
133
+ end
134
+
135
+ it 'pending message in json' do
136
+ ex1['pending'].must_be :nil?
137
+ ex3['pending'].must_equal "Can't find file \"/tmp/gordon/config.yaml\""
138
+ end
139
+ end
140
+
141
+ end
@@ -0,0 +1,104 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'functional/helper'
6
+
7
+ describe 'inspec json' do
8
+ include FunctionalHelper
9
+
10
+ it 'read the profile json' do
11
+ out = inspec('json ' + example_profile)
12
+ out.stderr.must_equal ''
13
+ out.exit_status.must_equal 0
14
+ s = out.stdout
15
+ JSON.load(s).must_be_kind_of Hash
16
+ end
17
+
18
+ describe 'json profile data' do
19
+ let(:json) { JSON.load(inspec('json ' + example_profile).stdout) }
20
+
21
+ it 'has a name' do
22
+ json['name'].must_equal 'profile'
23
+ end
24
+
25
+ it 'has a title' do
26
+ json['title'].must_equal 'InSpec Example Profile'
27
+ end
28
+
29
+ it 'has a summary' do
30
+ json['summary'].must_equal 'Demonstrates the use of InSpec Compliance Profile'
31
+ end
32
+
33
+ it 'has a version' do
34
+ json['version'].must_equal '1.0.0'
35
+ end
36
+
37
+ it 'has a maintainer' do
38
+ json['maintainer'].must_equal 'Chef Software, Inc.'
39
+ end
40
+
41
+ it 'has a copyright' do
42
+ json['copyright'].must_equal 'Chef Software, Inc.'
43
+ end
44
+
45
+ it 'has rules' do
46
+ json['rules'].length.must_equal 3 # TODO: flatten out or search deeper!
47
+ end
48
+
49
+ describe 'a rule' do
50
+ let(:rule) { json['rules']['controls/example.rb']['rules']['tmp-1.0'] }
51
+
52
+ it 'has a title' do
53
+ rule['title'].must_equal 'Create /tmp directory'
54
+ end
55
+
56
+ it 'has a description' do
57
+ rule['desc'].must_equal 'An optional description...'
58
+ end
59
+
60
+ it 'has an impact' do
61
+ rule['impact'].must_equal 0.7
62
+ end
63
+
64
+ it 'has a ref' do
65
+ rule['refs'].must_equal([{'ref' => 'Document A-12', 'url' => 'http://...'}])
66
+ end
67
+
68
+ it 'has a source location' do
69
+ loc = File.join(example_profile, '/controls/example.rb')
70
+ rule['source_location'].must_equal [loc, 8]
71
+ end
72
+
73
+ it 'has a the source code' do
74
+ rule['code'].must_match /\Acontrol \"tmp-1.0\" do.*end\n\Z/m
75
+ end
76
+ end
77
+ end
78
+
79
+ describe 'filter with --controls' do
80
+ let(:out) { inspec('json ' + example_profile + ' --controls tmp-1.0') }
81
+
82
+ it 'still succeeds' do
83
+ out.stderr.must_equal ''
84
+ out.exit_status.must_equal 0
85
+ end
86
+
87
+ it 'only has one control included' do
88
+ json = JSON.load(out.stdout)
89
+ grps = json['rules']
90
+ grps.keys.must_equal ['controls/example.rb']
91
+ rules = grps.values[0]['rules']
92
+ rules.keys.must_equal ['tmp-1.0']
93
+ end
94
+ end
95
+
96
+ it 'writes json to file' do
97
+ out = inspec('json ' + example_profile + ' --output ' + dst.path)
98
+ out.stderr.must_equal ''
99
+ out.exit_status.must_equal 0
100
+ hm = JSON.load(File.read(dst.path))
101
+ hm['name'].must_equal 'profile'
102
+ hm['rules'].length.must_equal 3 # TODO: flatten out or search deeper!
103
+ end
104
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ # author: Dominik Richter
3
+ # author: Christoph Hartmann
4
+
5
+ require 'functional/helper'
6
+
7
+ describe 'command tests' do
8
+ include FunctionalHelper
9
+
10
+ describe 'detect' do
11
+ it 'runs well on all nodes' do
12
+ out = inspec('detect')
13
+ out.stderr.must_equal ''
14
+ out.exit_status.must_equal 0
15
+ j = JSON.load(out.stdout)
16
+ j.keys.must_include 'name'
17
+ j.keys.must_include 'family'
18
+ j.keys.must_include 'arch'
19
+ j.keys.must_include 'release'
20
+ end
21
+ end
22
+
23
+ describe 'version' do
24
+ it 'provides the version number on stdout' do
25
+ out = inspec('version')
26
+ out.stderr.must_equal ''
27
+ out.exit_status.must_equal 0
28
+ out.stdout.must_equal Inspec::VERSION+"\n"
29
+ end
30
+ end
31
+
32
+ describe 'shell' do
33
+ it 'provides a help command' do
34
+ out = CMD.run_command("echo \"help\nexit\" | #{exec_inspec} shell")
35
+ out.exit_status.must_equal 0
36
+ out.stdout.must_include 'Available commands:'
37
+ out.stdout.must_include 'You are currently running on:'
38
+ end
39
+
40
+ it 'exposes all resources' do
41
+ out = CMD.run_command("echo \"os\nexit\" | #{exec_inspec} shell")
42
+ out.exit_status.must_equal 0
43
+ out.stdout.must_match /^=> .*Operating.* .*System.* .*Detection.*$/
44
+ end
45
+ end
46
+
47
+ describe 'check' do
48
+ it 'verifies that a profile is ok' do
49
+ out = inspec('check ' + example_profile)
50
+ out.stdout.must_match /Valid.*true/
51
+ out.exit_status.must_equal 0
52
+ end
53
+ end
54
+ end
@@ -91,7 +91,7 @@ describe Inspec::ProfileContext do
91
91
  it 'supports empty describe calls' do
92
92
  load('describe').must_output ''
93
93
  profile.rules.keys.length.must_equal 1
94
- profile.rules.keys[0].must_match /^\(generated from unknown:1 [0-9a-f]+\)$/
94
+ profile.rules.keys[0].must_match /^\(generated from \(eval\):1 [0-9a-f]+\)$/
95
95
  profile.rules.values[0].must_be_kind_of Inspec::Rule
96
96
  end
97
97
 
@@ -99,7 +99,7 @@ describe Inspec::ProfileContext do
99
99
  load('describe true do; it { should_eq true }; end')
100
100
  .must_output ''
101
101
  profile.rules.keys.length.must_equal 1
102
- profile.rules.keys[0].must_match /^\(generated from unknown:1 [0-9a-f]+\)$/
102
+ profile.rules.keys[0].must_match /^\(generated from \(eval\):1 [0-9a-f]+\)$/
103
103
  profile.rules.values[0].must_be_kind_of Inspec::Rule
104
104
  end
105
105
 
@@ -108,7 +108,7 @@ describe Inspec::ProfileContext do
108
108
  .must_output ''
109
109
  profile.rules.keys.length.must_equal 3
110
110
  [0, 1, 2].each do |i|
111
- profile.rules.keys[i].must_match /^\(generated from unknown:2 [0-9a-f]+\)$/
111
+ profile.rules.keys[i].must_match /^\(generated from \(eval\):2 [0-9a-f]+\)$/
112
112
  profile.rules.values[i].must_be_kind_of Inspec::Rule
113
113
  end
114
114
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.16.3
4
+ version: 0.16.4
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-03-23 00:00:00.000000000 Z
11
+ date: 2016-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: r-train
@@ -208,11 +208,9 @@ files:
208
208
  - examples/profile/README.md
209
209
  - examples/profile/controls/example.rb
210
210
  - examples/profile/controls/gordon.rb
211
+ - examples/profile/controls/meta.rb
211
212
  - examples/profile/inspec.yml
212
213
  - examples/profile/libraries/gordon_config.rb
213
- - examples/resource/controls/tiny.rb
214
- - examples/resource/inspec.yml
215
- - examples/resource/libraries/tiny.rb
216
214
  - inspec.gemspec
217
215
  - lib/bundles/README.md
218
216
  - lib/bundles/inspec-compliance.rb
@@ -360,7 +358,12 @@ files:
360
358
  - test/cookbooks/os_prepare/templates/default/sv-default-svlog-run.erb
361
359
  - test/docker_run.rb
362
360
  - test/docker_test.rb
363
- - test/functional/command_test.rb
361
+ - test/functional/helper.rb
362
+ - test/functional/inheritance_test.rb
363
+ - test/functional/inspec_archive_test.rb
364
+ - test/functional/inspec_exec_test.rb
365
+ - test/functional/inspec_json_test.rb
366
+ - test/functional/inspec_test.rb
364
367
  - test/helper.rb
365
368
  - test/integration/default/_debug_spec.rb
366
369
  - test/integration/default/apache_conf_spec.rb
@@ -617,7 +620,12 @@ test_files:
617
620
  - test/cookbooks/os_prepare/templates/default/sv-default-svlog-run.erb
618
621
  - test/docker_run.rb
619
622
  - test/docker_test.rb
620
- - test/functional/command_test.rb
623
+ - test/functional/helper.rb
624
+ - test/functional/inheritance_test.rb
625
+ - test/functional/inspec_archive_test.rb
626
+ - test/functional/inspec_exec_test.rb
627
+ - test/functional/inspec_json_test.rb
628
+ - test/functional/inspec_test.rb
621
629
  - test/helper.rb
622
630
  - test/integration/default/_debug_spec.rb
623
631
  - test/integration/default/apache_conf_spec.rb