chef 12.15.19-universal-mingw32 → 12.16.42-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 (99) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +0 -1
  3. data/VERSION +1 -1
  4. data/acceptance/.shared/kitchen_acceptance/.kitchen.ec2.yml +3 -1
  5. data/acceptance/Gemfile.lock +14 -14
  6. data/acceptance/data-collector/test/integration/default/serverspec/default_spec.rb +3 -11
  7. data/distro/common/html/knife_bootstrap.html +1 -1
  8. data/distro/common/man/man1/README.md +2 -2
  9. data/distro/common/man/man1/knife-client.1 +1 -1
  10. data/lib/chef/application.rb +7 -15
  11. data/lib/chef/application/client.rb +2 -2
  12. data/lib/chef/application/solo.rb +1 -1
  13. data/lib/chef/chef_class.rb +1 -0
  14. data/lib/chef/chef_fs/file_system/chef_server/cookbook_file.rb +3 -7
  15. data/lib/chef/chef_fs/file_system/chef_server/versioned_cookbook_dir.rb +1 -1
  16. data/lib/chef/data_collector.rb +83 -9
  17. data/lib/chef/data_collector/messages.rb +2 -1
  18. data/lib/chef/dsl/core.rb +1 -1
  19. data/lib/chef/dsl/declare_resource.rb +10 -4
  20. data/lib/chef/dsl/method_missing.rb +1 -1
  21. data/lib/chef/dsl/recipe.rb +1 -1
  22. data/lib/chef/dsl/universal.rb +1 -1
  23. data/lib/chef/event_dispatch/base.rb +3 -0
  24. data/lib/chef/http.rb +3 -4
  25. data/lib/chef/knife.rb +20 -2
  26. data/lib/chef/knife/core/generic_presenter.rb +18 -4
  27. data/lib/chef/knife/node_show.rb +0 -5
  28. data/lib/chef/knife/osc_user_show.rb +0 -1
  29. data/lib/chef/knife/ssl_fetch.rb +9 -5
  30. data/lib/chef/mixin/powershell_out.rb +1 -1
  31. data/lib/chef/mixin/shell_out.rb +1 -1
  32. data/lib/chef/node.rb +1 -5
  33. data/lib/chef/node/attribute.rb +70 -98
  34. data/lib/chef/node/attribute_collections.rb +28 -19
  35. data/lib/chef/node/common_api.rb +0 -6
  36. data/lib/chef/node/immutable_collections.rb +16 -79
  37. data/lib/chef/node/mixin/deep_merge_cache.rb +61 -0
  38. data/lib/chef/node/mixin/immutablize_array.rb +67 -0
  39. data/lib/chef/node/mixin/immutablize_hash.rb +54 -0
  40. data/lib/chef/node/mixin/state_tracking.rb +93 -0
  41. data/lib/chef/property.rb +4 -4
  42. data/lib/chef/provider/cron.rb +1 -1
  43. data/lib/chef/provider/group/suse.rb +23 -4
  44. data/lib/chef/provider/package.rb +43 -5
  45. data/lib/chef/provider/package/apt.rb +20 -0
  46. data/lib/chef/provider/package/windows/exe.rb +4 -3
  47. data/lib/chef/provider/package/windows/msi.rb +4 -3
  48. data/lib/chef/provider/package/yum.rb +20 -0
  49. data/lib/chef/provider/package/zypper.rb +20 -0
  50. data/lib/chef/provider/ruby_block.rb +1 -1
  51. data/lib/chef/provider/service/upstart.rb +25 -9
  52. data/lib/chef/provider/user.rb +4 -6
  53. data/lib/chef/provider/user/dscl.rb +8 -3
  54. data/lib/chef/provider/user/solaris.rb +5 -12
  55. data/lib/chef/resource.rb +19 -0
  56. data/lib/chef/resource/file.rb +1 -1
  57. data/lib/chef/resource/package.rb +1 -1
  58. data/lib/chef/resource/scm.rb +1 -7
  59. data/lib/chef/resource/yum_repository.rb +1 -1
  60. data/lib/chef/rest.rb +1 -0
  61. data/lib/chef/run_context.rb +12 -0
  62. data/lib/chef/version.rb +1 -1
  63. data/spec/data/trusted_certs/example_no_cn.crt +36 -0
  64. data/spec/functional/resource/group_spec.rb +1 -0
  65. data/spec/functional/resource/user/useradd_spec.rb +4 -2
  66. data/spec/integration/knife/data_bag_create_spec.rb +0 -3
  67. data/spec/integration/knife/environment_show_spec.rb +24 -4
  68. data/spec/integration/knife/node_environment_set_spec.rb +4 -1
  69. data/spec/integration/recipes/accumulator_spec.rb +232 -0
  70. data/spec/integration/recipes/resource_action_spec.rb +1 -1
  71. data/spec/spec_helper.rb +2 -2
  72. data/spec/support/shared/context/client.rb +12 -3
  73. data/spec/support/shared/integration/app_server_support.rb +1 -1
  74. data/spec/support/shared/integration/knife_support.rb +4 -1
  75. data/spec/unit/data_collector/messages_spec.rb +2 -0
  76. data/spec/unit/data_collector_spec.rb +158 -21
  77. data/spec/unit/http_spec.rb +1 -1
  78. data/spec/unit/knife/core/gem_glob_loader_spec.rb +1 -1
  79. data/spec/unit/knife/core/ui_spec.rb +10 -0
  80. data/spec/unit/knife/ssl_fetch_spec.rb +38 -0
  81. data/spec/unit/knife_spec.rb +31 -0
  82. data/spec/unit/mixin/powershell_out_spec.rb +25 -1
  83. data/spec/unit/node/attribute_spec.rb +46 -1
  84. data/spec/unit/node/vivid_mash_spec.rb +27 -89
  85. data/spec/unit/node_spec.rb +134 -3
  86. data/spec/unit/provider/deploy_spec.rb +1 -1
  87. data/spec/unit/provider/group/suse_spec.rb +90 -0
  88. data/spec/unit/provider/package/apt_spec.rb +22 -0
  89. data/spec/unit/provider/package/windows/msi_spec.rb +13 -4
  90. data/spec/unit/provider/package/windows_spec.rb +3 -3
  91. data/spec/unit/provider/package/yum_spec.rb +18 -0
  92. data/spec/unit/provider/package/zypper_spec.rb +64 -0
  93. data/spec/unit/provider/package_spec.rb +58 -0
  94. data/spec/unit/provider/remote_file/content_spec.rb +1 -1
  95. data/spec/unit/provider/service/upstart_service_spec.rb +13 -6
  96. data/spec/unit/provider/user/solaris_spec.rb +36 -9
  97. data/spec/unit/provider/user_spec.rb +6 -0
  98. data/spec/unit/resource/apt_repository_spec.rb +1 -1
  99. metadata +12 -5
