chef 12.14.89-universal-mingw32 → 12.15.19-universal-mingw32
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/CONTRIBUTING.md +76 -51
- data/Gemfile +1 -1
- data/README.md +9 -7
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/acceptance/Gemfile +3 -0
- data/acceptance/Gemfile.lock +19 -18
- data/acceptance/fips/.kitchen.yml +1 -1
- data/lib/chef/application/exit_code.rb +9 -0
- data/lib/chef/cookbook/file_system_file_vendor.rb +7 -8
- data/lib/chef/cookbook/metadata.rb +8 -0
- data/lib/chef/exceptions.rb +5 -0
- data/lib/chef/knife.rb +14 -15
- data/lib/chef/knife/ssh.rb +1 -0
- data/lib/chef/node/attribute.rb +1 -3
- data/lib/chef/node/attribute_collections.rb +20 -0
- data/lib/chef/provider/apt_repository.rb +1 -1
- data/lib/chef/provider/apt_update.rb +1 -1
- data/lib/chef/provider/group/groupadd.rb +2 -1
- data/lib/chef/provider/package/cab.rb +150 -0
- data/lib/chef/provider/package/rubygems.rb +0 -1
- data/lib/chef/provider/registry_key.rb +26 -2
- data/lib/chef/provider/remote_file/content.rb +1 -1
- data/lib/chef/provider/user.rb +10 -0
- data/lib/chef/provider/user/dscl.rb +2 -2
- data/lib/chef/provider/user/linux.rb +4 -14
- data/lib/chef/provider/user/pw.rb +2 -2
- data/lib/chef/provider/user/solaris.rb +15 -0
- data/lib/chef/provider/user/useradd.rb +1 -5
- data/lib/chef/providers.rb +1 -0
- data/lib/chef/resource/cab_package.rb +44 -0
- data/lib/chef/resource/registry_key.rb +3 -3
- data/lib/chef/resource/yum_repository.rb +1 -1
- data/lib/chef/resources.rb +1 -0
- data/lib/chef/server_api.rb +1 -1
- data/lib/chef/util/dsc/local_configuration_manager.rb +1 -1
- data/lib/chef/version.rb +1 -1
- data/spec/data/templates/chef-seattle20160930-4388-1crv7ef.txt +1 -0
- data/spec/data/templates/chef-seattle20160930-4388-jjfoae.txt +1 -0
- data/spec/data/templates/chef-seattle20160930-4388-umeq2c.txt +1 -0
- data/spec/functional/knife/cookbook_delete_spec.rb +48 -59
- data/spec/functional/resource/ifconfig_spec.rb +6 -0
- data/spec/functional/resource/registry_spec.rb +110 -4
- data/spec/unit/application/exit_code_spec.rb +10 -0
- data/spec/unit/cookbook/file_vendor_spec.rb +15 -0
- data/spec/unit/cookbook/metadata_spec.rb +19 -0
- data/spec/unit/exceptions_spec.rb +2 -0
- data/spec/unit/node/attribute_spec.rb +23 -1
- data/spec/unit/node/vivid_mash_spec.rb +27 -0
- data/spec/unit/provider/group/groupadd_spec.rb +118 -99
- data/spec/unit/provider/package/cab_spec.rb +218 -0
- data/spec/unit/provider/package/rubygems_spec.rb +2 -4
- data/spec/unit/provider/registry_key_spec.rb +94 -0
- data/spec/unit/provider/remote_file/content_spec.rb +1 -0
- data/spec/unit/provider/user/solaris_spec.rb +52 -40
- data/spec/unit/resource/apt_update_spec.rb +25 -17
- data/spec/unit/resource/cab_package_spec.rb +38 -0
- data/spec/unit/resource/registry_key_spec.rb +26 -10
- data/spec/unit/server_api_spec.rb +50 -0
- data/spec/unit/util/dsc/local_configuration_manager_spec.rb +10 -4
- metadata +13 -5
@@ -64,6 +64,10 @@ describe Chef::Application::ExitCode do
|
|
64
64
|
it "validates a REBOOT_FAILED return code of 41" do
|
65
65
|
expect(valid_rfc_exit_codes.include?(41)).to eq(true)
|
66
66
|
end
|
67
|
+
|
68
|
+
it "validates a CLIENT_UPGRADED return code of 213" do
|
69
|
+
expect(valid_rfc_exit_codes.include?(213)).to eq(true)
|
70
|
+
end
|
67
71
|
end
|
68
72
|
|
69
73
|
context "when Chef::Config :exit_status is not configured" do
|
@@ -215,6 +219,12 @@ describe Chef::Application::ExitCode do
|
|
215
219
|
expect(exit_codes.normalize_exit_code(runtime_error)).to eq(37)
|
216
220
|
end
|
217
221
|
|
222
|
+
it "returns CLIENT_UPGRADED when the client was upgraded during converge" do
|
223
|
+
client_upgraded_error = Chef::Exceptions::ClientUpgraded.new("BOOM")
|
224
|
+
runtime_error = Chef::Exceptions::RunFailedWrappingError.new(client_upgraded_error)
|
225
|
+
expect(exit_codes.normalize_exit_code(runtime_error)).to eq(213)
|
226
|
+
end
|
227
|
+
|
218
228
|
it "returns SIGINT_RECEIVED when a SIGINT is received." do
|
219
229
|
sigint_error = Chef::Exceptions::SigInt.new("BOOM")
|
220
230
|
runtime_error = Chef::Exceptions::RunFailedWrappingError.new(sigint_error)
|
@@ -94,4 +94,19 @@ describe Chef::Cookbook::FileVendor do
|
|
94
94
|
|
95
95
|
end
|
96
96
|
|
97
|
+
context "when vendoring a cookbook with a name mismatch" do
|
98
|
+
let(:cookbook_path) { File.join(CHEF_SPEC_DATA, "cookbooks") }
|
99
|
+
|
100
|
+
# A manifest is a Hash of the format defined by Chef::CookbookVersion#manifest
|
101
|
+
let(:manifest) { { :cookbook_name => "name-mismatch" } }
|
102
|
+
|
103
|
+
before do
|
104
|
+
file_vendor_class.fetch_from_disk(cookbook_path)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "retrieves the file from the correct location based on path to the cookbook that conatins the correct name metadata" do
|
108
|
+
file_vendor = file_vendor_class.create_from_manifest(manifest)
|
109
|
+
file_vendor.get_filename("metadata.rb")
|
110
|
+
end
|
111
|
+
end
|
97
112
|
end
|
@@ -948,5 +948,24 @@ describe Chef::Cookbook::Metadata do
|
|
948
948
|
end
|
949
949
|
end
|
950
950
|
|
951
|
+
describe "from_file" do
|
952
|
+
it "ignores unknown metadata fields in metadata.rb files" do
|
953
|
+
expect(Chef::Log).to receive(:debug).with(/ignoring method some_spiffy_new_metadata_field/)
|
954
|
+
Tempfile.open("metadata.rb") do |f|
|
955
|
+
f.write <<-EOF
|
956
|
+
some_spiffy_new_metadata_field "stuff its set to"
|
957
|
+
EOF
|
958
|
+
f.close
|
959
|
+
metadata.from_file(f.path)
|
960
|
+
end
|
961
|
+
end
|
962
|
+
end
|
963
|
+
|
964
|
+
describe "from_json" do
|
965
|
+
it "ignores unknown metadata fields in metdata.json files" do
|
966
|
+
json = %q{{ "some_spiffy_new_metadata_field": "stuff its set to" }}
|
967
|
+
metadata.from_json(json)
|
968
|
+
end
|
969
|
+
end
|
951
970
|
end
|
952
971
|
end
|
@@ -68,6 +68,8 @@ describe Chef::Exceptions do
|
|
68
68
|
Chef::Exceptions::EnvironmentNotFound => RuntimeError,
|
69
69
|
Chef::Exceptions::InvalidVersionConstraint => ArgumentError,
|
70
70
|
Chef::Exceptions::IllegalVersionConstraint => NotImplementedError,
|
71
|
+
Chef::Exceptions::RegKeyValuesTypeMissing => ArgumentError,
|
72
|
+
Chef::Exceptions::RegKeyValuesDataMissing => ArgumentError,
|
71
73
|
}
|
72
74
|
|
73
75
|
exception_to_super_class.each do |exception, expected_super_class|
|
@@ -1171,7 +1171,29 @@ describe Chef::Node::Attribute do
|
|
1171
1171
|
Chef::Config[:treat_deprecation_warnings_as_errors] = false
|
1172
1172
|
expect { @attributes.new_key = "new value" }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
|
1173
1173
|
end
|
1174
|
-
|
1175
1174
|
end
|
1176
1175
|
|
1176
|
+
describe "deeply converting values" do
|
1177
|
+
it "converts values through an array" do
|
1178
|
+
@attributes.default[:foo] = [ { bar: true } ]
|
1179
|
+
expect(@attributes["foo"].class).to eql(Chef::Node::ImmutableArray)
|
1180
|
+
expect(@attributes["foo"][0].class).to eql(Chef::Node::ImmutableMash)
|
1181
|
+
expect(@attributes["foo"][0]["bar"]).to be true
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
it "converts values through nested arrays" do
|
1185
|
+
@attributes.default[:foo] = [ [ { bar: true } ] ]
|
1186
|
+
expect(@attributes["foo"].class).to eql(Chef::Node::ImmutableArray)
|
1187
|
+
expect(@attributes["foo"][0].class).to eql(Chef::Node::ImmutableArray)
|
1188
|
+
expect(@attributes["foo"][0][0].class).to eql(Chef::Node::ImmutableMash)
|
1189
|
+
expect(@attributes["foo"][0][0]["bar"]).to be true
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
it "converts values through nested hashes" do
|
1193
|
+
@attributes.default[:foo] = { baz: { bar: true } }
|
1194
|
+
expect(@attributes["foo"].class).to eql(Chef::Node::ImmutableMash)
|
1195
|
+
expect(@attributes["foo"]["baz"].class).to eql(Chef::Node::ImmutableMash)
|
1196
|
+
expect(@attributes["foo"]["baz"]["bar"]).to be true
|
1197
|
+
end
|
1198
|
+
end
|
1177
1199
|
end
|
@@ -37,6 +37,33 @@ describe Chef::Node::VividMash do
|
|
37
37
|
expect(root).to receive(:top_level_breadcrumb=).with(key).at_least(:once).and_call_original
|
38
38
|
end
|
39
39
|
|
40
|
+
context "#[]=" do
|
41
|
+
it "deep converts values through arrays" do
|
42
|
+
allow(root).to receive(:reset_cache)
|
43
|
+
vivid[:foo] = [ { :bar => true } ]
|
44
|
+
expect(vivid["foo"].class).to eql(Chef::Node::AttrArray)
|
45
|
+
expect(vivid["foo"][0].class).to eql(Chef::Node::VividMash)
|
46
|
+
expect(vivid["foo"][0]["bar"]).to be true
|
47
|
+
end
|
48
|
+
|
49
|
+
it "deep converts values through nested arrays" do
|
50
|
+
allow(root).to receive(:reset_cache)
|
51
|
+
vivid[:foo] = [ [ { :bar => true } ] ]
|
52
|
+
expect(vivid["foo"].class).to eql(Chef::Node::AttrArray)
|
53
|
+
expect(vivid["foo"][0].class).to eql(Chef::Node::AttrArray)
|
54
|
+
expect(vivid["foo"][0][0].class).to eql(Chef::Node::VividMash)
|
55
|
+
expect(vivid["foo"][0][0]["bar"]).to be true
|
56
|
+
end
|
57
|
+
|
58
|
+
it "deep converts values through hashes" do
|
59
|
+
allow(root).to receive(:reset_cache)
|
60
|
+
vivid[:foo] = { baz: { :bar => true } }
|
61
|
+
expect(vivid["foo"]).to be_an_instance_of(Chef::Node::VividMash)
|
62
|
+
expect(vivid["foo"]["baz"]).to be_an_instance_of(Chef::Node::VividMash)
|
63
|
+
expect(vivid["foo"]["baz"]["bar"]).to be true
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
40
67
|
context "#read" do
|
41
68
|
before do
|
42
69
|
# vivify the vividmash, then we're read-only so the cache should never be cleared afterwards
|
@@ -18,156 +18,175 @@
|
|
18
18
|
|
19
19
|
require "spec_helper"
|
20
20
|
|
21
|
-
describe Chef::Provider::Group::Groupadd
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
@current_resource = Chef::Resource::Group.new("aj")
|
32
|
-
@current_resource.gid(50)
|
33
|
-
@current_resource.members(%w{root aj})
|
34
|
-
@current_resource.system false
|
35
|
-
@current_resource.non_unique false
|
36
|
-
@provider = Chef::Provider::Group::Groupadd.new(@new_resource, @run_context)
|
37
|
-
@provider.current_resource = @current_resource
|
38
|
-
end
|
39
|
-
|
40
|
-
field_list = {
|
41
|
-
:gid => "-g",
|
42
|
-
}
|
43
|
-
|
44
|
-
field_list.each do |attribute, option|
|
45
|
-
it "should check for differences in #{attribute} between the current and new resources" do
|
46
|
-
expect(@new_resource).to receive(attribute)
|
47
|
-
expect(@current_resource).to receive(attribute)
|
48
|
-
@provider.set_options
|
21
|
+
describe Chef::Provider::Group::Groupadd do
|
22
|
+
let(:node) { Chef::Node.new }
|
23
|
+
let(:events) { Chef::EventDispatch::Dispatcher.new }
|
24
|
+
let(:run_context) { Chef::RunContext.new(node, {}, events) }
|
25
|
+
let(:new_resource) do
|
26
|
+
Chef::Resource::Group.new("aj").tap do |r|
|
27
|
+
r.gid 50
|
28
|
+
r.members %w{root aj}
|
29
|
+
r.system false
|
30
|
+
r.non_unique false
|
49
31
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
32
|
+
end
|
33
|
+
let(:current_resource) do
|
34
|
+
Chef::Resource::Group.new("aj").tap do |r|
|
35
|
+
r.gid 50
|
36
|
+
r.members %w{root aj}
|
37
|
+
r.system false
|
38
|
+
r.non_unique false
|
53
39
|
end
|
54
40
|
end
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
field_list.sort { |a, b| a[0] <=> b[0] }.each do |attribute, option|
|
59
|
-
allow(@new_resource).to receive(attribute).and_return("hola")
|
60
|
-
match_string << " #{option} 'hola'"
|
41
|
+
let(:provider) do
|
42
|
+
described_class.new(new_resource, run_context).tap do |p|
|
43
|
+
p.current_resource = current_resource
|
61
44
|
end
|
62
|
-
match_string << " aj"
|
63
|
-
expect(@provider.set_options).to eql(match_string)
|
64
45
|
end
|
65
46
|
|
66
|
-
describe "
|
67
|
-
|
68
|
-
|
69
|
-
|
47
|
+
describe "#set_options" do
|
48
|
+
field_list = {
|
49
|
+
:gid => "-g",
|
50
|
+
}
|
51
|
+
|
52
|
+
field_list.each do |attribute, option|
|
53
|
+
it "should check for differences in #{attribute} between the current and new resources" do
|
54
|
+
expect(new_resource).to receive(attribute)
|
55
|
+
expect(current_resource).to receive(attribute)
|
56
|
+
provider.set_options
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should set the option for #{attribute} if the new resources #{attribute} is not null" do
|
60
|
+
allow(new_resource).to receive(attribute).and_return("wowaweea")
|
61
|
+
expect(provider.set_options).to eql(" #{option} '#{new_resource.send(attribute)}' #{new_resource.group_name}")
|
62
|
+
end
|
70
63
|
end
|
71
64
|
|
72
|
-
it "should
|
73
|
-
|
74
|
-
|
65
|
+
it "should combine all the possible options" do
|
66
|
+
match_string = ""
|
67
|
+
field_list.sort { |a, b| a[0] <=> b[0] }.each do |attribute, option|
|
68
|
+
allow(new_resource).to receive(attribute).and_return("hola")
|
69
|
+
match_string << " #{option} 'hola'"
|
70
|
+
end
|
71
|
+
match_string << " aj"
|
72
|
+
expect(provider.set_options).to eql(match_string)
|
75
73
|
end
|
76
|
-
end
|
77
74
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
75
|
+
describe "when we want to create a system group" do
|
76
|
+
it "should not set groupadd_options '-r' when system is false" do
|
77
|
+
new_resource.system(false)
|
78
|
+
expect(provider.groupadd_options).not_to match(/-r/)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should set groupadd -r if system is true" do
|
82
|
+
new_resource.system(true)
|
83
|
+
expect(provider.groupadd_options).to eq(" -r")
|
84
|
+
end
|
85
|
+
|
86
|
+
context "on Solaris" do
|
87
|
+
before { node.automatic["platform"] = "solaris2" }
|
88
|
+
it "should not set groupadd -r if system is true" do
|
89
|
+
new_resource.system(true)
|
90
|
+
expect(provider.groupadd_options).not_to match(/-r/)
|
91
|
+
end
|
92
|
+
end
|
82
93
|
end
|
83
94
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
end
|
95
|
+
describe "when we want to create a non_unique gid group" do
|
96
|
+
it "should not set groupadd_options '-o' when non_unique is false" do
|
97
|
+
new_resource.non_unique(false)
|
98
|
+
expect(provider.groupadd_options).not_to match(/-o/)
|
99
|
+
end
|
90
100
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
allow(@provider).to receive(:run_command).and_return(true)
|
97
|
-
allow(@provider).to receive(:set_options).and_return(" monkey")
|
98
|
-
allow(@provider).to receive(:groupadd_options).and_return("")
|
99
|
-
allow(@provider).to receive(:modify_group_members).and_return(true)
|
101
|
+
it "should set groupadd -o if non_unique is true" do
|
102
|
+
new_resource.non_unique(true)
|
103
|
+
expect(provider.groupadd_options).to eq(" -o")
|
104
|
+
end
|
105
|
+
end
|
100
106
|
end
|
101
107
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
108
|
+
describe "#create_group" do
|
109
|
+
before do
|
110
|
+
allow(provider).to receive(:run_command).and_return(true)
|
111
|
+
allow(provider).to receive(:set_options).and_return(" monkey")
|
112
|
+
allow(provider).to receive(:groupadd_options).and_return("")
|
113
|
+
allow(provider).to receive(:modify_group_members).and_return(true)
|
114
|
+
end
|
106
115
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
end
|
116
|
+
it "should run groupadd with the return of set_options" do
|
117
|
+
expect(provider).to receive(:run_command).with({ :command => "groupadd monkey" }).and_return(true)
|
118
|
+
provider.create_group
|
119
|
+
end
|
112
120
|
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
@run_context = Chef::RunContext.new(@node, {}, @events)
|
118
|
-
@new_resource = Chef::Resource::Group.new("aj")
|
119
|
-
@provider = Chef::Provider::Group::Groupadd.new(@new_resource, @run_context)
|
120
|
-
allow(@provider).to receive(:run_command).and_return(true)
|
121
|
-
allow(@provider).to receive(:set_options).and_return(" monkey")
|
121
|
+
it "should modify the group members" do
|
122
|
+
expect(provider).to receive(:modify_group_members).and_return(true)
|
123
|
+
provider.create_group
|
124
|
+
end
|
122
125
|
end
|
123
126
|
|
124
|
-
describe "
|
127
|
+
describe "#manage_group" do
|
128
|
+
before do
|
129
|
+
allow(provider).to receive(:run_command).and_return(true)
|
130
|
+
allow(provider).to receive(:set_options).and_return(" monkey")
|
131
|
+
end
|
125
132
|
|
126
133
|
it "should run groupmod with the return of set_options" do
|
127
|
-
allow(
|
128
|
-
expect(
|
129
|
-
|
134
|
+
allow(provider).to receive(:modify_group_members).and_return(true)
|
135
|
+
expect(provider).to receive(:run_command).with({ :command => "groupmod monkey" }).and_return(true)
|
136
|
+
provider.manage_group
|
130
137
|
end
|
131
138
|
|
132
139
|
it "should modify the group members" do
|
133
|
-
expect(
|
134
|
-
|
140
|
+
expect(provider).to receive(:modify_group_members).and_return(true)
|
141
|
+
provider.manage_group
|
135
142
|
end
|
136
143
|
end
|
137
144
|
|
138
|
-
describe "remove_group" do
|
145
|
+
describe "#remove_group" do
|
146
|
+
before do
|
147
|
+
allow(provider).to receive(:run_command).and_return(true)
|
148
|
+
allow(provider).to receive(:set_options).and_return(" monkey")
|
149
|
+
end
|
139
150
|
|
140
151
|
it "should run groupdel with the new resources group name" do
|
141
|
-
expect(
|
142
|
-
|
152
|
+
expect(provider).to receive(:run_command).with({ :command => "groupdel aj" }).and_return(true)
|
153
|
+
provider.remove_group
|
143
154
|
end
|
144
155
|
end
|
145
156
|
|
146
157
|
[:add_member, :remove_member, :set_members].each do |m|
|
147
158
|
it "should raise an error when calling #{m}" do
|
148
|
-
expect {
|
159
|
+
expect { provider.send(m, [ ]) }.to raise_error(Chef::Exceptions::Group, "you must override #{m} in #{provider}")
|
149
160
|
end
|
150
161
|
end
|
151
162
|
|
152
|
-
describe "load_current_resource" do
|
163
|
+
describe "#load_current_resource" do
|
164
|
+
before do
|
165
|
+
allow(provider).to receive(:run_command).and_return(true)
|
166
|
+
allow(provider).to receive(:set_options).and_return(" monkey")
|
167
|
+
end
|
168
|
+
|
153
169
|
before do
|
154
170
|
allow(File).to receive(:exists?).and_return(false)
|
155
|
-
|
171
|
+
provider.define_resource_requirements
|
156
172
|
end
|
173
|
+
|
157
174
|
it "should raise an error if the required binary /usr/sbin/groupadd doesn't exist" do
|
158
175
|
expect(File).to receive(:exists?).with("/usr/sbin/groupadd").and_return(false)
|
159
|
-
expect {
|
176
|
+
expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Group)
|
160
177
|
end
|
178
|
+
|
161
179
|
it "should raise an error if the required binary /usr/sbin/groupmod doesn't exist" do
|
162
180
|
expect(File).to receive(:exists?).with("/usr/sbin/groupadd").and_return(true)
|
163
181
|
expect(File).to receive(:exists?).with("/usr/sbin/groupmod").and_return(false)
|
164
|
-
expect {
|
182
|
+
expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Group)
|
165
183
|
end
|
184
|
+
|
166
185
|
it "should raise an error if the required binary /usr/sbin/groupdel doesn't exist" do
|
167
186
|
expect(File).to receive(:exists?).with("/usr/sbin/groupadd").and_return(true)
|
168
187
|
expect(File).to receive(:exists?).with("/usr/sbin/groupmod").and_return(true)
|
169
188
|
expect(File).to receive(:exists?).with("/usr/sbin/groupdel").and_return(false)
|
170
|
-
expect {
|
189
|
+
expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Group)
|
171
190
|
end
|
172
191
|
|
173
192
|
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Vasundhara Jagdale (<vasundhara.jagdale@msystechnologies.com>)
|
3
|
+
# Copyright:: Copyright 2008-2016, Chef Software, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require "spec_helper"
|
20
|
+
|
21
|
+
describe Chef::Provider::Package::Cab do
|
22
|
+
let(:timeout) {}
|
23
|
+
|
24
|
+
let(:new_resource) { Chef::Resource::CabPackage.new("windows_test_pkg") }
|
25
|
+
|
26
|
+
let(:provider) do
|
27
|
+
node = Chef::Node.new
|
28
|
+
events = Chef::EventDispatch::Dispatcher.new
|
29
|
+
run_context = Chef::RunContext.new(node, {}, events)
|
30
|
+
Chef::Provider::Package::Cab.new(new_resource, run_context)
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:installed_package_list_stdout) do
|
34
|
+
<<-EOF
|
35
|
+
Packages listing:
|
36
|
+
Package Identity : Package_for_KB2999486~31bf3856ad364e35~amd64~~6.1.9768.0
|
37
|
+
Package Identity : Package_for_KB2994825~31bf3856ad364e35~amd64~~6.1.7601.0
|
38
|
+
EOF
|
39
|
+
end
|
40
|
+
|
41
|
+
let(:package_version_stdout) do
|
42
|
+
<<-EOF
|
43
|
+
Package information:
|
44
|
+
Package Identity : Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0
|
45
|
+
State : Installed
|
46
|
+
Dependency : Language Pack
|
47
|
+
The operation completed successfully
|
48
|
+
EOF
|
49
|
+
end
|
50
|
+
|
51
|
+
before do
|
52
|
+
new_resource.source = "C:\\Temp\\Test6.1-KB2664825-v3-x64.cab"
|
53
|
+
installed_package_list_obj = double(stdout: installed_package_list_stdout)
|
54
|
+
allow(provider).to receive(:dism_command).with("/Get-Packages").and_return(installed_package_list_obj)
|
55
|
+
package_version_obj = double(stdout: package_version_stdout)
|
56
|
+
allow(provider).to receive(:dism_command).with("/Get-PackageInfo /PackagePath:\"#{new_resource.source}\"").and_return(package_version_obj)
|
57
|
+
end
|
58
|
+
|
59
|
+
def allow_package_info(package_path = nil, package_name = nil)
|
60
|
+
get_package_info_stdout = <<-EOF
|
61
|
+
Deployment Image Servicing and Management tool
|
62
|
+
Version: 6.1.7600.16385
|
63
|
+
|
64
|
+
Image Version: 6.1.7600.16385
|
65
|
+
|
66
|
+
Package information:
|
67
|
+
Package Identity : Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0
|
68
|
+
Applicable : Yes
|
69
|
+
Copyright : Microsoft Corporation
|
70
|
+
Company : Microsoft Corporation
|
71
|
+
State : Installed
|
72
|
+
Dependency : Language Pack
|
73
|
+
The operation completed successfully
|
74
|
+
EOF
|
75
|
+
get_package_info_obj = double(stdout: get_package_info_stdout)
|
76
|
+
if package_path
|
77
|
+
allow(provider).to receive(:dism_command).with("/Get-PackageInfo /PackagePath:\"#{package_path}\"").and_return(get_package_info_obj)
|
78
|
+
else
|
79
|
+
allow(provider).to receive(:dism_command).with("/Get-PackageInfo /PackageName:\"#{package_name}\"").and_return(get_package_info_obj)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def allow_get_packages
|
84
|
+
get_packages_stdout = <<-EOF
|
85
|
+
Deployment Image Servicing and Management tool
|
86
|
+
Version: 6.1.7600.16385
|
87
|
+
|
88
|
+
Image Version: 6.1.7600.16385
|
89
|
+
|
90
|
+
Packages listing:
|
91
|
+
|
92
|
+
Package Identity : Package_for_KB2999486~31bf3856ad364e35~amd64~~6.1.9768.0
|
93
|
+
State : Installed
|
94
|
+
Release Type : Language Pack
|
95
|
+
Install Time : 2/11/2015 11:33 PM
|
96
|
+
|
97
|
+
Package Identity : Package_for_KB2994825~31bf3856ad364e35~amd64~~6.1.7601.0
|
98
|
+
State : Installed
|
99
|
+
Release Type : Language Pack
|
100
|
+
Install Time : 2/11/2015 11:33 PM
|
101
|
+
|
102
|
+
Package Identity : Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0
|
103
|
+
State : Installed
|
104
|
+
Release Type : Feature Pack
|
105
|
+
Install Time : 11/21/2010 3:40 AM
|
106
|
+
|
107
|
+
The operation completed successfully.
|
108
|
+
EOF
|
109
|
+
get_packages_obj = double(stdout: get_packages_stdout)
|
110
|
+
allow(provider).to receive(:dism_command).with("/Get-Packages").and_return(get_packages_obj)
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "#load_current_resource" do
|
114
|
+
it "returns a current_resource" do
|
115
|
+
expect(provider.load_current_resource).to be_kind_of(Chef::Resource::CabPackage)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "sets the current_resource.version to nil when the package is not installed" do
|
119
|
+
provider.load_current_resource
|
120
|
+
expect(provider.current_resource.version).to eql(nil)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "sets the new resource package version" do
|
124
|
+
provider.load_current_resource
|
125
|
+
expect(provider.new_resource.version).to eql("6.1.3.0")
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "#initialize" do
|
130
|
+
it "returns the correct class" do
|
131
|
+
expect(provider).to be_kind_of(Chef::Provider::Package::Cab)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "#package_version" do
|
136
|
+
it "returns the new package version" do
|
137
|
+
allow_package_info(new_resource.source, nil)
|
138
|
+
expect(provider.package_version).to eql("6.1.3.0")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "#installed_version" do
|
143
|
+
it "returns the current installed version of package" do
|
144
|
+
allow_package_info(new_resource.source, nil)
|
145
|
+
allow_get_packages
|
146
|
+
allow_package_info(nil, "Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0")
|
147
|
+
expect(provider.installed_version).to eql("6.1.3.0")
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "#action_remove" do
|
152
|
+
it "does nothing when the package is already removed" do
|
153
|
+
provider.load_current_resource
|
154
|
+
expect(provider).not_to receive(:remove_package)
|
155
|
+
provider.run_action(:remove)
|
156
|
+
expect(new_resource).not_to be_updated_by_last_action
|
157
|
+
end
|
158
|
+
|
159
|
+
it "removes packages if package is installed" do
|
160
|
+
allow_package_info(new_resource.source, nil)
|
161
|
+
allow_get_packages
|
162
|
+
allow_package_info(nil, "Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0")
|
163
|
+
provider.load_current_resource
|
164
|
+
expect(provider.installed_version).not_to eql(nil)
|
165
|
+
expect(provider).to receive(:remove_package)
|
166
|
+
provider.run_action(:remove)
|
167
|
+
expect(new_resource).to be_updated_by_last_action
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "#action_install" do
|
172
|
+
it "installs package if already not installed" do
|
173
|
+
provider.load_current_resource
|
174
|
+
expect(provider.installed_version).to eql(nil)
|
175
|
+
expect(provider).to receive(:install_package)
|
176
|
+
provider.run_action(:install)
|
177
|
+
expect(new_resource).to be_updated_by_last_action
|
178
|
+
end
|
179
|
+
|
180
|
+
it "does not install package if already installed" do
|
181
|
+
allow_package_info(new_resource.source, nil)
|
182
|
+
allow_get_packages
|
183
|
+
allow_package_info(nil, "Package_for_KB2664825~31bf3856ad364e35~amd64~~6.1.3.0")
|
184
|
+
provider.load_current_resource
|
185
|
+
expect(provider.installed_version).not_to eql(nil)
|
186
|
+
expect(provider).not_to receive(:install_package)
|
187
|
+
provider.run_action(:install)
|
188
|
+
expect(new_resource).not_to be_updated_by_last_action
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context "Invalid package source" do
|
193
|
+
def package_version_stdout
|
194
|
+
package_version_stdout = <<-EOF
|
195
|
+
|
196
|
+
Deployment Image Servicing and Management tool
|
197
|
+
Version: 6.1.7600.16385
|
198
|
+
|
199
|
+
Image Version: 6.1.7600.16385
|
200
|
+
|
201
|
+
An error occurred trying to open - c:\\temp\\test6.1-KB2664825-v3-x64.cab Error: 0x80070003
|
202
|
+
Error: 3
|
203
|
+
The system cannot find the path specified.
|
204
|
+
The DISM log file can be found at C:\\Windows\\Logs\\DISM\\dism.log.
|
205
|
+
EOF
|
206
|
+
end
|
207
|
+
|
208
|
+
before do
|
209
|
+
new_resource.source = "C:\\Temp\\Test6.1-KB2664825-v3-x64.cab"
|
210
|
+
installed_package_list_obj = double(stdout: installed_package_list_stdout)
|
211
|
+
allow(provider).to receive(:dism_command).with("/Get-Packages").and_return(installed_package_list_obj)
|
212
|
+
end
|
213
|
+
|
214
|
+
it "raises error for invalid source path or file" do
|
215
|
+
expect { provider.load_current_resource }.to raise_error(Chef::Exceptions::Package, "DISM: The system cannot find the path or file specified.")
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|