chef 12.4.0.rc.2-universal-mingw32 → 12.4.0-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.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/distro/powershell/chef/chef.psm1 +327 -0
  3. data/lib/chef/chef_class.rb +4 -4
  4. data/lib/chef/client.rb +12 -6
  5. data/lib/chef/node_map.rb +63 -38
  6. data/lib/chef/platform/priority_map.rb +54 -0
  7. data/lib/chef/platform/provider_mapping.rb +2 -2
  8. data/lib/chef/platform/provider_priority_map.rb +3 -21
  9. data/lib/chef/platform/resource_priority_map.rb +5 -22
  10. data/lib/chef/provider.rb +1 -1
  11. data/lib/chef/provider/package/rpm.rb +2 -2
  12. data/lib/chef/provider/service/debian.rb +0 -2
  13. data/lib/chef/provider/service/insserv.rb +0 -2
  14. data/lib/chef/provider/service/invokercd.rb +0 -2
  15. data/lib/chef/provider/service/redhat.rb +0 -2
  16. data/lib/chef/provider/service/upstart.rb +0 -2
  17. data/lib/chef/provider/user.rb +0 -2
  18. data/lib/chef/resource.rb +23 -24
  19. data/lib/chef/resource/lwrp_base.rb +2 -1
  20. data/lib/chef/resource/macports_package.rb +2 -1
  21. data/lib/chef/resource/package.rb +0 -5
  22. data/lib/chef/resource_resolver.rb +1 -0
  23. data/lib/chef/version.rb +1 -1
  24. data/spec/integration/recipes/lwrp_spec.rb +2 -6
  25. data/spec/integration/recipes/recipe_dsl_spec.rb +254 -39
  26. data/spec/support/shared/shared_examples.rb +1 -1
  27. data/spec/unit/api_client_spec.rb +1 -1
  28. data/spec/unit/client_spec.rb +35 -19
  29. data/spec/unit/cookbook_version_spec.rb +1 -1
  30. data/spec/unit/data_bag_item_spec.rb +1 -1
  31. data/spec/unit/data_bag_spec.rb +1 -1
  32. data/spec/unit/environment_spec.rb +1 -1
  33. data/spec/unit/exceptions_spec.rb +1 -1
  34. data/spec/unit/json_compat_spec.rb +1 -1
  35. data/spec/unit/lwrp_spec.rb +43 -4
  36. data/spec/unit/node_spec.rb +1 -1
  37. data/spec/unit/osc_user_spec.rb +1 -1
  38. data/spec/unit/provider/package/rpm_spec.rb +335 -124
  39. data/spec/unit/provider_resolver_spec.rb +0 -1
  40. data/spec/unit/recipe_spec.rb +12 -8
  41. data/spec/unit/resource_collection_spec.rb +1 -1
  42. data/spec/unit/resource_resolver_spec.rb +49 -0
  43. data/spec/unit/resource_spec.rb +19 -4
  44. data/spec/unit/role_spec.rb +1 -1
  45. data/spec/unit/run_list_spec.rb +1 -1
  46. data/spec/unit/runner_spec.rb +2 -2
  47. data/spec/unit/user_spec.rb +1 -1
  48. metadata +10 -8
  49. data/spec/support/pedant/Gemfile.lock +0 -67
@@ -1,7 +1,7 @@
1
1
  # For storing any examples shared between multiple tests
2
2
 
3
3
  # Any object which defines a .to_json should import this test
4
- shared_examples "to_json equalivent to Chef::JSONCompat.to_json" do
4
+ shared_examples "to_json equivalent to Chef::JSONCompat.to_json" do
5
5
 