@@ -243,6 +243,34 @@ describe Chef::Node do
243
243
  expect { node.sunshine = "is bright" }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
244
244
  end
245
245
 
246
+ it "does not allow modification of node attributes via hash methods" do
247
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
248
+ node.default["h4sh"] = { foo: "bar" }
249
+ expect { node["h4sh"].delete("foo") }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
250
+ expect { node.h4sh.delete("foo") }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
251
+ end
252
+
253
+ it "does not allow modification of node attributes via array methods" do
254
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
255
+ node.default["array"] = []
256
+ expect { node["array"] << "boom" }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
257
+ expect { node.array << "boom" }.to raise_error(Chef::Exceptions::ImmutableAttributeModification)
258
+ end
259
+
260
+ it "returns merged immutable attributes for arrays" do
261
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
262
+ node.default["array"] = []
263
+ expect( node["array"].class ).to eql(Chef::Node::ImmutableArray)
264
+ expect( node.array.class ).to eql(Chef::Node::ImmutableArray)
265
+ end
266
+
267
+ it "returns merged immutable attributes for hashes" do
268
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
269
+ node.default["h4sh"] = {}
270
+ expect( node["h4sh"].class ).to eql(Chef::Node::ImmutableMash)
271
+ expect( node.h4sh.class ).to eql(Chef::Node::ImmutableMash)
272
+ end
273
+
246
274
  it "should allow you get get an attribute via method_missing" do
