cheffish 0.9.2 → 0.10
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 +4 -4
- data/lib/cheffish/chef_provider_base.rb +3 -0
- data/lib/cheffish/rspec/chef_run_support.rb +106 -0
- data/lib/cheffish/rspec/matchers.rb +67 -0
- data/lib/cheffish/rspec/repository_support.rb +108 -0
- data/lib/cheffish/rspec.rb +0 -0
- data/lib/cheffish/version.rb +1 -1
- data/spec/integration/chef_acl_spec.rb +2 -1
- data/spec/integration/chef_client_spec.rb +2 -1
- data/spec/integration/chef_container_spec.rb +2 -1
- data/spec/integration/chef_group_spec.rb +2 -1
- data/spec/integration/chef_mirror_spec.rb +2 -1
- data/spec/integration/chef_node_spec.rb +2 -1
- data/spec/integration/chef_organization_spec.rb +2 -1
- data/spec/integration/chef_user_spec.rb +2 -1
- data/spec/integration/private_key_spec.rb +2 -1
- data/spec/integration/recipe_dsl_spec.rb +2 -1
- data/spec/support/spec_support.rb +3 -169
- data/spec/unit/get_private_key_spec.rb +1 -0
- metadata +24 -7
- data/spec/support/repository_support.rb +0 -103
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0dd771a02b1ec79cf680acd44dbf8a86bf249ced
|
4
|
+
data.tar.gz: 986a7e74cb9a146bf0b16299a975567e4895d126
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 59571d73a981523e1113cf337ad2d9333e101200f1090b66efefbb8b436b96ae3a6176f08b945786ba66e9db6a5b8e090a6a14082fc4e2f525da57a32a673e6c
|
7
|
+
data.tar.gz: 2d315360a501d2bee824628d4eebb7f24e26b4f9272d79fdc7ca64b3cf6a624930184e094e23d69fbbb3092d165923137d3aba4833bd0ac9616f68ae1e490b49
|
@@ -60,6 +60,9 @@ module Cheffish
|
|
60
60
|
json = resource.raw_json || {}
|
61
61
|
keys.each do |json_key, resource_key|
|
62
62
|
value = resource.send(resource_key)
|
63
|
+
# This takes care of Chef ImmutableMash and ImmutableArray
|
64
|
+
value = value.to_hash if value.is_a?(Hash)
|
65
|
+
value = value.to_a if value.is_a?(Array)
|
63
66
|
json[json_key] = value if value
|
64
67
|
end
|
65
68
|
json
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'chef_zero/rspec'
|
2
|
+
require 'chef/server_api'
|
3
|
+
require 'cheffish/rspec/repository_support'
|
4
|
+
require 'uri'
|
5
|
+
require 'cheffish/basic_chef_client'
|
6
|
+
|
7
|
+
module Cheffish
|
8
|
+
module RSpec
|
9
|
+
module ChefRunSupport
|
10
|
+
include ChefZero::RSpec
|
11
|
+
|
12
|
+
def when_the_chef_12_server(*args, &block)
|
13
|
+
if Gem::Version.new(ChefZero::VERSION) >= Gem::Version.new('3.1')
|
14
|
+
when_the_chef_server(*args, :osc_compat => false, :single_org => false, &block)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.extended(klass)
|
19
|
+
klass.class_eval do
|
20
|
+
extend RepositorySupport
|
21
|
+
|
22
|
+
def rest
|
23
|
+
::Chef::ServerAPI.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def get(path, *args)
|
27
|
+
if path[0] == '/'
|
28
|
+
path = URI.join(rest.url, path)
|
29
|
+
end
|
30
|
+
rest.get(path, *args)
|
31
|
+
end
|
32
|
+
|
33
|
+
def chef_run
|
34
|
+
converge if !@converged
|
35
|
+
event_sink.events
|
36
|
+
end
|
37
|
+
|
38
|
+
def event_sink
|
39
|
+
@event_sink ||= EventSink.new
|
40
|
+
end
|
41
|
+
|
42
|
+
def basic_chef_client
|
43
|
+
@basic_chef_client ||= begin
|
44
|
+
::Cheffish::BasicChefClient.new(nil, event_sink)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def load_recipe(&block)
|
49
|
+
basic_chef_client.load_block(&block)
|
50
|
+
end
|
51
|
+
|
52
|
+
def run_recipe(&block)
|
53
|
+
load_recipe(&block)
|
54
|
+
converge
|
55
|
+
end
|
56
|
+
|
57
|
+
def reset_chef_client
|
58
|
+
@event_sink = nil
|
59
|
+
@basic_chef_client = nil
|
60
|
+
@converged = false
|
61
|
+
end
|
62
|
+
|
63
|
+
def converge
|
64
|
+
if @converged
|
65
|
+
raise "Already converged! Cannot converge twice, that's bad mojo."
|
66
|
+
end
|
67
|
+
@converged = true
|
68
|
+
basic_chef_client.converge
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def with_recipe(&block)
|
74
|
+
before :each do
|
75
|
+
load_recipe(&block)
|
76
|
+
end
|
77
|
+
|
78
|
+
after :each do
|
79
|
+
if !@converged
|
80
|
+
raise "Never tried to converge!"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def with_converge(&block)
|
86
|
+
before :each do
|
87
|
+
load_recipe(&block) if block_given?
|
88
|
+
converge
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class EventSink
|
93
|
+
def initialize
|
94
|
+
@events = []
|
95
|
+
end
|
96
|
+
|
97
|
+
attr_reader :events
|
98
|
+
|
99
|
+
def method_missing(method, *args)
|
100
|
+
@events << [ method, *args ]
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
|
2
|
+
match do |actual|
|
3
|
+
actual_actions = actual.select { |event, resource, action| event == :resource_updated && resource.to_s == resource_name }.map { |event, resource, action| action }
|
4
|
+
expect(actual_actions).to eq(expected_actions)
|
5
|
+
end
|
6
|
+
failure_message do |actual|
|
7
|
+
updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
|
8
|
+
result = "expected that the chef_run would #{expected_actions.join(',')} #{resource_name}."
|
9
|
+
if updates.size > 0
|
10
|
+
result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
|
11
|
+
else
|
12
|
+
result << " Nothing was updated."
|
13
|
+
end
|
14
|
+
result
|
15
|
+
end
|
16
|
+
failure_message_when_negated do |actual|
|
17
|
+
updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
|
18
|
+
result = "expected that the chef_run would not #{expected_actions.join(',')} #{resource_name}."
|
19
|
+
if updates.size > 0
|
20
|
+
result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
|
21
|
+
else
|
22
|
+
result << " Nothing was updated."
|
23
|
+
end
|
24
|
+
result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
RSpec::Matchers.define :update_acls do |acl_paths, expected_acls|
|
29
|
+
|
30
|
+
errors = []
|
31
|
+
|
32
|
+
match do |block|
|
33
|
+
orig_json = {}
|
34
|
+
Array(acl_paths).each do |acl_path|
|
35
|
+
orig_json[acl_path] = get(acl_path)
|
36
|
+
end
|
37
|
+
|
38
|
+
block.call
|
39
|
+
|
40
|
+
orig_json.each_pair do |acl_path, orig|
|
41
|
+
changed = get(acl_path)
|
42
|
+
expected_acls.each do |permission, hash|
|
43
|
+
hash.each do |type, actors|
|
44
|
+
actors.each do |actor|
|
45
|
+
if actor[0] == '-'
|
46
|
+
actor = actor[1..-1]
|
47
|
+
errors << "#{acl_path} expected to remove #{type} #{actor} from #{permission} permissions" if changed[permission][type].include?(actor)
|
48
|
+
orig[permission][type].delete(actor)
|
49
|
+
else
|
50
|
+
errors << "#{acl_path} expected to add #{type} #{actor} to #{permission} permissions" if !changed[permission][type].include?(actor)
|
51
|
+
changed[permission][type].delete(actor)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
# After checking everything, see if the remaining acl is the same as before
|
57
|
+
errors << "#{acl_path} updated more than expected!\nActual:\n#{changed}\nExpected:\n#{orig}" if changed != orig
|
58
|
+
end
|
59
|
+
errors.size == 0
|
60
|
+
end
|
61
|
+
|
62
|
+
failure_message do |block|
|
63
|
+
errors.join("\n")
|
64
|
+
end
|
65
|
+
|
66
|
+
supports_block_expectations
|
67
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
module Cheffish
|
2
|
+
module RSpec
|
3
|
+
module RepositorySupport
|
4
|
+
def when_the_repository(desc, *tags, &block)
|
5
|
+
context("when the chef repo #{desc}", *tags) do
|
6
|
+
include_context "with a chef repo"
|
7
|
+
extend WhenTheRepositoryClassMethods
|
8
|
+
module_eval(&block)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec.shared_context "with a chef repo" do
|
13
|
+
before :each do
|
14
|
+
raise "Can only create one directory per test" if @repository_dir
|
15
|
+
@repository_dir = Dir.mktmpdir('chef_repo')
|
16
|
+
Chef::Config.chef_repo_path = @repository_dir
|
17
|
+
%w(client cookbook data_bag environment node role user).each do |object_name|
|
18
|
+
Chef::Config.delete("#{object_name}_path".to_sym)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
after :each do
|
23
|
+
if @repository_dir
|
24
|
+
begin
|
25
|
+
%w(client cookbook data_bag environment node role user).each do |object_name|
|
26
|
+
Chef::Config.delete("#{object_name}_path".to_sym)
|
27
|
+
end
|
28
|
+
Chef::Config.delete(:chef_repo_path)
|
29
|
+
FileUtils.remove_entry_secure(@repository_dir)
|
30
|
+
ensure
|
31
|
+
@repository_dir = nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
Dir.chdir(@old_cwd) if @old_cwd
|
35
|
+
end
|
36
|
+
|
37
|
+
def directory(relative_path, &block)
|
38
|
+
old_parent_path = @parent_path
|
39
|
+
@parent_path = path_to(relative_path)
|
40
|
+
FileUtils.mkdir_p(@parent_path)
|
41
|
+
instance_eval(&block) if block
|
42
|
+
@parent_path = old_parent_path
|
43
|
+
end
|
44
|
+
|
45
|
+
def file(relative_path, contents)
|
46
|
+
filename = path_to(relative_path)
|
47
|
+
dir = File.dirname(filename)
|
48
|
+
FileUtils.mkdir_p(dir) unless dir == '.'
|
49
|
+
File.open(filename, 'w') do |file|
|
50
|
+
raw = case contents
|
51
|
+
when Hash
|
52
|
+
JSON.pretty_generate(contents)
|
53
|
+
when Array
|
54
|
+
contents.join("\n")
|
55
|
+
else
|
56
|
+
contents
|
57
|
+
end
|
58
|
+
file.write(raw)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def symlink(relative_path, relative_dest)
|
63
|
+
filename = path_to(relative_path)
|
64
|
+
dir = File.dirname(filename)
|
65
|
+
FileUtils.mkdir_p(dir) unless dir == '.'
|
66
|
+
dest_filename = path_to(relative_dest)
|
67
|
+
File.symlink(dest_filename, filename)
|
68
|
+
end
|
69
|
+
|
70
|
+
def path_to(relative_path)
|
71
|
+
File.expand_path(relative_path, (@parent_path || @repository_dir))
|
72
|
+
end
|
73
|
+
|
74
|
+
def cwd(relative_path)
|
75
|
+
@old_cwd = Dir.pwd
|
76
|
+
Dir.chdir(path_to(relative_path))
|
77
|
+
end
|
78
|
+
|
79
|
+
module WhenTheRepositoryClassMethods
|
80
|
+
def directory(*args, &block)
|
81
|
+
before :each do
|
82
|
+
directory(*args, &block)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def file(*args, &block)
|
87
|
+
before :each do
|
88
|
+
file(*args, &block)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def symlink(*args, &block)
|
93
|
+
before :each do
|
94
|
+
symlink(*args, &block)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def path_to(*args, &block)
|
99
|
+
before :each do
|
100
|
+
file(*args, &block)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
File without changes
|
data/lib/cheffish/version.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'chef/resource/chef_acl'
|
3
4
|
require 'chef/provider/chef_acl'
|
4
5
|
require 'chef_zero/version'
|
@@ -6,7 +7,7 @@ require 'uri'
|
|
6
7
|
|
7
8
|
if Gem::Version.new(ChefZero::VERSION) >= Gem::Version.new('3.1')
|
8
9
|
describe Chef::Resource::ChefAcl do
|
9
|
-
extend
|
10
|
+
extend Cheffish::RSpec::ChefRunSupport
|
10
11
|
|
11
12
|
context "Rights attributes" do
|
12
13
|
when_the_chef_server 'has a node named x', :osc_compat => false do
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'support/key_support'
|
3
4
|
require 'chef/resource/chef_client'
|
4
5
|
require 'chef/provider/chef_client'
|
@@ -6,7 +7,7 @@ require 'chef/provider/chef_client'
|
|
6
7
|
repo_path = Dir.mktmpdir('chef_repo')
|
7
8
|
|
8
9
|
describe Chef::Resource::ChefClient do
|
9
|
-
extend
|
10
|
+
extend Cheffish::RSpec::ChefRunSupport
|
10
11
|
|
11
12
|
when_the_chef_12_server 'is in multi-org mode' do
|
12
13
|
organization 'foo'
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'chef/resource/chef_container'
|
3
4
|
require 'chef/provider/chef_container'
|
4
5
|
|
5
6
|
describe Chef::Resource::ChefContainer do
|
6
|
-
extend
|
7
|
+
extend Cheffish::RSpec::ChefRunSupport
|
7
8
|
|
8
9
|
when_the_chef_12_server 'is in multi-org mode' do
|
9
10
|
organization 'foo'
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'chef/resource/chef_group'
|
3
4
|
require 'chef/provider/chef_group'
|
4
5
|
|
5
6
|
describe Chef::Resource::ChefGroup do
|
6
|
-
extend
|
7
|
+
extend Cheffish::RSpec::ChefRunSupport
|
7
8
|
|
8
9
|
when_the_chef_12_server 'is in multi-org mode' do
|
9
10
|
organization 'foo'
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'chef/resource/chef_mirror'
|
3
4
|
require 'chef/provider/chef_mirror'
|
4
5
|
|
5
6
|
describe Chef::Resource::ChefMirror do
|
6
|
-
extend
|
7
|
+
extend Cheffish::RSpec::ChefRunSupport
|
7
8
|
|
8
9
|
when_the_chef_12_server 'is in multi-org mode' do
|
9
10
|
organization 'foo'
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'chef/resource/chef_node'
|
3
4
|
require 'chef/provider/chef_node'
|
4
5
|
|
5
6
|
describe Chef::Resource::ChefNode do
|
6
|
-
extend
|
7
|
+
extend Cheffish::RSpec::ChefRunSupport
|
7
8
|
|
8
9
|
when_the_chef_12_server 'is in multi-org mode' do
|
9
10
|
organization 'foo'
|
@@ -1,9 +1,10 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'chef/resource/chef_organization'
|
3
4
|
require 'chef/provider/chef_organization'
|
4
5
|
|
5
6
|
describe Chef::Resource::ChefOrganization do
|
6
|
-
extend
|
7
|
+
extend Cheffish::RSpec::ChefRunSupport
|
7
8
|
|
8
9
|
when_the_chef_12_server 'is in multi-org mode' do
|
9
10
|
context 'and chef_server_url is pointed at the top level' do
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'support/key_support'
|
3
4
|
require 'chef/resource/chef_user'
|
4
5
|
require 'chef/provider/chef_user'
|
@@ -6,7 +7,7 @@ require 'chef/provider/chef_user'
|
|
6
7
|
repo_path = Dir.mktmpdir('chef_repo')
|
7
8
|
|
8
9
|
describe Chef::Resource::ChefUser do
|
9
|
-
extend
|
10
|
+
extend Cheffish::RSpec::ChefRunSupport
|
10
11
|
|
11
12
|
with_recipe do
|
12
13
|
private_key "#{repo_path}/blah.pem"
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'chef/resource/private_key'
|
3
4
|
require 'chef/provider/private_key'
|
4
5
|
require 'chef/resource/public_key'
|
@@ -8,7 +9,7 @@ require 'support/key_support'
|
|
8
9
|
repo_path = Dir.mktmpdir('chef_repo')
|
9
10
|
|
10
11
|
describe Chef::Resource::PrivateKey do
|
11
|
-
extend
|
12
|
+
extend Cheffish::RSpec::ChefRunSupport
|
12
13
|
|
13
14
|
before :each do
|
14
15
|
FileUtils.remove_entry_secure(repo_path)
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'support/spec_support'
|
2
|
+
require 'cheffish/rspec/chef_run_support'
|
2
3
|
require 'chef/resource/chef_node'
|
3
4
|
require 'chef/provider/chef_node'
|
4
5
|
require 'tmpdir'
|
5
6
|
|
6
7
|
describe 'Cheffish Recipe DSL' do
|
7
|
-
extend
|
8
|
+
extend Cheffish::RSpec::ChefRunSupport
|
8
9
|
|
9
10
|
context 'when we include with_chef_local_server' do
|
10
11
|
before :each do
|
@@ -1,174 +1,8 @@
|
|
1
|
-
|
2
|
-
require 'chef/server_api'
|
1
|
+
|
3
2
|
require 'cheffish'
|
4
|
-
require 'cheffish/basic_chef_client'
|
5
3
|
require 'chef/provider/chef_acl'
|
6
|
-
require '
|
7
|
-
require '
|
8
|
-
|
9
|
-
module SpecSupport
|
10
|
-
include ChefZero::RSpec
|
11
|
-
|
12
|
-
def when_the_chef_12_server(*args, &block)
|
13
|
-
if Gem::Version.new(ChefZero::VERSION) >= Gem::Version.new('3.1')
|
14
|
-
when_the_chef_server(*args, :osc_compat => false, :single_org => false, &block)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def self.extended(klass)
|
19
|
-
klass.class_eval do
|
20
|
-
extend RepositorySupport
|
21
|
-
|
22
|
-
def rest
|
23
|
-
Chef::ServerAPI.new
|
24
|
-
end
|
25
|
-
|
26
|
-
def get(path, *args)
|
27
|
-
if path[0] == '/'
|
28
|
-
path = URI.join(rest.url, path)
|
29
|
-
end
|
30
|
-
rest.get(path, *args)
|
31
|
-
end
|
32
|
-
|
33
|
-
def chef_run
|
34
|
-
converge if !@converged
|
35
|
-
event_sink.events
|
36
|
-
end
|
37
|
-
|
38
|
-
def event_sink
|
39
|
-
@event_sink ||= EventSink.new
|
40
|
-
end
|
41
|
-
|
42
|
-
def basic_chef_client
|
43
|
-
@basic_chef_client ||= begin
|
44
|
-
Cheffish::BasicChefClient.new(nil, event_sink)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def load_recipe(&block)
|
49
|
-
basic_chef_client.load_block(&block)
|
50
|
-
end
|
51
|
-
|
52
|
-
def run_recipe(&block)
|
53
|
-
load_recipe(&block)
|
54
|
-
converge
|
55
|
-
end
|
56
|
-
|
57
|
-
def reset_chef_client
|
58
|
-
@event_sink = nil
|
59
|
-
@basic_chef_client = nil
|
60
|
-
@converged = false
|
61
|
-
end
|
62
|
-
|
63
|
-
def converge
|
64
|
-
if @converged
|
65
|
-
raise "Already converged! Cannot converge twice, that's bad mojo."
|
66
|
-
end
|
67
|
-
@converged = true
|
68
|
-
basic_chef_client.converge
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def with_recipe(&block)
|
74
|
-
before :each do
|
75
|
-
load_recipe(&block)
|
76
|
-
end
|
77
|
-
|
78
|
-
after :each do
|
79
|
-
if !@converged
|
80
|
-
raise "Never tried to converge!"
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
|
85
|
-
def with_converge(&block)
|
86
|
-
before :each do
|
87
|
-
load_recipe(&block) if block_given?
|
88
|
-
converge
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class EventSink
|
93
|
-
def initialize
|
94
|
-
@events = []
|
95
|
-
end
|
96
|
-
|
97
|
-
attr_reader :events
|
98
|
-
|
99
|
-
def method_missing(method, *args)
|
100
|
-
@events << [ method, *args ]
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
|
-
RSpec::Matchers.define :have_updated do |resource_name, *expected_actions|
|
106
|
-
match do |actual|
|
107
|
-
actual_actions = actual.select { |event, resource, action| event == :resource_updated && resource.to_s == resource_name }.map { |event, resource, action| action }
|
108
|
-
expect(actual_actions).to eq(expected_actions)
|
109
|
-
end
|
110
|
-
failure_message do |actual|
|
111
|
-
updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
|
112
|
-
result = "expected that the chef_run would #{expected_actions.join(',')} #{resource_name}."
|
113
|
-
if updates.size > 0
|
114
|
-
result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
|
115
|
-
else
|
116
|
-
result << " Nothing was updated."
|
117
|
-
end
|
118
|
-
result
|
119
|
-
end
|
120
|
-
failure_message_when_negated do |actual|
|
121
|
-
updates = actual.select { |event, resource, action| event == :resource_updated }.to_a
|
122
|
-
result = "expected that the chef_run would not #{expected_actions.join(',')} #{resource_name}."
|
123
|
-
if updates.size > 0
|
124
|
-
result << " Actual updates were #{updates.map { |event, resource, action| "#{resource.to_s} => #{action.inspect}" }.join(', ')}"
|
125
|
-
else
|
126
|
-
result << " Nothing was updated."
|
127
|
-
end
|
128
|
-
result
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
RSpec::Matchers.define :update_acls do |acl_paths, expected_acls|
|
133
|
-
|
134
|
-
errors = []
|
135
|
-
|
136
|
-
match do |block|
|
137
|
-
orig_json = {}
|
138
|
-
Array(acl_paths).each do |acl_path|
|
139
|
-
orig_json[acl_path] = get(acl_path)
|
140
|
-
end
|
141
|
-
|
142
|
-
block.call
|
143
|
-
|
144
|
-
orig_json.each_pair do |acl_path, orig|
|
145
|
-
changed = get(acl_path)
|
146
|
-
expected_acls.each do |permission, hash|
|
147
|
-
hash.each do |type, actors|
|
148
|
-
actors.each do |actor|
|
149
|
-
if actor[0] == '-'
|
150
|
-
actor = actor[1..-1]
|
151
|
-
errors << "#{acl_path} expected to remove #{type} #{actor} from #{permission} permissions" if changed[permission][type].include?(actor)
|
152
|
-
orig[permission][type].delete(actor)
|
153
|
-
else
|
154
|
-
errors << "#{acl_path} expected to add #{type} #{actor} to #{permission} permissions" if !changed[permission][type].include?(actor)
|
155
|
-
changed[permission][type].delete(actor)
|
156
|
-
end
|
157
|
-
end
|
158
|
-
end
|
159
|
-
end
|
160
|
-
# After checking everything, see if the remaining acl is the same as before
|
161
|
-
errors << "#{acl_path} updated more than expected!\nActual:\n#{changed}\nExpected:\n#{orig}" if changed != orig
|
162
|
-
end
|
163
|
-
errors.size == 0
|
164
|
-
end
|
165
|
-
|
166
|
-
failure_message do |block|
|
167
|
-
errors.join("\n")
|
168
|
-
end
|
169
|
-
|
170
|
-
supports_block_expectations
|
171
|
-
end
|
4
|
+
require 'cheffish/rspec/chef_run_support'
|
5
|
+
require 'cheffish/rspec/matchers'
|
172
6
|
|
173
7
|
RSpec.configure do |config|
|
174
8
|
config.filter_run :focus => true
|
metadata
CHANGED
@@ -1,29 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cheffish
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: '0.10'
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Keiser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-03-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: chef-zero
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0'
|
19
|
+
version: '4.0'
|
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: '4.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: chef
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '12.1'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '12.1'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: rake
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -102,6 +116,10 @@ files:
|
|
102
116
|
- lib/cheffish/key_formatter.rb
|
103
117
|
- lib/cheffish/merged_config.rb
|
104
118
|
- lib/cheffish/recipe_dsl.rb
|
119
|
+
- lib/cheffish/rspec.rb
|
120
|
+
- lib/cheffish/rspec/chef_run_support.rb
|
121
|
+
- lib/cheffish/rspec/matchers.rb
|
122
|
+
- lib/cheffish/rspec/repository_support.rb
|
105
123
|
- lib/cheffish/server_api.rb
|
106
124
|
- lib/cheffish/version.rb
|
107
125
|
- lib/cheffish/with_pattern.rb
|
@@ -118,7 +136,6 @@ files:
|
|
118
136
|
- spec/integration/private_key_spec.rb
|
119
137
|
- spec/integration/recipe_dsl_spec.rb
|
120
138
|
- spec/support/key_support.rb
|
121
|
-
- spec/support/repository_support.rb
|
122
139
|
- spec/support/spec_support.rb
|
123
140
|
- spec/unit/get_private_key_spec.rb
|
124
141
|
homepage: http://wiki.opscode.com/display/chef
|
@@ -1,103 +0,0 @@
|
|
1
|
-
module RepositorySupport
|
2
|
-
def when_the_repository(desc, *tags, &block)
|
3
|
-
context("when the chef repo #{desc}", *tags) do
|
4
|
-
include_context "with a chef repo"
|
5
|
-
extend WhenTheRepositoryClassMethods
|
6
|
-
module_eval(&block)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
RSpec.shared_context "with a chef repo" do
|
11
|
-
before :each do
|
12
|
-
raise "Can only create one directory per test" if @repository_dir
|
13
|
-
@repository_dir = Dir.mktmpdir('chef_repo')
|
14
|
-
Chef::Config.chef_repo_path = @repository_dir
|
15
|
-
%w(client cookbook data_bag environment node role user).each do |object_name|
|
16
|
-
Chef::Config.delete("#{object_name}_path".to_sym)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
after :each do
|
21
|
-
if @repository_dir
|
22
|
-
begin
|
23
|
-
%w(client cookbook data_bag environment node role user).each do |object_name|
|
24
|
-
Chef::Config.delete("#{object_name}_path".to_sym)
|
25
|
-
end
|
26
|
-
Chef::Config.delete(:chef_repo_path)
|
27
|
-
FileUtils.remove_entry_secure(@repository_dir)
|
28
|
-
ensure
|
29
|
-
@repository_dir = nil
|
30
|
-
end
|
31
|
-
end
|
32
|
-
Dir.chdir(@old_cwd) if @old_cwd
|
33
|
-
end
|
34
|
-
|
35
|
-
def directory(relative_path, &block)
|
36
|
-
old_parent_path = @parent_path
|
37
|
-
@parent_path = path_to(relative_path)
|
38
|
-
FileUtils.mkdir_p(@parent_path)
|
39
|
-
instance_eval(&block) if block
|
40
|
-
@parent_path = old_parent_path
|
41
|
-
end
|
42
|
-
|
43
|
-
def file(relative_path, contents)
|
44
|
-
filename = path_to(relative_path)
|
45
|
-
dir = File.dirname(filename)
|
46
|
-
FileUtils.mkdir_p(dir) unless dir == '.'
|
47
|
-
File.open(filename, 'w') do |file|
|
48
|
-
raw = case contents
|
49
|
-
when Hash
|
50
|
-
JSON.pretty_generate(contents)
|
51
|
-
when Array
|
52
|
-
contents.join("\n")
|
53
|
-
else
|
54
|
-
contents
|
55
|
-
end
|
56
|
-
file.write(raw)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def symlink(relative_path, relative_dest)
|
61
|
-
filename = path_to(relative_path)
|
62
|
-
dir = File.dirname(filename)
|
63
|
-
FileUtils.mkdir_p(dir) unless dir == '.'
|
64
|
-
dest_filename = path_to(relative_dest)
|
65
|
-
File.symlink(dest_filename, filename)
|
66
|
-
end
|
67
|
-
|
68
|
-
def path_to(relative_path)
|
69
|
-
File.expand_path(relative_path, (@parent_path || @repository_dir))
|
70
|
-
end
|
71
|
-
|
72
|
-
def cwd(relative_path)
|
73
|
-
@old_cwd = Dir.pwd
|
74
|
-
Dir.chdir(path_to(relative_path))
|
75
|
-
end
|
76
|
-
|
77
|
-
module WhenTheRepositoryClassMethods
|
78
|
-
def directory(*args, &block)
|
79
|
-
before :each do
|
80
|
-
directory(*args, &block)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
def file(*args, &block)
|
85
|
-
before :each do
|
86
|
-
file(*args, &block)
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
def symlink(*args, &block)
|
91
|
-
before :each do
|
92
|
-
symlink(*args, &block)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def path_to(*args, &block)
|
97
|
-
before :each do
|
98
|
-
file(*args, &block)
|
99
|
-
end
|
100
|
-
end
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|