6
6
  let(:jsonable) {
7
7
  raise "You must define the subject when including this test"
@@ -144,7 +144,7 @@ describe Chef::ApiClient do
144
144
  expect(@json).not_to include("private_key")
145
145
  end
146
146
 
147
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
147
+ include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
148
148
  let(:jsonable) { @client }
149
149
  end
150
150
  end
@@ -238,23 +238,24 @@ describe Chef::Client do
238
238
  describe "when converge completes successfully" do
239
239
  include_context "a client run"
240
240
  include_context "converge completed"
241
-
242
- describe "when audit phase errors" do
243
- include_context "audit phase failed with error"
244
- include_examples "a completed run with audit failure" do
245
- let(:run_errors) { [audit_error] }
241
+ context 'when audit mode is enabled' do
242
+ describe "when audit phase errors" do
243
+ include_context "audit phase failed with error"
244
+ include_examples "a completed run with audit failure" do
245
+ let(:run_errors) { [audit_error] }
246
+ end
246
247
  end
247
- end
248
248
 
249
- describe "when audit phase completed" do
250
- include_context "audit phase completed"
251
- include_examples "a completed run"
252
- end
249
+ describe "when audit phase completed" do
250
+ include_context "audit phase completed"
251
+ include_examples "a completed run"
252
+ end
253
253
 
254
- describe "when audit phase completed with failed controls" do
255
- include_context "audit phase completed with failed controls"
256
- include_examples "a completed run with audit failure" do
257
- let(:run_errors) { [audit_error] }
254
+ describe "when audit phase completed with failed controls" do
255
+ include_context "audit phase completed with failed controls"
256
+ include_examples "a completed run with audit failure" do
257
+ let(:run_errors) { [audit_error] }
258
+ end
258
259
  end
259
260
  end
260
261
  end
@@ -512,11 +513,26 @@ describe Chef::Client do
512
513
  allow_any_instance_of(Chef::RunLock).to receive(:save_pid).and_raise(NoMethodError)
513
514
  end
514
515
 
515
- it "should run exception handlers on early fail" do
516
- expect(subject).to receive(:run_failed)
517
- expect { subject.run }.to raise_error(Chef::Exceptions::RunFailedWrappingError) do |error|
518
- expect(error.wrapped_errors.size).to eq 1
519
- expect(error.wrapped_errors).to include(NoMethodError)
516
+ context 'when audit mode is enabled' do
517
+ before do
518
+ Chef::Config[:audit_mode] = :enabled
519
+ end
520
+ it "should run exception handlers on early fail" do
521
+ expect(subject).to receive(:run_failed)
522
+ expect { subject.run }.to raise_error(Chef::Exceptions::RunFailedWrappingError) do |error|
523
+ expect(error.wrapped_errors.size).to eq 1
524
+ expect(error.wrapped_errors).to include(NoMethodError)
525
+ end
526
+ end
527
+ end
528
+
529
+ context 'when audit mode is disabled' do
530
+ before do
531
+ Chef::Config[:audit_mode] = :disabled
532
+ end
533
+ it "should run exception handlers on early fail" do
534
+ expect(subject).to receive(:run_failed)
535
+ expect { subject.run }.to raise_error(NoMethodError)
520
536
  end
521
537
  end
522
538
  end
@@ -336,7 +336,7 @@ describe Chef::CookbookVersion do
336
336
  end
337
337
 
338
338
 
339
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
339
+ include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
340
340
  let(:jsonable) { Chef::CookbookVersion.new("tatft", '/tmp/blah') }
341
341
  end
342
342
 
@@ -193,7 +193,7 @@ describe Chef::DataBagItem do
193
193
  expect(deserial["snooze"]).to eq({ "finally" => "world_will" })
194
194
  end
195
195
 
196
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
196
+ include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
197
197
  let(:jsonable) { data_bag_item }
198
198
  end
199
199
  end
@@ -73,7 +73,7 @@ describe Chef::DataBag do
73
73
  expect(@deserial.send(t.to_sym)).to eq(@data_bag.send(t.to_sym))
74
74
  end
75
75
 
76
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
76
+ include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
77
77
  let(:jsonable) { @data_bag }
78
78
  end
79
79
  end
@@ -208,7 +208,7 @@ describe Chef::Environment do
208
208
  expect(@json).to match(/"chef_type":"environment"/)
209
209
  end
210
210
 
211
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
211
+ include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
212
212
  let(:jsonable) { @environment }
213
213
  end
214
214
  end
@@ -76,7 +76,7 @@ describe Chef::Exceptions do
76
76
  end
77
77
 
78
78
  if exception.methods.include?(:to_json)
79
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
79
+ include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
80
80
  let(:jsonable) { exception }
81
81
  end
82
82
  end
@@ -67,7 +67,7 @@ describe Chef::JSONCompat do
67
67
  expect(Chef::JSONCompat.to_json_pretty(f)).to eql("{\n \"foo\": 1234,\n \"bar\": {\n \"baz\": 5678\n }\n}\n")
68
68
  end
69
69
 
70
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
70
+ include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
71
71
  let(:jsonable) { Foo.new }
72
72
  end
73
73
  end
@@ -409,13 +409,13 @@ describe "LWRP" do
409
409
  end
410
410
  end
411
411
 
412
- context "when the child does not defined the methods" do
412
+ context "when the child does not define the methods" do
413
413
  let(:child) do
414
414
  Class.new(parent)
415
415
  end
416
416
 
417
417
  it "delegates #actions to the parent" do
418
- expect(child.actions).to eq([:eat, :sleep])
418
+ expect(child.actions).to eq([:nothing, :eat, :sleep])
419
419
  end
420
420
 
421
421
  it "delegates #default_action to the parent" do
@@ -432,7 +432,7 @@ describe "LWRP" do
432
432
  end
433
433
 
434
434
  it "does not delegate #actions to the parent" do
435
- expect(child.actions).to eq([:dont_eat, :dont_sleep])
435
+ expect(child.actions).to eq([:nothing, :dont_eat, :dont_sleep])
436
436
  end
437
437
 
438
438
  it "does not delegate #default_action to the parent" do
@@ -457,11 +457,50 @@ describe "LWRP" do
457
457
 
458
458
  it "amends actions when they are already defined" do
459
459
  raise_if_deprecated!
460
- expect(child.actions).to eq([:eat, :sleep, :drink])
460
+ expect(child.actions).to eq([:nothing, :eat, :sleep, :drink])
461
461
  end
462
462
  end
463
463
  end
464
464
 
465
+ describe "when actions is set to an array" do
466
+ let(:resource_class) do
467
+ Class.new(Chef::Resource::LWRPBase) do
468
+ actions [ :eat, :sleep ]
469
+ end
470
+ end
471
+ let(:resource) do
472
+ resource_class.new('blah')
473
+ end
474
+ it "actions includes those actions" do
475
+ expect(resource_class.actions).to eq [ :nothing, :eat, :sleep ]
476
+ end
477
+ it "allowed_actions includes those actions" do
478
+ expect(resource_class.allowed_actions).to eq [ :nothing, :eat, :sleep ]
479
+ end
480
+ it "resource.allowed_actions includes those actions" do
481
+ expect(resource.allowed_actions).to eq [ :nothing, :eat, :sleep ]
482
+ end
483
+ end
484
+
485
+ describe "when allowed_actions is set to an array" do
486
+ let(:resource_class) do
487
+ Class.new(Chef::Resource::LWRPBase) do
488
+ allowed_actions [ :eat, :sleep ]
489
+ end
490
+ end
491
+ let(:resource) do
492
+ resource_class.new('blah')
493
+ end
494
+ it "actions includes those actions" do
495
+ expect(resource_class.actions).to eq [ :nothing, :eat, :sleep ]
496
+ end
497
+ it "allowed_actions includes those actions" do
498
+ expect(resource_class.allowed_actions).to eq [ :nothing, :eat, :sleep ]
499
+ end
500
+ it "resource.allowed_actions includes those actions" do
501
+ expect(resource.allowed_actions).to eq [ :nothing, :eat, :sleep ]
502
+ end
503
+ end
465
504
  end
466
505
 
467
506
  describe "Lightweight Chef::Provider" do
@@ -1106,7 +1106,7 @@ describe Chef::Node do
1106
1106
  expect(serialized_node.run_list).to eq(node.run_list)
1107
1107
  end
1108
1108
 
1109
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
1109
+ include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
1110
1110
  let(:jsonable) {
1111
1111
  node.from_file(File.expand_path("nodes/test.example.com.rb", CHEF_SPEC_DATA))
1112
1112
  node
@@ -160,7 +160,7 @@ describe Chef::OscUser do
160
160
  expect(@json).not_to include("password")
161
161
  end
162
162
 
163
- include_examples "to_json equalivent to Chef::JSONCompat.to_json" do
163
+ include_examples "to_json equivalent to Chef::JSONCompat.to_json" do
164
164
  let(:jsonable) { @user }
165
165
  end
166
166
  end
@@ -23,183 +23,394 @@ describe Chef::Provider::Package::Rpm do
23
23
  let(:node) { Chef::Node.new }
24
24
  let(:events) { Chef::EventDispatch::Dispatcher.new }
25
25
  let(:run_context) { Chef::RunContext.new(node, {}, events) }
26
+
27
+ let(:package_source) { "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm" }
28
+
29
+ let(:package_name) { "ImageMagick-c++" }
30
+
26
31
  let(:new_resource) do
27
- Chef::Resource::Package.new("ImageMagick-c++").tap do |resource|
28
- resource.source "/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
32
+ Chef::Resource::Package.new(package_name).tap do |resource|
33
+ resource.source(package_source)
29
34
  end
30
35
  end
31
- let(:exitstatus) { 0 }
32
- let(:stdout) { String.new('') }
33
- let(:status) { double('Process::Status', exitstatus: exitstatus, stdout: stdout) }
36
+
37
+ # `rpm -qp [stuff] $source`
38
+ let(:rpm_qp_status) { instance_double('Mixlib::ShellOut', exitstatus: rpm_qp_exitstatus, stdout: rpm_qp_stdout) }
39
+
40
+ # `rpm -q [stuff] $package_name`
41
+ let(:rpm_q_status) { instance_double('Mixlib::ShellOut', exitstatus: rpm_q_exitstatus, stdout: rpm_q_stdout) }
34
42
 
35
43
  before(:each) do
36
- allow(::File).to receive(:exists?).and_return(true)
37
- allow(provider).to receive(:shell_out!).and_return(status)
44
+ allow(::File).to receive(:exists?).with("PLEASE STUB File.exists? EXACTLY").and_return(true)
45
+
46
+ # Ensure all shell out usage is stubbed with exact arguments
47
+ allow(provider).to receive(:shell_out!).with("PLEASE STUB YOUR SHELLOUT CALLS").and_return(nil)
48
+ allow(provider).to receive(:shell_out).with("PLEASE STUB YOUR SHELLOUT CALLS").and_return(nil)
38
49
  end
39
50
 
40
- describe "when determining the current state of the package" do
41
- it "should create a current resource with the name of new_resource" do
42
- provider.load_current_resource
43
- expect(provider.current_resource.name).to eq("ImageMagick-c++")
44
- end
51
+ describe "when the package source is not valid" do
45
52
 
46
- it "should set the current reource package name to the new resource package name" do
47
- provider.load_current_resource
48
- expect(provider.current_resource.package_name).to eq('ImageMagick-c++')
49
- end
53
+ context "when source is not defiend" do
54
+ let(:new_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
50
55
 
51
- it "should raise an exception if a source is supplied but not found" do
52
- allow(::File).to receive(:exists?).and_return(false)
53
- expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
56
+ it "should raise an exception when attempting any action" do
57
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
58
+ end
54
59
  end
55
60
 
56
- context "installation exists" do
57
- let(:stdout) { "ImageMagick-c++ 6.5.4.7-7.el6_5" }
61
+ context "when the source is a file that doesn't exist" do
58
62
 
59
- it "should get the source package version from rpm if provided" do
60
- expect(provider).to receive(:shell_out!).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900).and_return(status)
61
- expect(provider).to receive(:shell_out).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++", timeout: 900).and_return(status)
62
- provider.load_current_resource
63
- expect(provider.current_resource.package_name).to eq("ImageMagick-c++")
64
- expect(provider.new_resource.version).to eq("6.5.4.7-7.el6_5")
63
+ it "should raise an exception when attempting any action" do
64
+ allow(::File).to receive(:exists?).with(package_source).and_return(false)
65
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
65
66
  end
67
+ end
66
68
 
67
- it "should return the current version installed if found by rpm" do
68
- expect(provider).to receive(:shell_out!).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900).and_return(status)
69
- expect(provider).to receive(:shell_out).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' ImageMagick-c++", timeout: 900).and_return(status)
70
- provider.load_current_resource
71
- expect(provider.current_resource.version).to eq("6.5.4.7-7.el6_5")
69
+ context "when the source is an unsupported URI scheme" do
70
+
71
+ let(:package_source) { "foobar://example.com/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm" }
72
+
73
+ it "should raise an exception if an uri formed source is non-supported scheme" do
74
+ allow(::File).to receive(:exists?).with(package_source).and_return(false)
75
+
76
+ # verify let bindings are as we expect
77
+ expect(new_resource.source).to eq("foobar://example.com/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
78
+ expect(provider.load_current_resource).to be_nil
79
+ expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
72
80
  end
73
81
  end
74
82
 
75
- context "source is uri formed" do
76
- before(:each) do
77
- allow(::File).to receive(:exists?).and_return(false)
83
+ end
84
+
85
+ describe "when the package source is valid" do
86
+
87
+ before do
88
+ expect(provider).to receive(:shell_out!).
89
+ with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{package_source}", timeout: 900).
90
+ and_return(rpm_qp_status)
91
+
92
+ expect(provider).to receive(:shell_out).
93
+ with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' #{package_name}", timeout: 900).
94
+ and_return(rpm_q_status)
95
+ end
96
+
97
+ context "when rpm fails when querying package installed state" do
98
+
99
+ before do
100
+ allow(::File).to receive(:exists?).with(package_source).and_return(true)
78
101
  end
79
102
 
80
- %w(http HTTP https HTTPS ftp FTP).each do |scheme|
81
- it "should accept uri formed source (#{scheme})" do
82
- new_resource.source "#{scheme}://example.com/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
83
- expect(provider.load_current_resource).not_to be_nil
103
+ let(:rpm_qp_stdout) { "ImageMagick-c++ 6.5.4.7-7.el6_5" }
104
+ let(:rpm_q_stdout) { "" }
105
+
106
+ let(:rpm_qp_exitstatus) { 0 }
107
+ let(:rpm_q_exitstatus) { -1 }
108
+
109
+ it "raises an exception when attempting any action" do
110
+ expected_message = "Unable to determine current version due to RPM failure."
111
+
112
+ expect { provider.run_action(:install) }.to raise_error do |error|
113
+ expect(error).to be_a_kind_of(Chef::Exceptions::Package)
114
+ expect(error.to_s).to include(expected_message)
84
115
  end
85
116
  end
117
+ end
118
+
119
+
120
+ context "when the package is installed" do
121
+
122
+ let(:rpm_qp_stdout) { "ImageMagick-c++ 6.5.4.7-7.el6_5" }
123
+ let(:rpm_q_stdout) { "ImageMagick-c++ 6.5.4.7-7.el6_5" }
124
+
125
+ let(:rpm_qp_exitstatus) { 0 }
126
+ let(:rpm_q_exitstatus) { 0 }
86
127
 
87
- %w(file FILE).each do |scheme|
88
- it "should accept uri formed source (#{scheme})" do
89
- new_resource.source "#{scheme}:///ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
90
- expect(provider.load_current_resource).not_to be_nil
128
+ let(:action) { :install }
129
+
130
+ context "when the source is a file system path" do
131
+
132
+ before do
133
+ allow(::File).to receive(:exists?).with(package_source).and_return(true)
134
+
135
+ provider.action = action
136
+
137
+ provider.load_current_resource
138
+ provider.define_resource_requirements
139
+ provider.process_resource_requirements
91
140
  end
92
- end
93
141
 
94
- it "should raise an exception if an uri formed source is non-supported scheme" do
95
- new_resource.source "foobar://example.com/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm"
96
- expect(provider.load_current_resource).to be_nil
97
- expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
98
- end
99
- end
142
+ it "should get the source package version from rpm if provided" do
143
+ expect(provider.current_resource.package_name).to eq("ImageMagick-c++")
144
+ expect(provider.new_resource.version).to eq("6.5.4.7-7.el6_5")
145
+ end
100
146
 
101
- context "source is not defiend" do
102
- let(:new_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
147
+ it "should return the current version installed if found by rpm" do
148
+ expect(provider.current_resource.version).to eq("6.5.4.7-7.el6_5")
149
+ end
150
+
151
+ describe "action install" do
152
+
153
+ context "when at the desired version already" do
154
+ it "does nothing when the correct version is installed" do
155
+ expect(provider).to_not receive(:shell_out!).with("rpm -i /tmp/imagemagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
156
+
157
+ provider.action_install
158
+ end
159
+ end
160
+
161
+ context "when a newer version is desired" do
162
+
163
+ let(:rpm_q_stdout) { "imagemagick-c++ 0.5.4.7-7.el6_5" }
164
+
165
+ it "runs rpm -u with the package source to upgrade" do
166
+ expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
167
+ provider.action_install
168
+ end
169
+ end
170
+
171
+ context "when an older version is desired" do
172
+ let(:new_resource) do
173
+ Chef::Resource::RpmPackage.new(package_name).tap do |r|
174
+ r.source(package_source)
175
+ r.allow_downgrade(true)
176
+ end
177
+ end
178
+
179
+ let(:rpm_q_stdout) { "imagemagick-c++ 21.4-19.el6_5" }
180
+
181
+ it "should run rpm -u --oldpackage with the package source to downgrade" do
182
+ expect(provider).to receive(:shell_out!).with("rpm -U --oldpackage /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
183
+ provider.action_install
184
+ end
185
+
186
+ end
187
+
188
+ end
189
+
190
+ describe "action upgrade" do
191
+
192
+ let(:action) { :upgrade }
193
+
194
+ context "when at the desired version already" do
195
+ it "does nothing when the correct version is installed" do
196
+ expect(provider).to_not receive(:shell_out!).with("rpm -i /tmp/imagemagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
197
+
198
+ provider.action_upgrade
199
+ end
200
+ end
201
+
202
+ context "when a newer version is desired" do
203
+
204
+ let(:rpm_q_stdout) { "imagemagick-c++ 0.5.4.7-7.el6_5" }
205
+
206
+ it "runs rpm -u with the package source to upgrade" do
207
+ expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
208
+ provider.action_upgrade
209
+ end
210
+ end
211
+
212
+ context "when an older version is desired" do
213
+ let(:new_resource) do
214
+ Chef::Resource::RpmPackage.new(package_name).tap do |r|
215
+ r.source(package_source)
216
+ r.allow_downgrade(true)
217
+ end
218
+ end
219
+
220
+ let(:rpm_q_stdout) { "imagemagick-c++ 21.4-19.el6_5" }
221
+
222
+ it "should run rpm -u --oldpackage with the package source to downgrade" do
223
+ expect(provider).to receive(:shell_out!).with("rpm -U --oldpackage /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
224
+ provider.action_upgrade
225
+ end
226
+
227
+ end
228
+ end
229
+
230
+ describe "action :remove" do
231
+
232
+ let(:action) { :remove }
233
+
234
+ it "should remove the package" do
235
+ expect(provider).to receive(:shell_out!).with("rpm -e ImageMagick-c++-6.5.4.7-7.el6_5", timeout: 900)
236
+ provider.action_remove
237
+ end
238
+ end
239
+
240
+
241
+ context "when the package name contains a tilde (chef#3503)" do
242
+
243
+ let(:package_name) { "supermarket" }
244
+
245
+ let(:package_source) { "/tmp/supermarket-1.10.1~alpha.0-1.el5.x86_64.rpm" }
246
+
247
+ let(:rpm_qp_stdout) { "supermarket 1.10.1~alpha.0-1.el5" }
248
+ let(:rpm_q_stdout) { "supermarket 1.10.1~alpha.0-1.el5" }
249
+
250
+ let(:rpm_qp_exitstatus) { 0 }
251
+ let(:rpm_q_exitstatus) { 0 }
252
+
253
+ it "should correctly determine the candidate version and installed version" do
254
+ expect(provider.current_resource.package_name).to eq("supermarket")
255
+ expect(provider.new_resource.version).to eq("1.10.1~alpha.0-1.el5")
256
+ end
257
+ end
103
258
 
104
- it "should raise an exception if the source is not set but we are installing" do
105
- expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
106
259
  end
107
- end
108
260
 
109
- context "installation does not exist" do
110
- let(:stdout) { String.new("package openssh-askpass is not installed") }
111
- let(:exitstatus) { -1 }
112
- let(:new_resource) do
113
- Chef::Resource::Package.new("openssh-askpass").tap do |resource|
114
- resource.source "openssh-askpass"
261
+ context "when the source is given as an URI" do
262
+ before(:each) do
263
+ allow(::File).to receive(:exists?).with(package_source).and_return(false)
264
+
265
+ provider.action = action
266
+
267
+ provider.load_current_resource
268
+ provider.define_resource_requirements
269
+ provider.process_resource_requirements
270
+ end
271
+
272
+ %w(http HTTP https HTTPS ftp FTP file FILE).each do |scheme|
273
+
274
+ context "when the source URI uses protocol scheme '#{scheme}'" do
275
+
276
+ let(:package_source) { "#{scheme}://example.com/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm" }
277
+
278
+ it "should get the source package version from rpm if provided" do
279
+ expect(provider.current_resource.package_name).to eq("ImageMagick-c++")
280
+ expect(provider.new_resource.version).to eq("6.5.4.7-7.el6_5")
281
+ end
282
+
283
+ it "should return the current version installed if found by rpm" do
284
+ expect(provider.current_resource.version).to eq("6.5.4.7-7.el6_5")
285
+ end
286
+
287
+ end
115
288
  end
289
+
116
290
  end
117
291
 
118
- it "should raise an exception if rpm fails to run" do
119
- allow(provider).to receive(:shell_out).and_return(status)
120
- expect { provider.run_action(:any) }.to raise_error(Chef::Exceptions::Package)
292
+ end
293
+
294
+ context "when the package is not installed" do
295
+
296
+ let(:package_name) { "openssh-askpass" }
297
+
298
+ let(:package_source) { "/tmp/openssh-askpass-1.2.3-4.el6_5.x86_64.rpm" }
299
+
300
+ let(:rpm_qp_stdout) { "openssh-askpass 1.2.3-4.el6_5" }
301
+ let(:rpm_q_stdout) { "package openssh-askpass is not installed" }
302
+
303
+ let(:rpm_qp_exitstatus) { 0 }
304
+ let(:rpm_q_exitstatus) { 0 }
305
+
306
+ let(:action) { :install }
307
+
308
+ before do
309
+ allow(File).to receive(:exists?).with(package_source).and_return(true)
310
+
311
+ provider.action = action
312
+
313
+ provider.load_current_resource
314
+ provider.define_resource_requirements
315
+ provider.process_resource_requirements
121
316
  end
122
317
 
123
318
  it "should not detect the package name as version when not installed" do
124
- expect(provider).to receive(:shell_out!).with("rpm -qp --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass", timeout: 900).and_return(status)
125
- expect(provider).to receive(:shell_out).with("rpm -q --queryformat '%{NAME} %{VERSION}-%{RELEASE}\n' openssh-askpass", timeout: 900).and_return(status)
126
- provider.load_current_resource
127
319
  expect(provider.current_resource.version).to be_nil
128
320
  end
129
- end
130
- end
131
321
 
132
- describe "after the current resource is loaded" do
133
- let(:current_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
134
- let(:provider) do
135
- Chef::Provider::Package::Rpm.new(new_resource, run_context).tap do |provider|
136
- provider.current_resource = current_resource
137
- end
138
- end
322
+ context "when the package name contains a tilde (chef#3503)" do
139
323
 
140
- describe "when installing or upgrading" do
141
- it "should run rpm -i with the package source to install" do
142
- expect(provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
143
- provider.install_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
144
- end
324
+ let(:package_name) { "supermarket" }
145
325
 
146
- it "should run rpm -U with the package source to upgrade" do
147
- current_resource.version("21.4-19.el5")
148
- expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
149
- provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
150
- end
326
+ let(:package_source) { "/tmp/supermarket-1.10.1~alpha.0-1.el5.x86_64.rpm" }
151
327
 
152
- it "should install package if missing and set to upgrade" do
153
- current_resource.version("ImageMagick-c++")
154
- expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
155
- provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
156
- end
328
+ let(:rpm_qp_stdout) { "supermarket 1.10.1~alpha.0-1.el5" }
329
+ let(:rpm_q_stdout) { "package supermarket is not installed" }
157
330
 
158
- context "allowing downgrade" do
159
- let(:new_resource) { Chef::Resource::RpmPackage.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm") }
160
- let(:current_resource) { Chef::Resource::RpmPackage.new("ImageMagick-c++") }
331
+ let(:rpm_qp_exitstatus) { 0 }
332
+ let(:rpm_q_exitstatus) { 0 }
161
333
 
162
- it "should run rpm -U --oldpackage with the package source to downgrade" do
163
- new_resource.allow_downgrade(true)
164
- current_resource.version("21.4-19.el5")
165
- expect(provider).to receive(:shell_out!).with("rpm -U --oldpackage /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
166
- provider.upgrade_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
334
+ it "should correctly determine the candidate version" do
335
+ expect(provider.new_resource.version).to eq("1.10.1~alpha.0-1.el5")
167
336
  end
168
337
  end
169
338
 
170
- context "installing when the name is a path" do
171
- let(:new_resource) { Chef::Resource::Package.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm") }
172
- let(:current_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
339
+ describe "managing the package" do
340
+
341
+ describe "action install" do
342
+
343
+ it "installs the package" do
344
+ expect(provider).to receive(:shell_out!).with("rpm -i #{package_source}", timeout: 900)
173
345
 
174
- it "should install from a path when the package is a path and the source is nil" do
175
- expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
176
- provider.current_resource = current_resource
177
- expect(provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
178
- provider.install_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
346
+ provider.action_install
347
+ end
348
+
349
+ context "when custom resource options are given" do
350
+ it "installs with custom options specified in the resource" do
351
+ new_resource.options("--dbpath /var/lib/rpm")
352
+ expect(provider).to receive(:shell_out!).with("rpm --dbpath /var/lib/rpm -i #{package_source}", timeout: 900)
353
+ provider.action_install
354
+ end
355
+ end
179
356
  end
180
357
 
181
- it "should uprgrade from a path when the package is a path and the source is nil" do
182
- expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
183
- current_resource.version("21.4-19.el5")
184
- provider.current_resource = current_resource
185
- expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
186
- provider.upgrade_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
358
+ describe "action upgrade" do
359
+
360
+ let(:action) { :upgrade }
361
+
362
+ it "installs the package" do
363
+ expect(provider).to receive(:shell_out!).with("rpm -i #{package_source}", timeout: 900)
364
+
365
+ provider.action_upgrade
366
+ end
367
+ end
368
+
369
+ describe "when removing the package" do
370
+
371
+ let(:action) { :remove }
372
+
373
+ it "should do nothing" do
374
+ expect(provider).to_not receive(:shell_out!).with("rpm -e ImageMagick-c++-6.5.4.7-7.el6_5", timeout: 900)
375
+ provider.action_remove
376
+ end
187
377
  end
188
- end
189
378
 
190
- it "installs with custom options specified in the resource" do
191
- provider.candidate_version = '11'
192
- new_resource.options("--dbpath /var/lib/rpm")
193
- expect(provider).to receive(:shell_out!).with("rpm --dbpath /var/lib/rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
194
- provider.install_package(new_resource.name, provider.candidate_version)
195
379
  end
380
+
381
+
196
382
  end
383
+ end
197
384
 
198
- describe "when removing the package" do
199
- it "should run rpm -e to remove the package" do
200
- expect(provider).to receive(:shell_out!).with("rpm -e ImageMagick-c++-6.5.4.7-7.el6_5", timeout: 900)
201
- provider.remove_package("ImageMagick-c++", "6.5.4.7-7.el6_5")
202
- end
385
+ context "when the resource name is the path to the package" do
386
+
387
+ let(:new_resource) do
388
+ # When we pass a source in as the name, then #initialize in the
389
+ # provider will call File.exists?. Because of the ordering in our
390
+ # let() bindings and such, we have to set the stub here and not in a
391
+ # before block.
392
+ allow(::File).to receive(:exists?).with(package_source).and_return(true)
393
+ Chef::Resource::Package.new("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
394
+ end
395
+
396
+ let(:current_resource) { Chef::Resource::Package.new("ImageMagick-c++") }
397
+
398
+ it "should install from a path when the package is a path and the source is nil" do
399
+ expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
400
+ provider.current_resource = current_resource
401
+ expect(provider).to receive(:shell_out!).with("rpm -i /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
402
+ provider.install_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
403
+ end
404
+
405
+ it "should uprgrade from a path when the package is a path and the source is nil" do
406
+ expect(new_resource.source).to eq("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm")
407
+ current_resource.version("21.4-19.el5")
408
+ provider.current_resource = current_resource
409
+ expect(provider).to receive(:shell_out!).with("rpm -U /tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", timeout: 900)
410
+ provider.upgrade_package("/tmp/ImageMagick-c++-6.5.4.7-7.el6_5.x86_64.rpm", "6.5.4.7-7.el6_5")
203
411
  end
204
412
  end
413
+
414
+
205
415
  end
416
+