247
275
  Chef::Config[:treat_deprecation_warnings_as_errors] = false
248
276
  node.default.sunshine = "is bright"
@@ -756,9 +784,9 @@ describe Chef::Node do
756
784
  # In Chef-12.0 there is a deep_merge cache on the top level attribute which had a bug
757
785
  # where it cached node[:foo] separate from node['foo']. These tests exercise those edge conditions.
758
786
  #
759
- # https://github.com/opscode/chef/issues/2700
760
- # https://github.com/opscode/chef/issues/2712
761
- # https://github.com/opscode/chef/issues/2745
787
+ # https://github.com/chef/chef/issues/2700
788
+ # https://github.com/chef/chef/issues/2712
789
+ # https://github.com/chef/chef/issues/2745
762
790
  #
763
791
  describe "deep merge attribute cache edge conditions" do
764
792
  it "does not error with complicated attribute substitution" do
@@ -1681,4 +1709,107 @@ describe Chef::Node do
1681
1709
  end
1682
1710
  end
1683
1711
 
1712
+ describe "path tracking via __path__" do
1713
+ it "works through hash keys" do
1714
+ node.default["foo"] = { "bar" => { "baz" => "qux" } }
1715
+ expect(node["foo"]["bar"].__path__).to eql(%w{foo bar})
1716
+ end
1717
+
1718
+ it "works through the default level" do
1719
+ node.default["foo"] = { "bar" => { "baz" => "qux" } }
1720
+ expect(node.default["foo"]["bar"].__path__).to eql(%w{foo bar})
1721
+ end
1722
+
1723
+ it "works through arrays" do
1724
+ node.default["foo"] = [ { "bar" => { "baz" => "qux" } } ]
1725
+ expect(node["foo"][0].__path__).to eql(["foo", 0])
1726
+ expect(node["foo"][0]["bar"].__path__).to eql(["foo", 0, "bar"])
1727
+ end
1728
+
1729
+ it "works through arrays at the default level" do
1730
+ node.default["foo"] = [ { "bar" => { "baz" => "qux" } } ]
1731
+ expect(node.default["foo"][0].__path__).to eql(["foo", 0])
1732
+ expect(node.default["foo"][0]["bar"].__path__).to eql(["foo", 0, "bar"])
1733
+ end
1734
+
1735
+ # if we set __path__ in the initializer we'd get this wrong, this is why we
1736
+ # update the path on every #[] or #[]= operator
1737
+ it "works on access when the node has been rearranged" do
1738
+ node.default["foo"] = { "bar" => { "baz" => "qux" } }
1739
+ a = node.default["foo"]
1740
+ node.default["fizz"] = a
1741
+ expect(node["fizz"]["bar"].__path__).to eql(%w{fizz bar})
1742
+ expect(node["foo"]["bar"].__path__).to eql(%w{foo bar})
1743
+ end
1744
+
1745
+ # We have a problem because the __path__ is stored on in each node, but the
1746
+ # node can be wired up at multiple locations in the tree via pointers. One
1747
+ # solution would be to deep-dup the value in `#[]=(key, value)` and fix the
1748
+ # __path__ on all the dup'd nodes. The problem is that this would create an
1749
+ # unusual situation where after assignment, you couldn't mutate the thing you
1750
+ # hand a handle on. I'm not entirely positive this behavior is the correct
1751
+ # thing to support, but it is more hash-like (although if we start with a hash
1752
+ # then convert_value does its thing and we *do* get dup'd on assignment). This
1753
+ # behavior likely makes any implementation of a deep merge cache built over the
1754
+ # top of __path__ tracking have edge conditions where it will fail.
1755
+ #
1756
+ # Removing this support would be a breaking change. The test is included here
1757
+ # because it seems most likely that someone would break this behavior while trying
1758
+ # to fix __path__ behavior.
1759
+ it "does not dup in the background when a node is assigned" do
1760
+ # get a handle on a vividmash (can't be a hash or else we convert_value it)
1761
+ node.default["foo"] = { "bar" => { "baz" => "qux" } }
1762
+ a = node.default["foo"]
1763
+ # assign that somewhere else in the tree
1764
+ node.default["fizz"] = a
1765
+ # now upate the source
1766
+ a["duptest"] = true
1767
+ # the tree should have been updated
1768
+ expect(node.default["fizz"]["duptest"]).to be true
1769
+ expect(node["fizz"]["duptest"]).to be true
1770
+ end
1771
+ end
1772
+
1773
+ describe "root tracking via __root__" do
1774
+ it "works through hash keys" do
1775
+ node.default["foo"] = { "bar" => { "baz" => "qux" } }
1776
+ expect(node["foo"]["bar"].__root__).to eql(node.attributes)
1777
+ end
1778
+
1779
+ it "works through the default level" do
1780
+ node.default["foo"] = { "bar" => { "baz" => "qux" } }
1781
+ expect(node.default["foo"]["bar"].__root__).to eql(node.attributes)
1782
+ end
1783
+
1784
+ it "works through arrays" do
1785
+ node.default["foo"] = [ { "bar" => { "baz" => "qux" } } ]
1786
+ expect(node["foo"][0].__root__).to eql(node.attributes)
1787
+ expect(node["foo"][0]["bar"].__root__).to eql(node.attributes)
1788
+ end
1789
+
1790
+ it "works through arrays at the default level" do
1791
+ node.default["foo"] = [ { "bar" => { "baz" => "qux" } } ]
1792
+ expect(node.default["foo"][0].__root__).to eql(node.attributes)
1793
+ expect(node.default["foo"][0]["bar"].__root__).to eql(node.attributes)
1794
+ end
1795
+ end
1796
+
1797
+ describe "ways of abusing Chef 12 node state" do
1798
+ # these tests abuse the top_level_breadcrumb state in Chef 12
1799
+ it "derived attributes work correctly" do
1800
+ node.default["v1"] = 1
1801
+ expect(node["a"]).to eql(nil)
1802
+ node.default["a"] = node["v1"]
1803
+ expect(node["a"]).to eql(1)
1804
+ end
1805
+
1806
+ it "works when saving nodes to variables" do
1807
+ a = node.default["a"]
1808
+ expect(node["a"]).to eql({})
1809
+ node.default["b"] = 0
1810
+ a["key"] = 1
1811
+
1812
+ expect(node["a"]["key"]).to eql(1)
1813
+ end
1814
+ end
1684
1815
  end
