chef 18.2.7 → 18.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/chef-universal-mingw-ucrt.gemspec +1 -1
  4. data/chef.gemspec +3 -3
  5. data/lib/chef/application/base.rb +2 -0
  6. data/lib/chef/chef_fs/file_pattern.rb +1 -1
  7. data/lib/chef/chef_fs/path_utils.rb +7 -9
  8. data/lib/chef/client.rb +2 -2
  9. data/lib/chef/cookbook/synchronizer.rb +19 -2
  10. data/lib/chef/cookbook_version.rb +1 -1
  11. data/lib/chef/delayed_evaluator.rb +4 -0
  12. data/lib/chef/file_access_control/windows.rb +4 -1
  13. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +2 -0
  14. data/lib/chef/http/ssl_policies.rb +2 -2
  15. data/lib/chef/mixin/homebrew_user.rb +15 -5
  16. data/lib/chef/monkey_patches/net-http.rb +127 -0
  17. data/lib/chef/node/attribute_collections.rb +10 -1
  18. data/lib/chef/node/immutable_collections.rb +7 -3
  19. data/lib/chef/node/mixin/state_tracking.rb +1 -1
  20. data/lib/chef/node/mixin/state_tracking_array.rb +41 -0
  21. data/lib/chef/node.rb +22 -0
  22. data/lib/chef/provider/launchd.rb +1 -1
  23. data/lib/chef/provider/mount/linux.rb +1 -1
  24. data/lib/chef/provider/mount/mount.rb +5 -5
  25. data/lib/chef/provider/package/apt.rb +11 -2
  26. data/lib/chef/provider/package/chocolatey.rb +239 -18
  27. data/lib/chef/provider/package/zypper.rb +6 -0
  28. data/lib/chef/provider/powershell_script.rb +96 -6
  29. data/lib/chef/provider/remote_file/http.rb +1 -1
  30. data/lib/chef/provider/service/systemd.rb +23 -8
  31. data/lib/chef/provider/service/windows.rb +1 -0
  32. data/lib/chef/provider/service.rb +14 -0
  33. data/lib/chef/provider/user.rb +5 -1
  34. data/lib/chef/provider/yum_repository.rb +1 -1
  35. data/lib/chef/recipe.rb +3 -11
  36. data/lib/chef/resource/_rest_resource.rb +1 -1
  37. data/lib/chef/resource/apt_package.rb +19 -0
  38. data/lib/chef/resource/apt_repository.rb +26 -6
  39. data/lib/chef/resource/chef_client_systemd_timer.rb +1 -1
  40. data/lib/chef/resource/chocolatey_installer.rb +207 -0
  41. data/lib/chef/resource/chocolatey_package.rb +8 -0
  42. data/lib/chef/resource/homebrew_cask.rb +6 -7
  43. data/lib/chef/resource/homebrew_package.rb +1 -1
  44. data/lib/chef/resource/homebrew_tap.rb +5 -5
  45. data/lib/chef/resource/launchd.rb +5 -1
  46. data/lib/chef/resource/locale.rb +5 -2
  47. data/lib/chef/resource/macos_pkg.rb +111 -0
  48. data/lib/chef/resource/powershell_script.rb +5 -1
  49. data/lib/chef/resource/service.rb +3 -0
  50. data/lib/chef/resource/sudo.rb +37 -2
  51. data/lib/chef/resource/support/ulimit.erb +40 -0
  52. data/lib/chef/resource/user_ulimit.rb +38 -0
  53. data/lib/chef/resource/windows_certificate.rb +1 -1
  54. data/lib/chef/resource/windows_security_policy.rb +2 -2
  55. data/lib/chef/resource.rb +11 -1
  56. data/lib/chef/resources.rb +2 -0
  57. data/lib/chef/version.rb +1 -1
  58. data/lib/chef/win32/security.rb +7 -1
  59. data/spec/data/trusted_certs/example.crt +29 -20
  60. data/spec/data/trusted_certs/example_no_cn.crt +30 -34
  61. data/spec/functional/resource/chocolatey_package_spec.rb +32 -20
  62. data/spec/functional/resource/execute_spec.rb +1 -1
  63. data/spec/functional/resource/windows_certificate_spec.rb +25 -0
  64. data/spec/functional/resource/zypper_package_spec.rb +10 -0
  65. data/spec/unit/client_spec.rb +2 -2
  66. data/spec/unit/compliance/reporter/chef_server_automate_spec.rb +1 -1
  67. data/spec/unit/delayed_evaluator_spec.rb +35 -0
  68. data/spec/unit/mixin/homebrew_user_spec.rb +30 -7
  69. data/spec/unit/node/vivid_mash_spec.rb +42 -0
  70. data/spec/unit/node_spec.rb +6 -0
  71. data/spec/unit/provider/apt_repository_spec.rb +17 -7
  72. data/spec/unit/provider/launchd_spec.rb +2 -2
  73. data/spec/unit/provider/mount/aix_spec.rb +2 -2
  74. data/spec/unit/provider/mount/linux_spec.rb +6 -5
  75. data/spec/unit/provider/mount/mount_spec.rb +8 -8
  76. data/spec/unit/provider/package/apt_spec.rb +18 -13
  77. data/spec/unit/provider/package/chocolatey_spec.rb +53 -9
  78. data/spec/unit/provider/package/rpm_spec.rb +2 -2
  79. data/spec/unit/provider/package/zypper_spec.rb +10 -0
  80. data/spec/unit/provider/powershell_script_spec.rb +100 -4
  81. data/spec/unit/provider/remote_file/http_spec.rb +4 -4
  82. data/spec/unit/provider/service/systemd_service_spec.rb +1 -0
  83. data/spec/unit/provider/user/linux_spec.rb +10 -0
  84. data/spec/unit/resource/apt_repository_spec.rb +5 -0
  85. data/spec/unit/resource/chef_client_systemd_timer_spec.rb +1 -1
  86. data/spec/unit/resource/chocolatey_installer_spec.rb +151 -0
  87. data/spec/unit/resource/macos_pkg_spec.rb +38 -0
  88. data/spec/unit/resource/powershell_script_spec.rb +2 -2
  89. data/spec/unit/resource_spec.rb +86 -0
  90. metadata +29 -16
  91. /data/spec/functional/assets/chocolatey_feed/{test-A.1.0.nupkg → test-A.1.0.0.nupkg} +0 -0
  92. /data/spec/functional/assets/chocolatey_feed/{test-A.1.5.nupkg → test-A.1.5.0.nupkg} +0 -0
  93. /data/spec/functional/assets/chocolatey_feed/{test-A.2.0.nupkg → test-A.2.0.0.nupkg} +0 -0
  94. /data/spec/functional/assets/chocolatey_feed/{test-B.1.0.nupkg → test-B.1.0.0.nupkg} +0 -0
