chef 12.4.0.rc.2-universal-mingw32 → 12.4.0-universal-mingw32

Sign up to get free protection for your applications and to get access to all the features.
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
+