@@ -556,7 +556,7 @@ describe Chef::Provider::Deploy do
556
556
  @resource.deploy_to("/my/app")
557
557
  expect(mock_execution).to receive(:user).with("notCoolMan")
558
558
  expect(mock_execution).to receive(:group).with("Ggroup")
559
- expect(mock_execution).to receive(:cwd) {|*args|
559
+ expect(mock_execution).to receive(:cwd) { |*args|
560
560
  if args.empty?
561
561
  nil
562
562
  else
@@ -0,0 +1,90 @@
1
+ #
2
+ # Author:: Tom Duffield (<tom@chef.io>)
3
+ # Copyright:: Copyright 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::Group::Suse 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_members) { %w{root new_user} }
26
+ let(:new_resource) do
27
+ Chef::Resource::Group.new("new_group").tap do |r|
28
+ r.gid 50
29
+ r.members new_members
30
+ r.system false
31
+ r.non_unique false
32
+ end
33
+ end
34
+ let(:current_resource) do
35
+ Chef::Resource::Group.new("new_group").tap do |r|
36
+ r.gid 50
37
+ r.members %w{root}
38
+ r.system false
39
+ r.non_unique false
40
+ end
41
+ end
42
+ let(:provider) do
43
+ described_class.new(new_resource, run_context).tap do |p|
44
+ p.current_resource = current_resource
45
+ end
46
+ end
47
+
48
+ describe "when determining the current group state" do
49
+ before(:each) do
50
+ allow(File).to receive(:exists?).and_return(true)
51
+ provider.action = :create
52
+ provider.define_resource_requirements
53
+ end
54
+
55
+ # Checking for required binaries is already done in the spec
56
+ # for Chef::Provider::Group - no need to repeat it here. We'll
57
+ # include only what's specific to this provider.
58
+ it "should raise an error if the required binary /usr/sbin/groupmod doesn't exist" do
59
+ expect(File).to receive(:exists?).with("/usr/sbin/groupmod").and_return(false)
60
+ expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Group)
61
+ end
62
+
63
+ it "should raise error if one of the member users does not exist" do
64
+ expect(Etc).to receive(:getpwnam).with("new_user").and_raise ArgumentError
65
+ expect { provider.process_resource_requirements }.to raise_error(Chef::Exceptions::Group)
66
+ end
67
+ end
68
+
69
+ describe "#set_members" do
70
+ it "should add missing members and remove deleted members" do
71
+ expect(provider).not_to receive(:remove_member)
72
+ expect(provider).to receive(:add_member).with("new_user")
73
+ provider.set_members(new_members)
74
+ end
75
+ end
76
+
77
+ describe "#add_member" do
78
+ it "should call out to groupmod to add user" do
79
+ expect(provider).to receive(:shell_out!).with("groupmod -A new_user new_group")
80
+ provider.add_member("new_user")
81
+ end
82
+ end
83
+
84
+ describe "#remove_member" do
85
+ it "should call out to groupmod to remove user" do
86
+ expect(provider).to receive(:shell_out!).with("groupmod -R new_user new_group")
87
+ provider.remove_member("new_user")
88
+ end
89
+ end
90
+ end
@@ -395,6 +395,28 @@ mpg123 1.12.1-0ubuntu1
395
395
  end
396
396
  end
397
397
 
398
+ describe "when locking a package" do
399
+ it "should run apt-mark hold package" do
400
+ expect(@provider).to receive(:shell_out!).with(
401
+ "apt-mark hold irssi",
402
+ :env => { "DEBIAN_FRONTEND" => "noninteractive" },
403
+ :timeout => @timeout
404
+ )
405
+ @provider.lock_package("irssi", "0.8.12-7")
406
+ end
407
+ end
408
+
409
+ describe "when unlocking a package" do
410
+ it "should run apt-mark unhold package" do
411
+ expect(@provider).to receive(:shell_out!).with(
412
+ "apt-mark unhold irssi",
413
+ :env => { "DEBIAN_FRONTEND" => "noninteractive" },
414
+ :timeout => @timeout
415
+ )
416
+ @provider.unlock_package("irssi", "0.8.12-7")
417
+ end
418
+ end
419
+
398
420
  describe "when installing a virtual package" do
399
421
  it "should install the package without specifying a version" do
400
422
  @provider.package_data["libmysqlclient15-dev"][:virtual] = true
@@ -121,7 +121,7 @@ describe Chef::Provider::Package::Windows::MSI do
121
121
  end
122
122
 
123
123
  it "removes installed package" do
124
- expect(provider).to receive(:shell_out!).with(/MsiExec.exe \/X{guid} \/Q/, kind_of(Hash))
124
+ expect(provider).to receive(:shell_out!).with(/msiexec \/x {guid} \/q/, kind_of(Hash))
125
125
  provider.remove_package
126
126
  end
127
127
 
@@ -140,8 +140,8 @@ describe Chef::Provider::Package::Windows::MSI do
140
140
  end
141
141
 
142
142
  it "removes both installed package" do
143
- expect(provider).to receive(:shell_out!).with(/MsiExec.exe \/X{guid} \/Q/, kind_of(Hash))
144
- expect(provider).to receive(:shell_out!).with(/MsiExec.exe \/X{guid2} \/Q/, kind_of(Hash))
143
+ expect(provider).to receive(:shell_out!).with(/msiexec \/x {guid} \/q/, kind_of(Hash))
144
+ expect(provider).to receive(:shell_out!).with(/msiexec \/x {guid2} \/q/, kind_of(Hash))
145
145
  provider.remove_package
146
146
  end
147
147
  end
@@ -150,7 +150,16 @@ describe Chef::Provider::Package::Windows::MSI do
150
150
  before { new_resource.options("/Q") }
151
151
 
152
152
  it "does not duplicate quiet switch" do
153
- expect(provider).to receive(:shell_out!).with(/MsiExec.exe \/X{guid} \/Q/, kind_of(Hash))
153
+ expect(provider).to receive(:shell_out!).with(/msiexec \/x {guid} \/Q/, kind_of(Hash))
154
+ provider.remove_package
155
+ end
156
+ end
157
+
158
+ context "custom options includes /qn" do
159
+ before { new_resource.options("/qn") }
160
+
161
+ it "does not duplicate quiet switch" do
162
+ expect(provider).to receive(:shell_out!).with(/msiexec \/x {guid} \/qn/, kind_of(Hash))
154
163
  provider.remove_package
155
164
  end
156
165
  end
@@ -26,9 +26,9 @@ describe Chef::Provider::Package::Windows, :windows_only do
26
26
  allow(Chef::FileCache).to receive(:create_cache_path).with("package/").and_return(cache_path)
27
27
  end
28
28
 
29
- let(:node) { double("Chef::Node") }
30
- let(:events) { double("Chef::Events").as_null_object } # mock all the methods
31
- let(:run_context) { double("Chef::RunContext", :node => node, :events => events) }
29
+ let(:node) { Chef::Node.new }
30
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
31
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
32
32
  let(:resource_source) { "calculator.msi" }
33
33
  let(:resource_name) { "calculator" }
34
34
  let(:installer_type) { nil }
@@ -785,6 +785,24 @@ describe Chef::Provider::Package::Yum do
785
785
  end
786
786
  end
787
787
 
788
+ describe "when locking a package" do
789
+ it "should run yum versionlock add with the package name" do
790
+ expect(@provider).to receive(:yum_command).with(
791
+ "-d0 -e0 -y versionlock add emacs"
792
+ )
793
+ @provider.lock_package("emacs", nil)
794
+ end
795
+ end
796
+
797
+ describe "when unlocking a package" do
798
+ it "should run yum versionlock delete with the package name" do
799
+ expect(@provider).to receive(:yum_command).with(
800
+ "-d0 -e0 -y versionlock delete emacs"
801
+ )
802
+ @provider.unlock_package("emacs", nil)
803
+ end
804
+ end
805
+
788
806
  describe "when running yum" do
789
807
  it "should run yum once if it exits with a return code of 0" do
790
808
  @status = double("Status", :exitstatus => 0, :stdout => "", :stderr => "")
@@ -231,6 +231,70 @@ describe Chef::Provider::Package::Zypper do
231
231
  end
232
232
  end
233
233
 
234
+ describe "lock_package" do
235
+ it "should run zypper addlock with the package name" do
236
+ allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(true)
237
+ shell_out_expectation!(
238
+ "zypper --non-interactive addlock emacs"
239
+ )
240
+ provider.lock_package(["emacs"], [nil])
241
+ end
242
+ it "should run zypper addlock without gpg checks" do
243
+ allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(false)
244
+ shell_out_expectation!(
245
+ "zypper --non-interactive --no-gpg-checks addlock emacs"
246
+ )
247
+ provider.lock_package(["emacs"], [nil])
248
+ end
249
+ it "should warn about gpg checks on zypper addlock" do
250
+ expect(Chef::Log).to receive(:warn).with(
251
+ /All packages will be installed without gpg signature checks/
252
+ )
253
+ shell_out_expectation!(
254
+ "zypper --non-interactive --no-gpg-checks addlock emacs"
255
+ )
256
+ provider.lock_package(["emacs"], [nil])
257
+ end
258
+ it "should run zypper addlock without gpg checks" do
259
+ shell_out_expectation!(
260
+ "zypper --non-interactive --no-gpg-checks addlock emacs"
261
+ )
262
+ provider.lock_package(["emacs"], [nil])
263
+ end
264
+ end
265
+
266
+ describe "unlock_package" do
267
+ it "should run zypper removelock with the package name" do
268
+ allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(true)
269
+ shell_out_expectation!(
270
+ "zypper --non-interactive removelock emacs"
271
+ )
272
+ provider.unlock_package(["emacs"], [nil])
273
+ end
274
+ it "should run zypper removelock without gpg checks" do
275
+ allow(Chef::Config).to receive(:[]).with(:zypper_check_gpg).and_return(false)
276
+ shell_out_expectation!(
277
+ "zypper --non-interactive --no-gpg-checks removelock emacs"
278
+ )
279
+ provider.unlock_package(["emacs"], [nil])
280
+ end
281
+ it "should warn about gpg checks on zypper removelock" do
282
+ expect(Chef::Log).to receive(:warn).with(
283
+ /All packages will be installed without gpg signature checks/
284
+ )
285
+ shell_out_expectation!(
286
+ "zypper --non-interactive --no-gpg-checks removelock emacs"
287
+ )
288
+ provider.unlock_package(["emacs"], [nil])
289
+ end
290
+ it "should run zypper removelock without gpg checks" do
291
+ shell_out_expectation!(
292
+ "zypper --non-interactive --no-gpg-checks removelock emacs"
293
+ )
294
+ provider.unlock_package(["emacs"], [nil])
295
+ end
296
+ end
297
+
234
298
  describe "on an older zypper" do
235
299
  before(:each) do
236
300
  allow(provider).to receive(:`).and_return("0.11.6")
@@ -321,6 +321,56 @@ describe Chef::Provider::Package do
321
321
  end
322
322
  end
323
323
 
324
+ describe "When locking the package" do
325
+ before(:each) do
326
+ allow(provider).to receive(:lock_package).and_return(true)
327
+ end
328
+
329
+ it "should lock the package if it is unlocked" do
330
+ allow(provider).to receive(:package_locked).and_return(false)
331
+ expect(provider).to receive(:lock_package)
332
+ provider.run_action(:lock)
333
+ end
334
+
335
+ it "should not lock the package if it is already locked" do
336
+ allow(provider).to receive(:package_locked).and_return(true)
337
+ expect(provider).not_to receive(:lock_package)
338
+ provider.run_action(:lock)
339
+ expect(new_resource).not_to be_updated_by_last_action
340
+ end
341
+
342
+ it "should set the resource to updated if it locks the package" do
343
+ allow(provider).to receive(:package_locked).and_return(false)
344
+ provider.run_action(:lock)
345
+ expect(new_resource).to be_updated
346
+ end
347
+ end
348
+
349
+ describe "When unlocking the package" do
350
+ before(:each) do
351
+ allow(provider).to receive(:unlock_package).and_return(true)
352
+ end
353
+
354
+ it "should unlock the package if it is locked" do
355
+ allow(provider).to receive(:package_locked).and_return(true)
356
+ expect(provider).to receive(:unlock_package)
357
+ provider.run_action(:unlock)
358
+ end
359
+
360
+ it "should not unlock the package if it is already unlocked" do
361
+ allow(provider).to receive(:package_locked).and_return(false)
362
+ expect(provider).not_to receive(:unlock_package)
363
+ provider.run_action(:unlock)
364
+ expect(new_resource).not_to be_updated_by_last_action
365
+ end
366
+
367
+ it "should set the resource to updated if it unlocks the package" do
368
+ allow(provider).to receive(:package_locked).and_return(true)
369
+ provider.run_action(:unlock)
370
+ expect(new_resource).to be_updated
371
+ end
372
+ end
373
+
324
374
  describe "when running commands to be implemented by subclasses" do
325
375
  it "should raises UnsupportedAction for install" do
326
376
  expect { provider.install_package("emacs", "1.4.2") }.to raise_error(Chef::Exceptions::UnsupportedAction)
@@ -346,6 +396,14 @@ describe Chef::Provider::Package do
346
396
  it "should raise UnsupportedAction for reconfig" do
347
397
  expect { provider.reconfig_package("emacs", "1.4.2") }.to raise_error(Chef::Exceptions::UnsupportedAction)
348
398
  end
399
+
400
+ it "should raise UnsupportedAction for lock" do
401
+ expect { provider.lock_package("emacs", nil) }.to raise_error(Chef::Exceptions::UnsupportedAction)
402
+ end
403
+
404
+ it "should raise UnsupportedAction for unlock" do
405
+ expect { provider.unlock_package("emacs", nil) }.to raise_error(Chef::Exceptions::UnsupportedAction)
406
+ end
349
407
  end
350
408
 
351
409
  describe "when given a response file" do