@@ -170,7 +170,7 @@ describe Chef::Compliance::Reporter::ChefServerAutomate do
170
170
  "X-Ops-Userid" => "spec-node",
171
171
  "X-Remote-Request-Id" => /.+/,
172
172
  }
173
- ).to_return(status: 200)
173
+ ).to_return(status: 200, body: "OK")
174
174
 
175
175
  expect(reporter.send_report(inspec_report)).to eq(true)
176
176
 
@@ -0,0 +1,35 @@
1
+ #
2
+ # Copyright:: Copyright (c) Progress Software Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require "spec_helper"
19
+
20
+ describe Chef::DelayedEvaluator do
21
+ let(:magic) { "This is magic!" }
22
+ let(:de) { Chef::DelayedEvaluator.new { magic } }
23
+
24
+ describe "#inspect" do
25
+ it "inspects the result rather than the Proc" do
26
+ expect(de.inspect).to eq("lazy { (evaluates to) #{magic.inspect} }")
27
+ end
28
+ end
29
+
30
+ describe "#call" do
31
+ it "evaluates correctly" do
32
+ expect(de.call).to eq(magic)
33
+ end
34
+ end
35
+ end
@@ -47,6 +47,8 @@ describe Chef::Mixin::HomebrewUser do
47
47
  let(:user) { nil }
48
48
  let(:brew_owner) { 2001 }
49
49
  let(:default_brew_path) { "/usr/local/bin/brew" }
50
+ let(:default_brew_path_arm) { "/opt/homebrew/bin/brew" }
51
+ let(:default_brew_path_linux) { "/home/linuxbrew/.linuxbrew/bin/brew" }
50
52
  let(:stat_double) do
51
53
  d = double
52
54
  expect(d).to receive(:uid).and_return(brew_owner)
@@ -59,16 +61,38 @@ describe Chef::Mixin::HomebrewUser do
59
61
  expect(Etc).to receive(:getpwuid).with(brew_owner).and_return(OpenStruct.new(name: "name"))
60
62
  end
61
63
 
62
- it "returns the owner of the brew executable when it is at a default location" do
63
- expect(File).to receive(:exist?).with(default_brew_path).and_return(true)
64
- expect(File).to receive(:stat).with(default_brew_path).and_return(stat_double)
64
+ def false_unless_specific_value(object, method, value)
65
+ allow(object).to receive(method).and_return(false)
66
+ allow(object).to receive(method).with(value).and_return(true)
67
+ end
68
+
69
+ it "returns the owner of the brew executable when it is at a default location for x86_64 machines" do
70
+ false_unless_specific_value(File, :exist?, default_brew_path)
71
+ false_unless_specific_value(File, :executable?, default_brew_path)
72
+ allow(File).to receive(:stat).with(default_brew_path).and_return(stat_double)
73
+ expect(homebrew_user.find_homebrew_uid(user)).to eq(brew_owner)
74
+ end
75
+
76
+ it "returns the owner of the brew executable when it is at a default location for arm machines" do
77
+ false_unless_specific_value(File, :exist?, default_brew_path_arm)
78
+ false_unless_specific_value(File, :executable?, default_brew_path_arm)
79
+ allow(File).to receive(:stat).with(default_brew_path_arm).and_return(stat_double)
80
+ expect(homebrew_user.find_homebrew_uid(user)).to eq(brew_owner)
81
+ end
82
+
83
+ it "returns the owner of the brew executable when it is at a default location for linux machines" do
84
+ false_unless_specific_value(File, :exist?, default_brew_path_linux)
85
+ false_unless_specific_value(File, :executable?, default_brew_path_linux)
86
+ allow(File).to receive(:stat).with(default_brew_path_linux).and_return(stat_double)
65
87
  expect(homebrew_user.find_homebrew_uid(user)).to eq(brew_owner)
66
88
  end
67
89
 
68
90
  it "returns the owner of the brew executable when it is not at a default location" do
69
- expect(File).to receive(:exist?).with(default_brew_path).and_return(false)
91
+ allow_any_instance_of(ExampleHomebrewUser).to receive(:which).and_return("/foo")
92
+ false_unless_specific_value(File, :exist?, "/foo")
93
+ false_unless_specific_value(File, :executable?, "/foo")
70
94
  allow(homebrew_user).to receive_message_chain(:shell_out, :stdout, :strip).and_return("/foo")
71
- expect(File).to receive(:stat).with("/foo").and_return(stat_double)
95
+ allow(File).to receive(:stat).with("/foo").and_return(stat_double)
72
96
  expect(homebrew_user.find_homebrew_uid(user)).to eq(brew_owner)
73
97
  end
74
98
 
@@ -78,8 +102,7 @@ describe Chef::Mixin::HomebrewUser do
78
102
  describe "when the homebrew user is not provided" do
79
103
 
80
104
  it "raises an error if no executable is found" do
81
- expect(File).to receive(:exist?).with(default_brew_path).and_return(false)
82
- allow(homebrew_user).to receive_message_chain(:shell_out, :stdout, :strip).and_return("")
105
+ expect(File).to receive(:exist?).and_return(nil).at_least(:once)
83
106
  expect { homebrew_user.find_homebrew_uid(user) }.to raise_error(Chef::Exceptions::CannotDetermineHomebrewOwner)
84
107
  end
85
108
 
@@ -364,20 +364,53 @@ describe Chef::Node::AttrArray do
364
364
 
365
365
  context "#<<" do
366
366
  it "converts a Hash appended with #<< to a VividMash" do
367
+ expect(root).to receive(:reset_cache).with(nil)
367
368
  array << { "three" => "four" }
368
369
  expect(array[3].class).to eql(Chef::Node::VividMash)
369
370
  end
370
371
 
371
372
  it "deeply converts objects appended with #<<" do
373
+ expect(root).to receive(:reset_cache).with(nil)
372
374
  array << [ { "three" => [ 0, 1] } ]
373
375
  expect(array[3].class).to eql(Chef::Node::AttrArray)
374
376
  expect(array[3][0].class).to eql(Chef::Node::VividMash)
375
377
  expect(array[3][0]["three"].class).to eql(Chef::Node::AttrArray)
376
378
  end
379
+
380
+ it "does not invalidate root DeepMergeCache if VividMash top-level key" do
381
+ # We're checking that __path__ is used to avoid full DeepMergeCache invalidation
382
+ expect(root).to receive(:reset_cache).with("array")
383
+ expect(root).not_to receive(:reset_cache).with(nil)
384
+
385
+ attr_array = Chef::Node::AttrArray.new([ 0, 1, 2 ])
386
+ vivid = Chef::Node::VividMash.new(
387
+ { "one" => { "two" => { "three" => "four" } }, "array" => attr_array },
388
+ root
389
+ )
390
+ vivid["array"] << 3
391
+ end
392
+
393
+ it "does not send reset_cache with nil if VividMashi nested key" do
394
+ # We're checking that __path__ is used to avoid full DeepMergeCache invalidation,
395
+ # and that it is invalidating the top-level key
396
+ expect(root).to receive(:reset_cache).with("array")
397
+ expect(root).not_to receive(:reset_cache).with(nil)
398
+
399
+ attr_array = Chef::Node::AttrArray.new([ 0, 1, 2 ])
400
+ vivid = Chef::Node::VividMash.new(
401
+ {
402
+ "one" => { "two" => { "three" => "four" } },
403
+ "array" => { "nested" => attr_array },
404
+ },
405
+ root
406
+ )
407
+ vivid["array"]["nested"] << 3
408
+ end
377
409
  end
378
410
 
379
411
  context "#[]=" do
380
412
  it "assigning a Hash into an array converts it to VividMash" do
413
+ expect(root).to receive(:reset_cache).with(nil)
381
414
  array[0] = { "zero" => "zero2" }
382
415
  expect(array[0].class).to eql(Chef::Node::VividMash)
383
416
  end
@@ -385,6 +418,7 @@ describe Chef::Node::AttrArray do
385
418
 
386
419
  context "#push" do
387
420
  it "pushing a Hash into an array converts it to VividMash" do
421
+ expect(root).to receive(:reset_cache).with(nil)
388
422
  array.push({ "three" => "four" })
389
423
  expect(array[3].class).to eql(Chef::Node::VividMash)
390
424
  end
@@ -392,6 +426,7 @@ describe Chef::Node::AttrArray do
392
426
 
393
427
  context "#unshift" do
394
428
  it "unshifting a Hash into an array converts it to VividMash" do
429
+ expect(root).to receive(:reset_cache).with(nil)
395
430
  array.unshift({ "zero" => "zero2" })
396
431
  expect(array[0].class).to eql(Chef::Node::VividMash)
397
432
  end
@@ -399,6 +434,7 @@ describe Chef::Node::AttrArray do
399
434
 
400
435
  context "#insert" do
401
436
  it "inserting a Hash into an array converts it to VividMash" do
437
+ expect(root).to receive(:reset_cache).with(nil)
402
438
  array.insert(1, { "zero" => "zero2" })
403
439
  expect(array[1].class).to eql(Chef::Node::VividMash)
404
440
  end
@@ -406,6 +442,7 @@ describe Chef::Node::AttrArray do
406
442
 
407
443
  context "#collect!" do
408
444
  it "converts Hashes" do
445
+ expect(root).to receive(:reset_cache).at_least(:once).with(nil)
409
446
  array.collect! { |x| { "zero" => "zero2" } }
410
447
  expect(array[1].class).to eql(Chef::Node::VividMash)
411
448
  end
@@ -413,6 +450,7 @@ describe Chef::Node::AttrArray do
413
450
 
414
451
  context "#map!" do
415
452
  it "converts Hashes" do
453
+ expect(root).to receive(:reset_cache).with(nil)
416
454
  array.map! { |x| { "zero" => "zero2" } }
417
455
  expect(array[1].class).to eql(Chef::Node::VividMash)
418
456
  end
@@ -420,6 +458,7 @@ describe Chef::Node::AttrArray do
420
458
 
421
459
  context "#compact!" do
422
460
  it "VividMashes remain VividMashes" do
461
+ expect(root).to receive(:reset_cache).with(nil)
423
462
  array = Chef::Node::AttrArray.new(
424
463
  [ nil, { "one" => "two" }, nil ],
425
464
  root
@@ -432,6 +471,7 @@ describe Chef::Node::AttrArray do
432
471
 
433
472
  context "#fill" do
434
473
  it "inserts VividMashes for Hashes" do
474
+ expect(root).to receive(:reset_cache).at_least(:once).with(nil)
435
475
  array.fill({ "one" => "two" })
436
476
  expect(array[0].class).to eql(Chef::Node::VividMash)
437
477
  end
@@ -439,6 +479,7 @@ describe Chef::Node::AttrArray do
439
479
 
440
480
  context "#flatten!" do
441
481
  it "flattens sub-arrays maintaining VividMashes in them" do
482
+ expect(root).to receive(:reset_cache).with(nil)
442
483
  array = Chef::Node::AttrArray.new(
443
484
  [ [ { "one" => "two" } ], [ { "one" => "two" } ] ],
444
485
  root
@@ -451,6 +492,7 @@ describe Chef::Node::AttrArray do
451
492
 
452
493
  context "#replace" do
453
494
  it "replaces the array converting hashes to mashes" do
495
+ expect(root).to receive(:reset_cache).with(nil)
454
496
  array.replace([ { "foo" => "bar" } ])
455
497
  expect(array[0].class).to eql(Chef::Node::VividMash)
456
498
  end
@@ -303,6 +303,12 @@ describe Chef::Node do
303
303
  expect(node["tags"]).to eq(%w{one two three four})
304
304
  end
305
305
 
306
+ it "should let you use untag as a convince method for the tags attribute" do
307
+ node.normal["tags"] = %w{one two three four}
308
+ node.untag("three", "four")
309
+ expect(node["tags"]).to eq(%w{one two})
310
+ end
311
+
306
312
  it "normal_unless sets a value even if default or override attrs are set" do
307
313
  node.default[:decontamination] = true
308
314
  node.override[:decontamination] = false
@@ -246,33 +246,43 @@ C5986B4F1257FFA86632CBA746181433FBB75451
246
246
  describe "#build_repo" do
247
247
  it "creates a repository string" do
248
248
  target = "deb http://test/uri unstable main\n"
249
- expect(provider.build_repo("http://test/uri", "unstable", "main", false, nil)).to eql(target)
249
+ expect(provider.build_repo("http://test/uri", "unstable", "main", false, nil, [])).to eql(target)
250
250
  end
251
251
 
252
252
  it "creates a repository string with spaces" do
253
253
  target = "deb http://test/uri%20with%20spaces unstable main\n"
254
- expect(provider.build_repo("http://test/uri with spaces", "unstable", "main", false, nil)).to eql(target)
254
+ expect(provider.build_repo("http://test/uri with spaces", "unstable", "main", false, nil, [])).to eql(target)
255
255
  end
256
256
 
257
257
  it "creates a repository string with no distribution" do
258
258
  target = "deb http://test/uri main\n"
259
- expect(provider.build_repo("http://test/uri", nil, "main", false, nil)).to eql(target)
259
+ expect(provider.build_repo("http://test/uri", nil, "main", false, nil, [])).to eql(target)
260
260
  end
261
261
 
262
262
  it "creates a repository string with source" do
263
263
  target = "deb http://test/uri unstable main\ndeb-src http://test/uri unstable main\n"
264
- expect(provider.build_repo("http://test/uri", "unstable", "main", false, nil, true)).to eql(target)
264
+ expect(provider.build_repo("http://test/uri", "unstable", "main", false, nil, [], true)).to eql(target)
265
265
  end
266
266
 
267
- it "creates a repository string with options" do
267
+ it "creates a repository string with trusted" do
268
268
  target = "deb [trusted=yes] http://test/uri unstable main\n"
269
- expect(provider.build_repo("http://test/uri", "unstable", "main", true, nil)).to eql(target)
269
+ expect(provider.build_repo("http://test/uri", "unstable", "main", true, nil, [])).to eql(target)
270
+ end
271
+
272
+ it "creates a repository string with custom options" do
273
+ target = "deb [by-hash=no] http://test/uri unstable main\n"
274
+ expect(provider.build_repo("http://test/uri", "unstable", "main", false, nil, ["by-hash=no"])).to eql(target)
275
+ end
276
+
277
+ it "creates a repository string with trusted, arch, and custom options" do
278
+ target = "deb [arch=amd64 trusted=yes by-hash=no] http://test/uri unstable main\n"
279
+ expect(provider.build_repo("http://test/uri", "unstable", "main", true, "amd64", ["by-hash=no"])).to eql(target)
270
280
  end
271
281
 
272
282
  it "handles a ppa repo" do
273
283
  target = "deb http://ppa.launchpad.net/chef/main/ubuntu unstable main\n"
274
284
  expect(provider).to receive(:make_ppa_url).with("ppa:chef/main").and_return("http://ppa.launchpad.net/chef/main/ubuntu")
275
- expect(provider.build_repo("ppa:chef/main", "unstable", "main", false, nil)).to eql(target)
285
+ expect(provider.build_repo("ppa:chef/main", "unstable", "main", false, nil, [])).to eql(target)
276
286
  end
277
287
  end
278
288
  end
@@ -197,7 +197,7 @@ describe Chef::Provider::Launchd do
197
197
  describe "with an :delete action" do
198
198
  describe "and the ld file is present" do
199
199
  before(:each) do
200
- allow(File).to receive(:exists?).and_return(true)
200
+ allow(File).to receive(:exist?).and_return(true)
201
201
  allow(provider).to receive(
202
202
  :manage_service
203
203
  ).with(:disable).and_return(true)
@@ -218,7 +218,7 @@ describe Chef::Provider::Launchd do
218
218
 
219
219
  describe "and the ld file is not present" do
220
220
  before(:each) do
221
- allow(File).to receive(:exists?).and_return(false)
221
+ allow(File).to receive(:exist?).and_return(false)
222
222
  allow(provider).to receive(
223
223
  :manage_plist
224
224
  ).with(:delete).and_return(true)
@@ -65,8 +65,8 @@ describe Chef::Provider::Mount::Aix do
65
65
 
66
66
  @provider = Chef::Provider::Mount::Aix.new(@new_resource, @run_context)
67
67
 
68
- allow(::File).to receive(:exists?).with("/dev/sdz1").and_return true
69
- allow(::File).to receive(:exists?).with("/tmp/foo").and_return true
68
+ allow(::File).to receive(:exist?).with("/dev/sdz1").and_return true
69
+ allow(::File).to receive(:exist?).with("/tmp/foo").and_return true
70
70
  end
71
71
 
72
72
  def stub_mounted(provider, mounted_output)
@@ -22,10 +22,11 @@ describe Chef::Provider::Mount::Linux do
22
22
  end
23
23
 
24
24
  before(:each) do
25
- allow(::File).to receive(:exists?).with("/dev/sdz1").and_return true
26
- allow(::File).to receive(:exists?).with("/tmp/foo").and_return true
27
- allow(::File).to receive(:exists?).with("//192.168.11.102/Share/backup").and_return true
28
- allow(::File).to receive(:exists?).with("//192.168.11.102/Share/backup folder").and_return true
25
+ allow(::File).to receive(:exist?).with("/etc/fstab").and_call_original
26
+ allow(::File).to receive(:exist?).with("/dev/sdz1").and_return true
27
+ allow(::File).to receive(:exist?).with("/tmp/foo").and_return true
28
+ allow(::File).to receive(:exist?).with("//192.168.11.102/Share/backup").and_return true
29
+ allow(::File).to receive(:exist?).with("//192.168.11.102/Share/backup folder").and_return true
29
30
  allow(::File).to receive(:realpath).with("/dev/sdz1").and_return "/dev/sdz1"
30
31
  allow(::File).to receive(:realpath).with("/tmp/foo").and_return "/tmp/foo"
31
32
  end
@@ -127,4 +128,4 @@ describe Chef::Provider::Mount::Linux do
127
128
  end
128
129
  end
129
130
 
130
- end
131
+ end
@@ -34,8 +34,8 @@ describe Chef::Provider::Mount::Mount do
34
34
 
35
35
  @provider = Chef::Provider::Mount::Mount.new(@new_resource, @run_context)
36
36
 
37
- allow(::File).to receive(:exists?).with("/dev/sdz1").and_return true
38
- allow(::File).to receive(:exists?).with("/tmp/foo").and_return true
37
+ allow(::File).to receive(:exist?).with("/dev/sdz1").and_return true
38
+ allow(::File).to receive(:exist?).with("/tmp/foo").and_return true
39
39
  allow(::File).to receive(:realpath).with("/dev/sdz1").and_return "/dev/sdz1"
40
40
  allow(::File).to receive(:realpath).with("/tmp/foo").and_return "/tmp/foo"
41
41
  end
@@ -83,12 +83,12 @@ describe Chef::Provider::Mount::Mount do
83
83
  end
84
84
 
85
85
  it "should raise an error if the mount device does not exist" do
86
- allow(::File).to receive(:exists?).with("/dev/sdz1").and_return false
86
+ allow(::File).to receive(:exist?).with("/dev/sdz1").and_return false
87
87
  expect { @provider.load_current_resource; @provider.mountable? }.to raise_error(Chef::Exceptions::Mount)
88
88
  end
89
89
 
90
90
  it "should not call mountable? with load_current_resource - CHEF-1565" do
91
- allow(::File).to receive(:exists?).with("/dev/sdz1").and_return false
91
+ allow(::File).to receive(:exist?).with("/dev/sdz1").and_return false
92
92
  expect(@provider).to receive(:mounted?).and_return(true)
93
93
  expect(@provider).to receive(:enabled?).and_return(true)
94
94
  expect(@provider).not_to receive(:mountable?)
@@ -100,12 +100,12 @@ describe Chef::Provider::Mount::Mount do
100
100
  @new_resource.device_type :uuid
101
101
  @new_resource.device "d21afe51-a0fe-4dc6-9152-ac733763ae0a"
102
102
  expect(@provider).to receive(:shell_out_compacted).with("/sbin/findfs", "UUID=d21afe51-a0fe-4dc6-9152-ac733763ae0a").and_return(status)
103
- expect(::File).to receive(:exists?).with("").and_return(false)
103
+ expect(::File).to receive(:exist?).with("").and_return(false)
104
104
  expect { @provider.load_current_resource; @provider.mountable? }.to raise_error(Chef::Exceptions::Mount)
105
105
  end
106
106
 
107
107
  it "should raise an error if the mount point does not exist" do
108
- allow(::File).to receive(:exists?).with("/tmp/foo").and_return false
108
+ allow(::File).to receive(:exist?).with("/tmp/foo").and_return false
109
109
  expect { @provider.load_current_resource; @provider.mountable? }.to raise_error(Chef::Exceptions::Mount)
110
110
  end
111
111
 
@@ -521,8 +521,8 @@ describe Chef::Provider::Mount::Mount do
521
521
 
522
522
  @provider = Chef::Provider::Mount::Mount.new(@new_resource, @run_context)
523
523
 
524
- allow(::File).to receive(:exists?).with("cephserver:6789:/").and_return true
525
- allow(::File).to receive(:exists?).with("/tmp/bar").and_return true
524
+ allow(::File).to receive(:exist?).with("cephserver:6789:/").and_return true
525
+ allow(::File).to receive(:exist?).with("/tmp/bar").and_return true
526
526
  allow(::File).to receive(:realpath).with("cephserver:6789:/").and_return "cephserver:6789:/"
527
527
  allow(::File).to receive(:realpath).with("/tmp/bar").and_return "/tmp/foo"
528
528
  end
@@ -63,11 +63,16 @@ describe Chef::Provider::Package::Apt do
63
63
  allow(@provider).to receive(:shell_out).with("dpkg", "--compare-versions", "1.0.1ubuntu2", "eq", "1.1.0").and_return(so2)
64
64
  end
65
65
 
66
+ def get_pkg_name_str(name)
67
+ # Package name with or without anchors attached to it based on the flag.
68
+ @new_resource.anchor_package_regex ? "^#{name}$" : name
69
+ end
70
+
66
71
  describe "when loading current resource" do
67
72
 
68
73
  it "should create a current resource with the name of the new_resource" do
69
74
  expect(@provider).to receive(:shell_out_compacted!).with(
70
- "apt-cache", "policy", @new_resource.package_name,
75
+ "apt-cache", "policy", get_pkg_name_str(@new_resource.package_name),
71
76
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
72
77
  timeout: @timeout
73
78
  ).and_return(@shell_out)
@@ -107,7 +112,7 @@ describe Chef::Provider::Package::Apt do
107
112
  POLICY_STDOUT
108
113
  policy = double(stdout: policy_out, exitstatus: 0)
109
114
  expect(@provider).to receive(:shell_out_compacted!).with(
110
- "apt-cache", "policy", "conic-smarms",
115
+ "apt-cache", "policy", get_pkg_name_str("conic-smarms"),
111
116
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
112
117
  timeout: @timeout
113
118
  ).and_return(policy)
@@ -116,7 +121,7 @@ describe Chef::Provider::Package::Apt do
116
121
  SHOWPKG_STDOUT
117
122
  showpkg = double(stdout: showpkg_out, exitstatus: 0)
118
123
  expect(@provider).to receive(:shell_out_compacted!).with(
119
- "apt-cache", "showpkg", "conic-smarms",
124
+ "apt-cache", "showpkg", get_pkg_name_str("conic-smarms"),
120
125
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
121
126
  timeout: @timeout
122
127
  ).and_return(showpkg)
@@ -135,7 +140,7 @@ describe Chef::Provider::Package::Apt do
135
140
  VPKG_STDOUT
136
141
  virtual_package = double(stdout: virtual_package_out, exitstatus: 0)
137
142
  expect(@provider).to receive(:shell_out_compacted!).with(
138
- "apt-cache", "policy", "libmysqlclient15-dev",
143
+ "apt-cache", "policy", get_pkg_name_str("libmysqlclient15-dev"),
139
144
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
140
145
  timeout: @timeout
141
146
  ).and_return(virtual_package)
@@ -159,7 +164,7 @@ describe Chef::Provider::Package::Apt do
159
164
  SHOWPKG_STDOUT
160
165
  showpkg = double(stdout: showpkg_out, exitstatus: 0)
161
166
  expect(@provider).to receive(:shell_out_compacted!).with(
162
- "apt-cache", "showpkg", "libmysqlclient15-dev",
167
+ "apt-cache", "showpkg", get_pkg_name_str("libmysqlclient15-dev"),
163
168
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
164
169
  timeout: @timeout
165
170
  ).and_return(showpkg)
@@ -178,7 +183,7 @@ describe Chef::Provider::Package::Apt do
178
183
  RPKG_STDOUT
179
184
  real_package = double(stdout: real_package_out, exitstatus: 0)
180
185
  expect(@provider).to receive(:shell_out_compacted!).with(
181
- "apt-cache", "policy", "libmysqlclient-dev",
186
+ "apt-cache", "policy", get_pkg_name_str("libmysqlclient-dev"),
182
187
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
183
188
  timeout: @timeout
184
189
  ).and_return(real_package)
@@ -195,7 +200,7 @@ describe Chef::Provider::Package::Apt do
195
200
  VPKG_STDOUT
196
201
  virtual_package = double(stdout: virtual_package_out, exitstatus: 0)
197
202
  expect(@provider).to receive(:shell_out_compacted!).with(
198
- "apt-cache", "policy", "mp3-decoder",
203
+ "apt-cache", "policy", get_pkg_name_str("mp3-decoder"),
199
204
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
200
205
  timeout: @timeout
201
206
  ).and_return(virtual_package)
@@ -222,7 +227,7 @@ describe Chef::Provider::Package::Apt do
222
227
  SHOWPKG_STDOUT
223
228
  showpkg = double(stdout: showpkg_out, exitstatus: 0)
224
229
  expect(@provider).to receive(:shell_out_compacted!).with(
225
- "apt-cache", "showpkg", "mp3-decoder",
230
+ "apt-cache", "showpkg", get_pkg_name_str("mp3-decoder"),
226
231
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
227
232
  timeout: @timeout
228
233
  ).and_return(showpkg)
@@ -236,7 +241,7 @@ describe Chef::Provider::Package::Apt do
236
241
  @new_resource.default_release("lenny-backports")
237
242
  @new_resource.provider(nil)
238
243
  expect(@provider).to receive(:shell_out_compacted!).with(
239
- "apt-cache", "-o", "APT::Default-Release=lenny-backports", "policy", "irssi",
244
+ "apt-cache", "-o", "APT::Default-Release=lenny-backports", "policy", get_pkg_name_str("irssi"),
240
245
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
241
246
  timeout: @timeout
242
247
  ).and_return(@shell_out)
@@ -246,7 +251,7 @@ describe Chef::Provider::Package::Apt do
246
251
  it "raises an exception if a source is specified (CHEF-5113)" do
247
252
  @new_resource.source "pluto"
248
253
  expect(@provider).to receive(:shell_out_compacted!).with(
249
- "apt-cache", "policy", @new_resource.package_name,
254
+ "apt-cache", "policy", get_pkg_name_str(@new_resource.package_name),
250
255
  env: { "DEBIAN_FRONTEND" => "noninteractive" } ,
251
256
  timeout: @timeout
252
257
  ).and_return(@shell_out)
@@ -277,7 +282,7 @@ describe Chef::Provider::Package::Apt do
277
282
  RPKG_STDOUT
278
283
  real_package = double(stdout: real_package_out, exitstatus: 0)
279
284
  expect(@provider).to receive(:shell_out_compacted!).with(
280
- "apt-cache", "policy", "libmysqlclient-dev",
285
+ "apt-cache", "policy", get_pkg_name_str("libmysqlclient-dev"),
281
286
  env: { "DEBIAN_FRONTEND" => "noninteractive" },
282
287
  timeout: @timeout
283
288
  ).and_return(real_package)
@@ -307,12 +312,12 @@ describe Chef::Provider::Package::Apt do
307
312
  RPKG_STDOUT
308
313
  real_package = double(stdout: real_package_out, exitstatus: 0)
309
314
  expect(@provider).to receive(:shell_out_compacted!).with(
310
- "apt-cache", "policy", @new_resource.package_name,
315
+ "apt-cache", "policy", get_pkg_name_str(@new_resource.package_name),
311
316
  env: { "DEBIAN_FRONTEND" => "noninteractive" } ,
312
317
  timeout: @timeout
313
318
  ).and_return(real_package)
314
319
  expect(@provider).to receive(:shell_out_compacted!).with(
315
- "apt-cache", "showpkg", @new_resource.package_name,
320
+ "apt-cache", "showpkg", get_pkg_name_str(@new_resource.package_name),
316
321
  env: { "DEBIAN_FRONTEND" => "noninteractive" } ,
317
322
  timeout: @timeout
318
323
  ).and_return(real_package)
@@ -47,9 +47,20 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
47
47
  allow(provider).to receive(:choco_exe).and_return(choco_exe)
48
48
  local_list_obj = double(stdout: local_list_stdout)
49
49
  allow(provider).to receive(:shell_out_compacted!).with(choco_exe, "list", "-l", "-r", { returns: [0, 2], timeout: timeout }).and_return(local_list_obj)
50
+ allow(provider).to receive(:powershell_exec!).with("#{choco_exe} --version").and_return(double(result: "2.1.0"))
51
+ # Mock the local file system choco queries
52
+ allow(provider).to receive(:get_local_pkg_dirs).and_return(%w{chocolatey ConEmu})
53
+ allow(provider).to receive(:fetch_package_versions_local).and_return({ "chocolatey" => "0.9.9.11", "conemu" => "15.10.25.0" })
54
+ end
55
+
56
+ after(:each) do
57
+ provider.instance_variable_set(:@get_choco_version, nil)
50
58
  end
51
59
 
52
60
  def allow_remote_list(package_names, args = nil)
61
+ # Ensure that when we set this, we invalidate any cache since we're changing
62
+ # the returned data on purpose
63
+ provider.invalidate_cache
53
64
  remote_list_stdout = <<~EOF
54
65
  Chocolatey v0.9.9.11
55
66
  chocolatey|0.9.9.11
@@ -59,12 +70,10 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
59
70
  munin-node|1.6.1.20130823
60
71
  EOF
61
72
  remote_list_obj = double(stdout: remote_list_stdout)
62
- package_names.each do |pkg|
63
- if args
64
- allow(provider).to receive(:shell_out_compacted!).with(choco_exe, "list", "-r", pkg, *args, { returns: [0, 2], timeout: timeout }).and_return(remote_list_obj)
65
- else
66
- allow(provider).to receive(:shell_out_compacted!).with(choco_exe, "list", "-r", pkg, { returns: [0, 2], timeout: timeout }).and_return(remote_list_obj)
67
- end
73
+ if args
74
+ allow(provider).to receive(:shell_out_compacted!).with(choco_exe, provider.query_command, "-r", *(package_names.sort + args), { returns: [0, 2], timeout: timeout }).and_return(remote_list_obj)
75
+ else
76
+ allow(provider).to receive(:shell_out_compacted!).with(choco_exe, provider.query_command, "-r", *(package_names.sort), { returns: [0, 2], timeout: timeout }).and_return(remote_list_obj)
68
77
  end
69
78
  end
70
79
 
@@ -78,6 +87,25 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
78
87
  end
79
88
  end
80
89
 
90
+ describe "choco searches change with the version" do
91
+ it "Choco V1 uses List" do
92
+ allow(provider).to receive(:powershell_exec!).with("#{choco_exe} --version").and_return(double(result: "1.4.0"))
93
+ expect(provider.query_command).to eql("list")
94
+ end
95
+
96
+ it "Choco V2 uses Search" do
97
+ allow(provider).to receive(:powershell_exec!).with("#{choco_exe} --version").and_return(double(result: "2.1.0"))
98
+ expect(provider.query_command).to eql("search")
99
+ end
100
+ end
101
+
102
+ describe "bulk_query changes the search behaviour" do
103
+ it "should respect bulk_query when getting working out what to search" do
104
+ new_resource.bulk_query(true)
105
+ expect(provider.collect_package_requests).to eql(["*"])
106
+ end
107
+ end
108
+
81
109
  describe "#candidate_version" do
82
110
  it "should set the candidate_version to the latest version when not pinning" do
83
111
  allow_remote_list(["git"])
@@ -121,6 +149,13 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
121
149
  end
122
150
  end
123
151
 
152
+ describe "the query cache should be invalidated if the config is clean" do
153
+ it "should return false to cache_is_valid? by default" do
154
+ provider.invalidate_cache
155
+ expect(provider.cache_is_valid?).to eql(false)
156
+ end
157
+ end
158
+
124
159
  describe "#load_current_resource" do
125
160
  it "should return a current_resource" do
126
161
  expect(provider.load_current_resource).to be_kind_of(Chef::Resource::ChocolateyPackage)
@@ -131,7 +166,16 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
131
166
  expect(provider.current_resource.package_name).to eql(["git"])
132
167
  end
133
168
 
134
- it "should load and downcase names in the installed_packages hash" do
169
+ it "should load and downcase names in the installed_packages hash (with disk provider)" do
170
+ new_resource.use_choco_list(false)
171
+ provider.load_current_resource
172
+ expect(provider.send(:installed_packages)).to eql(
173
+ { "chocolatey" => "0.9.9.11", "conemu" => "15.10.25.0" }
174
+ )
175
+ end
176
+
177
+ it "should load and downcase names in the installed_packages hash (with choco list provider)" do
178
+ new_resource.use_choco_list(true)
135
179
  provider.load_current_resource
136
180
  expect(provider.send(:installed_packages)).to eql(
137
181
  { "chocolatey" => "0.9.9.11", "conemu" => "15.10.25.0" }
@@ -150,7 +194,7 @@ describe Chef::Provider::Package::Chocolatey, :windows_only do
150
194
  new_resource.package_name("package-does-not-exist")
151
195
  new_resource.returns([0])
152
196
  allow(provider).to receive(:shell_out_compacted!)
153
- .with(choco_exe, "list", "-r", new_resource.package_name.first, { returns: new_resource.returns, timeout: timeout })
197
+ .with(choco_exe, provider.query_command, "-r", new_resource.package_name.first, { returns: new_resource.returns, timeout: timeout })
154
198
  .and_raise(Mixlib::ShellOut::ShellCommandFailed, "Expected process to exit with [0], but received '2'")
155
199
  expect { provider.send(:available_packages) }.to raise_error(Mixlib::ShellOut::ShellCommandFailed, "Expected process to exit with [0], but received '2'")
156
200
  end
@@ -508,7 +552,7 @@ describe "behavior when Chocolatey is not installed" do
508
552
  end
509
553
 
510
554
  let(:error_regex) do
511
- /Could not locate.*install.*cookbook.*PowerShell.*GetEnvironmentVariable/m
555
+ /Could not locate.*installer.*resource.*PowerShell.*GetEnvironmentVariable/m
512
556
  end
513
557
 
514
558
  context "#choco_exe" do