chef 12.4.0-universal-mingw32 → 12.4.1-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 (133) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/api_client.rb +31 -129
  3. data/lib/chef/api_client_v1.rb +325 -0
  4. data/lib/chef/chef_class.rb +15 -7
  5. data/lib/chef/chef_fs/file_system/chef_server_root_dir.rb +2 -2
  6. data/lib/chef/dsl/resources.rb +6 -4
  7. data/lib/chef/exceptions.rb +2 -2
  8. data/lib/chef/guard_interpreter/resource_guard_interpreter.rb +2 -1
  9. data/lib/chef/knife/bootstrap/templates/chef-full.erb +4 -4
  10. data/lib/chef/knife/client_bulk_delete.rb +2 -2
  11. data/lib/chef/knife/client_create.rb +4 -4
  12. data/lib/chef/knife/client_delete.rb +3 -3
  13. data/lib/chef/knife/client_edit.rb +10 -2
  14. data/lib/chef/knife/client_list.rb +2 -2
  15. data/lib/chef/knife/client_reregister.rb +2 -2
  16. data/lib/chef/knife/client_show.rb +2 -2
  17. data/lib/chef/knife/osc_user_create.rb +3 -3
  18. data/lib/chef/knife/osc_user_delete.rb +2 -2
  19. data/lib/chef/knife/osc_user_edit.rb +3 -3
  20. data/lib/chef/knife/osc_user_list.rb +2 -2
  21. data/lib/chef/knife/osc_user_reregister.rb +2 -2
  22. data/lib/chef/knife/osc_user_show.rb +2 -2
  23. data/lib/chef/knife/user_create.rb +3 -3
  24. data/lib/chef/knife/user_delete.rb +4 -4
  25. data/lib/chef/knife/user_edit.rb +3 -3
  26. data/lib/chef/knife/user_list.rb +2 -2
  27. data/lib/chef/knife/user_reregister.rb +2 -2
  28. data/lib/chef/knife/user_show.rb +2 -2
  29. data/lib/chef/node_map.rb +14 -18
  30. data/lib/chef/platform/handler_map.rb +45 -0
  31. data/lib/chef/platform/priority_map.rb +19 -32
  32. data/lib/chef/platform/provider_handler_map.rb +29 -0
  33. data/lib/chef/platform/provider_mapping.rb +3 -2
  34. data/lib/chef/platform/resource_handler_map.rb +29 -0
  35. data/lib/chef/platform/resource_priority_map.rb +0 -6
  36. data/lib/chef/provider.rb +1 -1
  37. data/lib/chef/provider/dsc_resource.rb +2 -2
  38. data/lib/chef/provider/dsc_script.rb +1 -1
  39. data/lib/chef/provider/mount/aix.rb +1 -1
  40. data/lib/chef/provider/package.rb +0 -31
  41. data/lib/chef/provider/package/aix.rb +1 -0
  42. data/lib/chef/provider/package/apt.rb +1 -0
  43. data/lib/chef/provider/package/homebrew.rb +1 -0
  44. data/lib/chef/provider/package/ips.rb +1 -0
  45. data/lib/chef/provider/package/macports.rb +1 -0
  46. data/lib/chef/provider/package/openbsd.rb +1 -0
  47. data/lib/chef/provider/package/pacman.rb +1 -0
  48. data/lib/chef/provider/package/paludis.rb +1 -0
  49. data/lib/chef/provider/package/portage.rb +2 -0
  50. data/lib/chef/provider/package/smartos.rb +1 -0
  51. data/lib/chef/provider/package/solaris.rb +2 -0
  52. data/lib/chef/provider/package/yum.rb +1 -0
  53. data/lib/chef/provider/package/zypper.rb +1 -0
  54. data/lib/chef/provider/service.rb +4 -22
  55. data/lib/chef/provider/service/debian.rb +2 -0
  56. data/lib/chef/provider/service/insserv.rb +2 -0
  57. data/lib/chef/provider/service/invokercd.rb +2 -0
  58. data/lib/chef/provider/service/openbsd.rb +1 -1
  59. data/lib/chef/provider/service/redhat.rb +2 -0
  60. data/lib/chef/provider/service/upstart.rb +3 -0
  61. data/lib/chef/provider_resolver.rb +59 -53
  62. data/lib/chef/resource.rb +22 -73
  63. data/lib/chef/resource/dsc_script.rb +1 -1
  64. data/lib/chef/resource/ips_package.rb +1 -0
  65. data/lib/chef/resource/mount.rb +8 -0
  66. data/lib/chef/resource/openbsd_package.rb +0 -11
  67. data/lib/chef/resource/solaris_package.rb +1 -4
  68. data/lib/chef/resource_resolver.rb +54 -26
  69. data/lib/chef/run_list/versioned_recipe_list.rb +6 -5
  70. data/lib/chef/user.rb +52 -188
  71. data/lib/chef/user_v1.rb +335 -0
  72. data/lib/chef/version.rb +1 -1
  73. data/spec/data/trusted_certs/opscode.pem +53 -56
  74. data/spec/functional/provider/whyrun_safe_ruby_block_spec.rb +1 -1
  75. data/spec/functional/resource/package_spec.rb +0 -2
  76. data/spec/integration/recipes/recipe_dsl_spec.rb +661 -126
  77. data/spec/spec_helper.rb +19 -13
  78. data/spec/support/shared/unit/api_versioning.rb +2 -2
  79. data/spec/unit/api_client_spec.rb +22 -201
  80. data/spec/unit/api_client_v1_spec.rb +457 -0
  81. data/spec/unit/knife/client_bulk_delete_spec.rb +4 -4
  82. data/spec/unit/knife/client_create_spec.rb +1 -1
  83. data/spec/unit/knife/client_delete_spec.rb +3 -3
  84. data/spec/unit/knife/client_edit_spec.rb +14 -1
  85. data/spec/unit/knife/client_list_spec.rb +1 -1
  86. data/spec/unit/knife/client_reregister_spec.rb +2 -2
  87. data/spec/unit/knife/client_show_spec.rb +2 -2
  88. data/spec/unit/knife/osc_user_create_spec.rb +5 -5
  89. data/spec/unit/knife/osc_user_delete_spec.rb +1 -1
  90. data/spec/unit/knife/osc_user_edit_spec.rb +1 -1
  91. data/spec/unit/knife/osc_user_list_spec.rb +1 -1
  92. data/spec/unit/knife/osc_user_reregister_spec.rb +1 -1
  93. data/spec/unit/knife/osc_user_show_spec.rb +1 -1
  94. data/spec/unit/knife/user_create_spec.rb +1 -1
  95. data/spec/unit/knife/user_delete_spec.rb +2 -2
  96. data/spec/unit/knife/user_edit_spec.rb +2 -2
  97. data/spec/unit/knife/user_list_spec.rb +1 -1
  98. data/spec/unit/knife/user_reregister_spec.rb +1 -1
  99. data/spec/unit/knife/user_show_spec.rb +2 -2
  100. data/spec/unit/lwrp_spec.rb +146 -134
  101. data/spec/unit/node_map_spec.rb +12 -0
  102. data/spec/unit/platform_spec.rb +1 -1
  103. data/spec/unit/provider/deploy_spec.rb +1 -1
  104. data/spec/unit/provider/dsc_resource_spec.rb +3 -3
  105. data/spec/unit/provider/dsc_script_spec.rb +2 -2
  106. data/spec/unit/provider_resolver_spec.rb +170 -135
  107. data/spec/unit/recipe_spec.rb +3 -3
  108. data/spec/unit/resource/breakpoint_spec.rb +1 -1
  109. data/spec/unit/resource/cron_spec.rb +1 -1
  110. data/spec/unit/resource/directory_spec.rb +1 -1
  111. data/spec/unit/resource/dsc_resource_spec.rb +1 -1
  112. data/spec/unit/resource/dsc_script_spec.rb +2 -2
  113. data/spec/unit/resource/env_spec.rb +1 -1
  114. data/spec/unit/resource/erl_call_spec.rb +1 -1
  115. data/spec/unit/resource/file_spec.rb +1 -1
  116. data/spec/unit/resource/group_spec.rb +1 -1
  117. data/spec/unit/resource/link_spec.rb +1 -1
  118. data/spec/unit/resource/mdadm_spec.rb +1 -1
  119. data/spec/unit/resource/mount_spec.rb +1 -1
  120. data/spec/unit/resource/ohai_spec.rb +1 -1
  121. data/spec/unit/resource/registry_key_spec.rb +1 -1
  122. data/spec/unit/resource/route_spec.rb +1 -1
  123. data/spec/unit/resource/ruby_block_spec.rb +3 -3
  124. data/spec/unit/resource/user_spec.rb +1 -1
  125. data/spec/unit/resource/windows_service_spec.rb +1 -1
  126. data/spec/unit/resource_resolver_spec.rb +8 -4
  127. data/spec/unit/resource_spec.rb +89 -3
  128. data/spec/unit/run_list/versioned_recipe_list_spec.rb +115 -48
  129. data/spec/unit/user_spec.rb +97 -405
  130. data/spec/unit/user_v1_spec.rb +584 -0
  131. metadata +11 -6
  132. data/lib/chef/osc_user.rb +0 -194
  133. data/spec/unit/osc_user_spec.rb +0 -276
@@ -43,7 +43,7 @@ describe Chef::Resource::WhyrunSafeRubyBlock do
43
43
  end
44
44
 
45
45
  it "updates the evil laugh, even in why-run mode" do
46
- new_resource.run_action(new_resource.action)
46
+ Array(new_resource.action).each {|action| new_resource.run_action(action) }
47
47
  expect($evil_global_evil_laugh).to eq(:mwahahaha)
48
48
  expect(new_resource).to be_updated
49
49
  end
@@ -386,5 +386,3 @@ describe Chef::Resource::Package, metadata do
386
386
  end
387
387
 
388
388
  end
389
-
390
-
@@ -11,7 +11,7 @@ describe "Recipe DSL methods" do
11
11
  before(:all) { Namer.current_index = 1 }
12
12
  before { Namer.current_index += 1 }
13
13
 
14
- context "With resource 'base_thingy' declared as BaseThingy" do
14
+ context "with resource 'base_thingy' declared as BaseThingy" do
15
15
  before(:context) {
16
16
 
17
17
  class BaseThingy < Chef::Resource
@@ -19,6 +19,7 @@ describe "Recipe DSL methods" do
19
19
  default_action :create
20
20
 
21
21
  class<<self
22
+ attr_accessor :created_name
22
23
  attr_accessor :created_resource
23
24
  attr_accessor :created_provider
24
25
  end
@@ -30,6 +31,7 @@ describe "Recipe DSL methods" do
30
31
  def load_current_resource
31
32
  end
32
33
  def action_create
34
+ BaseThingy.created_name = new_resource.name
33
35
  BaseThingy.created_resource = new_resource.class
34
36
  BaseThingy.created_provider = self.class
35
37
  end
@@ -47,12 +49,38 @@ describe "Recipe DSL methods" do
47
49
  BaseThingy.created_provider = nil
48
50
  end
49
51
 
52
+ it "creates base_thingy when you call base_thingy in a recipe" do
53
+ recipe = converge {
54
+ base_thingy 'blah' do; end
55
+ }
56
+ expect(recipe.logged_warnings).to eq ''
57
+ expect(BaseThingy.created_name).to eq 'blah'
58
+ expect(BaseThingy.created_resource).to eq BaseThingy
59
+ end
60
+
61
+ it "errors out when you call base_thingy do ... end in a recipe" do
62
+ expect_converge {
63
+ base_thingy do; end
64
+ }.to raise_error(ArgumentError, 'You must supply a name when declaring a base_thingy resource')
65
+ end
66
+
67
+ it "emits a warning when you call base_thingy 'foo', 'bar' do ... end in a recipe" do
68
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
69
+ recipe = converge {
70
+ base_thingy 'foo', 'bar' do
71
+ end
72
+ }
73
+ expect(recipe.logged_warnings).to match(/Cannot create resource base_thingy with more than one argument. All arguments except the name \("foo"\) will be ignored. This will cause an error in Chef 13. Arguments: \["foo", "bar"\]/)
74
+ expect(BaseThingy.created_name).to eq 'foo'
75
+ expect(BaseThingy.created_resource).to eq BaseThingy
76
+ end
77
+
50
78
  context "Deprecated automatic resource DSL" do
51
79
  before do
52
80
  Chef::Config[:treat_deprecation_warnings_as_errors] = false
53
81
  end
54
82
 
55
- context "With a resource 'backcompat_thingy' declared in Chef::Resource and Chef::Provider" do
83
+ context "with a resource 'backcompat_thingy' declared in Chef::Resource and Chef::Provider" do
56
84
  before(:context) {
57
85
 
58
86
  class Chef::Resource::BackcompatThingy < Chef::Resource
@@ -97,7 +125,7 @@ describe "Recipe DSL methods" do
97
125
  end
98
126
  end
99
127
 
100
- context "With a resource named RecipeDSLSpecNamespace::Bar::BarThingy" do
128
+ context "with a resource named RecipeDSLSpecNamespace::Bar::BarThingy" do
101
129
  before(:context) {
102
130
 
103
131
  class RecipeDSLSpecNamespace::Bar::BarThingy < BaseThingy
@@ -112,7 +140,7 @@ describe "Recipe DSL methods" do
112
140
  end
113
141
  end
114
142
 
115
- context "With a resource named Chef::Resource::NoNameThingy with resource_name nil" do
143
+ context "with a resource named Chef::Resource::NoNameThingy with resource_name nil" do
116
144
  before(:context) {
117
145
 
118
146
  class Chef::Resource::NoNameThingy < BaseThingy
@@ -128,7 +156,7 @@ describe "Recipe DSL methods" do
128
156
  end
129
157
  end
130
158
 
131
- context "With a resource named AnotherNoNameThingy with resource_name :another_thingy_name" do
159
+ context "with a resource named AnotherNoNameThingy with resource_name :another_thingy_name" do
132
160
  before(:context) {
133
161
 
134
162
  class AnotherNoNameThingy < BaseThingy
@@ -152,7 +180,7 @@ describe "Recipe DSL methods" do
152
180
  end
153
181
  end
154
182
 
155
- context "With a resource named AnotherNoNameThingy2 with resource_name :another_thingy_name2; resource_name :another_thingy_name3" do
183
+ context "with a resource named AnotherNoNameThingy2 with resource_name :another_thingy_name2; resource_name :another_thingy_name3" do
156
184
  before(:context) {
157
185
 
158
186
  class AnotherNoNameThingy2 < BaseThingy
@@ -184,7 +212,7 @@ describe "Recipe DSL methods" do
184
212
  end
185
213
 
186
214
  context "provides overriding resource_name" do
187
- context "With a resource named AnotherNoNameThingy3 with provides :another_no_name_thingy3, os: 'blarghle'" do
215
+ context "with a resource named AnotherNoNameThingy3 with provides :another_no_name_thingy3, os: 'blarghle'" do
188
216
  before(:context) {
189
217
 
190
218
  class AnotherNoNameThingy3 < BaseThingy
@@ -213,7 +241,7 @@ describe "Recipe DSL methods" do
213
241
  end
214
242
  end
215
243
 
216
- context "With a resource named AnotherNoNameThingy4 with two provides" do
244
+ context "with a resource named AnotherNoNameThingy4 with two provides" do
217
245
  before(:context) {
218
246
 
219
247
  class AnotherNoNameThingy4 < BaseThingy
@@ -253,7 +281,7 @@ describe "Recipe DSL methods" do
253
281
  end
254
282
  end
255
283
 
256
- context "With a resource named AnotherNoNameThingy5, a different resource_name, and a provides with the original resource_name" do
284
+ context "with a resource named AnotherNoNameThingy5, a different resource_name, and a provides with the original resource_name" do
257
285
  before(:context) {
258
286
 
259
287
  class AnotherNoNameThingy5 < BaseThingy
@@ -290,7 +318,7 @@ describe "Recipe DSL methods" do
290
318
  end
291
319
  end
292
320
 
293
- context "With a resource named AnotherNoNameThingy6, a provides with the original resource name, and a different resource_name" do
321
+ context "with a resource named AnotherNoNameThingy6, a provides with the original resource name, and a different resource_name" do
294
322
  before(:context) {
295
323
 
296
324
  class AnotherNoNameThingy6 < BaseThingy
@@ -327,7 +355,7 @@ describe "Recipe DSL methods" do
327
355
  end
328
356
  end
329
357
 
330
- context "With a resource named AnotherNoNameThingy7, a new resource_name, and provides with that new resource name" do
358
+ context "with a resource named AnotherNoNameThingy7, a new resource_name, and provides with that new resource name" do
331
359
  before(:context) {
332
360
 
333
361
  class AnotherNoNameThingy7 < BaseThingy
@@ -365,7 +393,7 @@ describe "Recipe DSL methods" do
365
393
  end
366
394
 
367
395
  # opposite order from the previous test (provides, then resource_name)
368
- context "With a resource named AnotherNoNameThingy8, a provides with a new resource name, and resource_name with that new resource name" do
396
+ context "with a resource named AnotherNoNameThingy8, a provides with a new resource name, and resource_name with that new resource name" do
369
397
  before(:context) {
370
398
 
371
399
  class AnotherNoNameThingy8 < BaseThingy
@@ -401,119 +429,6 @@ describe "Recipe DSL methods" do
401
429
  }.to raise_error(NoMethodError)
402
430
  end
403
431
  end
404
-
405
- context "With a resource TwoClassesOneDsl" do
406
- let(:class_name) { "TwoClassesOneDsl#{Namer.current_index}" }
407
- let(:dsl_method) { :"two_classes_one_dsl#{Namer.current_index}" }
408
-
409
- before {
410
- eval <<-EOM, nil, __FILE__, __LINE__+1
411
- class #{class_name} < BaseThingy
412
- resource_name #{dsl_method.inspect}
413
- end
414
- EOM
415
- }
416
- context "and resource BlahModule::TwoClassesOneDsl" do
417
- before {
418
- eval <<-EOM, nil, __FILE__, __LINE__+1
419
- module BlahModule
420
- class #{class_name} < BaseThingy
421
- resource_name #{dsl_method.inspect}
422
- end
423
- end
424
- EOM
425
- }
426
- it "two_classes_one_dsl resolves to BlahModule::TwoClassesOneDsl (alphabetical)" do
427
- dsl_method = self.dsl_method
428
- recipe = converge {
429
- instance_eval("#{dsl_method} 'blah' do; end")
430
- }
431
- expect(recipe.logged_warnings).to eq ''
432
- expect(BaseThingy.created_resource).to eq eval("BlahModule::#{class_name}")
433
- end
434
- it "resource_matching_short_name returns BlahModule::TwoClassesOneDsl" do
435
- expect(Chef::Resource.resource_matching_short_name(dsl_method)).to eq eval("BlahModule::#{class_name}")
436
- end
437
- end
438
- context "and resource BlahModule::TwoClassesOneDsl with resource_name nil" do
439
- before {
440
- eval <<-EOM, nil, __FILE__, __LINE__+1
441
- module BlahModule
442
- class BlahModule::#{class_name} < BaseThingy
443
- resource_name nil
444
- end
445
- end
446
- EOM
447
- }
448
- it "two_classes_one_dsl resolves to ::TwoClassesOneDsl" do
449
- dsl_method = self.dsl_method
450
- recipe = converge {
451
- instance_eval("#{dsl_method} 'blah' do; end")
452
- }
453
- expect(recipe.logged_warnings).to eq ''
454
- expect(BaseThingy.created_resource).to eq eval("::#{class_name}")
455
- end
456
- it "resource_matching_short_name returns ::TwoClassesOneDsl" do
457
- expect(Chef::Resource.resource_matching_short_name(dsl_method)).to eq eval("::#{class_name}")
458
- end
459
- end
460
- context "and resource BlahModule::TwoClassesOneDsl with resource_name :argh" do
461
- before {
462
- eval <<-EOM, nil, __FILE__, __LINE__+1
463
- module BlahModule
464
- class BlahModule::#{class_name} < BaseThingy
465
- resource_name :argh
466
- end
467
- end
468
- EOM
469
- }
470
- it "two_classes_one_dsl resolves to ::TwoClassesOneDsl" do
471
- dsl_method = self.dsl_method
472
- recipe = converge {
473
- instance_eval("#{dsl_method} 'blah' do; end")
474
- }
475
- expect(recipe.logged_warnings).to eq ''
476
- expect(BaseThingy.created_resource).to eq eval("::#{class_name}")
477
- end
478
- it "resource_matching_short_name returns ::TwoClassesOneDsl" do
479
- expect(Chef::Resource.resource_matching_short_name(dsl_method)).to eq eval("::#{class_name}")
480
- end
481
- end
482
- context "and resource BlahModule::TwoClassesOneDsl with provides :two_classes_one_dsl, os: 'blarghle'" do
483
- before {
484
- eval <<-EOM, nil, __FILE__, __LINE__+1
485
- module BlahModule
486
- class BlahModule::#{class_name} < BaseThingy
487
- resource_name #{dsl_method.inspect}
488
- provides #{dsl_method.inspect}, os: 'blarghle'
489
- end
490
- end
491
- EOM
492
- }
493
-
494
- it "and os = blarghle, two_classes_one_dsl resolves to BlahModule::TwoClassesOneDsl" do
495
- dsl_method = self.dsl_method
496
- recipe = converge {
497
- # this is an ugly way to test, make Cheffish expose node attrs
498
- run_context.node.automatic[:os] = 'blarghle'
499
- instance_eval("#{dsl_method} 'blah' do; end")
500
- }
501
- expect(recipe.logged_warnings).to eq ''
502
- expect(BaseThingy.created_resource).to eq eval("BlahModule::#{class_name}")
503
- end
504
-
505
- it "and os = linux, two_classes_one_dsl resolves to ::TwoClassesOneDsl" do
506
- dsl_method = self.dsl_method
507
- recipe = converge {
508
- # this is an ugly way to test, make Cheffish expose node attrs
509
- run_context.node.automatic[:os] = 'linux'
510
- instance_eval("#{dsl_method} 'blah' do; end")
511
- }
512
- expect(recipe.logged_warnings).to eq ''
513
- expect(BaseThingy.created_resource).to eq eval("::#{class_name}")
514
- end
515
- end
516
- end
517
432
  end
518
433
  end
519
434
 
@@ -833,7 +748,7 @@ describe "Recipe DSL methods" do
833
748
  end
834
749
  end
835
750
 
836
- context "With platform-specific resources 'my_super_thingy_foo' and 'my_super_thingy_bar'" do
751
+ context "with platform-specific resources 'my_super_thingy_foo' and 'my_super_thingy_bar'" do
837
752
  before(:context) {
838
753
  class MySuperThingyFoo < BaseThingy
839
754
  resource_name :my_super_thingy_foo
@@ -924,6 +839,601 @@ describe "Recipe DSL methods" do
924
839
  end
925
840
  end
926
841
  end
842
+
843
+ context "with a resource named 'B' with resource name :two_classes_one_dsl" do
844
+ let(:two_classes_one_dsl) { :"two_classes_one_dsl#{Namer.current_index}" }
845
+ let(:resource_class) {
846
+ result = Class.new(BaseThingy) do
847
+ def self.name
848
+ "B"
849
+ end
850
+ def self.to_s; name; end
851
+ def self.inspect; name.inspect; end
852
+ end
853
+ result.resource_name two_classes_one_dsl
854
+ result
855
+ }
856
+ before { resource_class } # pull on it so it gets defined before the recipe runs
857
+
858
+ context "and another resource named 'A' with resource_name :two_classes_one_dsl" do
859
+ let(:resource_class_a) {
860
+ result = Class.new(BaseThingy) do
861
+ def self.name
862
+ "A"
863
+ end
864
+ def self.to_s; name; end
865
+ def self.inspect; name.inspect; end
866
+ end
867
+ result.resource_name two_classes_one_dsl
868
+ result
869
+ }
870
+ before { resource_class_a } # pull on it so it gets defined before the recipe runs
871
+
872
+ it "two_classes_one_dsl resolves to A (alphabetically earliest)" do
873
+ two_classes_one_dsl = self.two_classes_one_dsl
874
+ recipe = converge {
875
+ instance_eval("#{two_classes_one_dsl} 'blah'")
876
+ }
877
+ expect(recipe.logged_warnings).to eq ''
878
+ expect(BaseThingy.created_resource).to eq resource_class_a
879
+ end
880
+
881
+ it "resource_matching_short_name returns B" do
882
+ expect(Chef::Resource.resource_matching_short_name(two_classes_one_dsl)).to eq resource_class_a
883
+ end
884
+ end
885
+
886
+ context "and another resource named 'Z' with resource_name :two_classes_one_dsl" do
887
+ let(:resource_class_z) {
888
+ result = Class.new(BaseThingy) do
889
+ def self.name
890
+ "Z"
891
+ end
892
+ def self.to_s; name; end
893
+ def self.inspect; name.inspect; end
894
+ end
895
+ result.resource_name two_classes_one_dsl
896
+ result
897
+ }
898
+ before { resource_class_z } # pull on it so it gets defined before the recipe runs
899
+
900
+ it "two_classes_one_dsl resolves to B (alphabetically earliest)" do
901
+ two_classes_one_dsl = self.two_classes_one_dsl
902
+ recipe = converge {
903
+ instance_eval("#{two_classes_one_dsl} 'blah'")
904
+ }
905
+ expect(recipe.logged_warnings).to eq ''
906
+ expect(BaseThingy.created_resource).to eq resource_class
907
+ end
908
+
909
+ it "resource_matching_short_name returns B" do
910
+ expect(Chef::Resource.resource_matching_short_name(two_classes_one_dsl)).to eq resource_class
911
+ end
912
+
913
+ context "and a priority array [ Z, B ]" do
914
+ before do
915
+ Chef.set_resource_priority_array(two_classes_one_dsl, [ resource_class_z, resource_class ])
916
+ end
917
+
918
+ it "two_classes_one_dsl resolves to Z (respects the priority array)" do
919
+ two_classes_one_dsl = self.two_classes_one_dsl
920
+ recipe = converge {
921
+ instance_eval("#{two_classes_one_dsl} 'blah'")
922
+ }
923
+ expect(recipe.logged_warnings).to eq ''
924
+ expect(BaseThingy.created_resource).to eq resource_class_z
925
+ end
926
+
927
+ it "resource_matching_short_name returns B" do
928
+ expect(Chef::Resource.resource_matching_short_name(two_classes_one_dsl)).to eq resource_class
929
+ end
930
+
931
+ context "when Z provides(:two_classes_one_dsl) { false }" do
932
+ before do
933
+ resource_class_z.provides(two_classes_one_dsl) { false }
934
+ end
935
+
936
+ it "two_classes_one_dsl resolves to B (picks the next thing in the priority array)" do
937
+ two_classes_one_dsl = self.two_classes_one_dsl
938
+ recipe = converge {
939
+ instance_eval("#{two_classes_one_dsl} 'blah'")
940
+ }
941
+ expect(recipe.logged_warnings).to eq ''
942
+ expect(BaseThingy.created_resource).to eq resource_class
943
+ end
944
+
945
+ it "resource_matching_short_name returns B" do
946
+ expect(Chef::Resource.resource_matching_short_name(two_classes_one_dsl)).to eq resource_class
947
+ end
948
+ end
949
+ end
950
+
951
+ context "and priority arrays [ B ] and [ Z ]" do
952
+ before do
953
+ Chef.set_resource_priority_array(two_classes_one_dsl, [ resource_class ])
954
+ Chef.set_resource_priority_array(two_classes_one_dsl, [ resource_class_z ])
955
+ end
956
+
957
+ it "two_classes_one_dsl resolves to Z (respects the most recent priority array)" do
958
+ two_classes_one_dsl = self.two_classes_one_dsl
959
+ recipe = converge {
960
+ instance_eval("#{two_classes_one_dsl} 'blah'")
961
+ }
962
+ expect(recipe.logged_warnings).to eq ''
963
+ expect(BaseThingy.created_resource).to eq resource_class_z
964
+ end
965
+
966
+ it "resource_matching_short_name returns B" do
967
+ expect(Chef::Resource.resource_matching_short_name(two_classes_one_dsl)).to eq resource_class
968
+ end
969
+
970
+ context "when Z provides(:two_classes_one_dsl) { false }" do
971
+ before do
972
+ resource_class_z.provides(two_classes_one_dsl) { false }
973
+ end
974
+
975
+ it "two_classes_one_dsl resolves to B (picks the first match from the other priority array)" do
976
+ two_classes_one_dsl = self.two_classes_one_dsl
977
+ recipe = converge {
978
+ instance_eval("#{two_classes_one_dsl} 'blah'")
979
+ }
980
+ expect(recipe.logged_warnings).to eq ''
981
+ expect(BaseThingy.created_resource).to eq resource_class
982
+ end
983
+
984
+ it "resource_matching_short_name returns B" do
985
+ expect(Chef::Resource.resource_matching_short_name(two_classes_one_dsl)).to eq resource_class
986
+ end
987
+ end
988
+ end
989
+
990
+ context "and a priority array [ Z ]" do
991
+ before do
992
+ Chef.set_resource_priority_array(two_classes_one_dsl, [ resource_class_z ])
993
+ end
994
+
995
+ context "when Z provides(:two_classes_one_dsl) { false }" do
996
+ before do
997
+ resource_class_z.provides(two_classes_one_dsl) { false }
998
+ end
999
+
1000
+ it "two_classes_one_dsl resolves to B (picks the first match outside the priority array)" do
1001
+ two_classes_one_dsl = self.two_classes_one_dsl
1002
+ recipe = converge {
1003
+ instance_eval("#{two_classes_one_dsl} 'blah'")
1004
+ }
1005
+ expect(recipe.logged_warnings).to eq ''
1006
+ expect(BaseThingy.created_resource).to eq resource_class
1007
+ end
1008
+
1009
+ it "resource_matching_short_name returns B" do
1010
+ expect(Chef::Resource.resource_matching_short_name(two_classes_one_dsl)).to eq resource_class
1011
+ end
1012
+ end
1013
+ end
1014
+
1015
+ end
1016
+
1017
+ context "and a provider named 'B' which provides :two_classes_one_dsl" do
1018
+ before do
1019
+ resource_class.send(:define_method, :provider) { nil }
1020
+ end
1021
+
1022
+ let(:provider_class) {
1023
+ result = Class.new(BaseThingy::Provider) do
1024
+ def self.name
1025
+ "B"
1026
+ end
1027
+ def self.to_s; name; end
1028
+ def self.inspect; name.inspect; end
1029
+ end
1030
+ result.provides two_classes_one_dsl
1031
+ result
1032
+ }
1033
+ before { provider_class } # pull on it so it gets defined before the recipe runs
1034
+
1035
+ context "and another provider named 'A'" do
1036
+ let(:provider_class_a) {
1037
+ result = Class.new(BaseThingy::Provider) do
1038
+ def self.name
1039
+ "A"
1040
+ end
1041
+ def self.to_s; name; end
1042
+ def self.inspect; name.inspect; end
1043
+ end
1044
+ result
1045
+ }
1046
+ context "which provides :two_classes_one_dsl" do
1047
+ before { provider_class_a.provides two_classes_one_dsl }
1048
+
1049
+ it "two_classes_one_dsl resolves to A (alphabetically earliest)" do
1050
+ two_classes_one_dsl = self.two_classes_one_dsl
1051
+ recipe = converge {
1052
+ instance_eval("#{two_classes_one_dsl} 'blah'")
1053
+ }
1054
+ expect(recipe.logged_warnings).to eq ''
1055
+ expect(BaseThingy.created_provider).to eq provider_class_a
1056
+ end
1057
+ end
1058
+ context "which provides(:two_classes_one_dsl) { false }" do
1059
+ before { provider_class_a.provides(two_classes_one_dsl) { false } }
1060
+
1061
+ it "two_classes_one_dsl resolves to B (since A declined)" do
1062
+ two_classes_one_dsl = self.two_classes_one_dsl
1063
+ recipe = converge {
1064
+ instance_eval("#{two_classes_one_dsl} 'blah'")
1065
+ }
1066
+ expect(recipe.logged_warnings).to eq ''
1067
+ expect(BaseThingy.created_provider).to eq provider_class
1068
+ end
1069
+ end
1070
+ end
1071
+
1072
+ context "and another provider named 'Z'" do
1073
+ let(:provider_class_z) {
1074
+ result = Class.new(BaseThingy::Provider) do
1075
+ def self.name
1076
+ "Z"
1077
+ end
1078
+ def self.to_s; name; end
1079
+ def self.inspect; name.inspect; end
1080
+ end
1081
+ result
1082
+ }
1083
+ before { provider_class_z } # pull on it so it gets defined before the recipe runs
1084
+
1085
+ context "which provides :two_classes_one_dsl" do
1086
+ before { provider_class_z.provides two_classes_one_dsl }
1087
+
1088
+ it "two_classes_one_dsl resolves to B (alphabetically earliest)" do
1089
+ two_classes_one_dsl = self.two_classes_one_dsl
1090
+ recipe = converge {
1091
+ instance_eval("#{two_classes_one_dsl} 'blah'")
1092
+ }
1093
+ expect(recipe.logged_warnings).to eq ''
1094
+ expect(BaseThingy.created_provider).to eq provider_class
1095
+ end
1096
+
1097
+ context "with a priority array [ Z, B ]" do
1098
+ before { Chef.set_provider_priority_array two_classes_one_dsl, [ provider_class_z, provider_class ] }
1099
+
1100
+ it "two_classes_one_dsl resolves to Z (respects the priority map)" do
1101
+ two_classes_one_dsl = self.two_classes_one_dsl
1102
+ recipe = converge {
1103
+ instance_eval("#{two_classes_one_dsl} 'blah'")
1104
+ }
1105
+ expect(recipe.logged_warnings).to eq ''
1106
+ expect(BaseThingy.created_provider).to eq provider_class_z
1107
+ end
1108
+ end
1109
+ end
1110
+
1111
+ context "which provides(:two_classes_one_dsl) { false }" do
1112
+ before { provider_class_z.provides(two_classes_one_dsl) { false } }
1113
+
1114
+ context "with a priority array [ Z, B ]" do
1115
+ before { Chef.set_provider_priority_array two_classes_one_dsl, [ provider_class_z, provider_class ] }
1116
+
1117
+ it "two_classes_one_dsl resolves to B (the next one in the priority map)" do
1118
+ two_classes_one_dsl = self.two_classes_one_dsl
1119
+ recipe = converge {
1120
+ instance_eval("#{two_classes_one_dsl} 'blah'")
1121
+ }
1122
+ expect(recipe.logged_warnings).to eq ''
1123
+ expect(BaseThingy.created_provider).to eq provider_class
1124
+ end
1125
+ end
1126
+
1127
+ context "with priority arrays [ B ] and [ Z ]" do
1128
+ before { Chef.set_provider_priority_array two_classes_one_dsl, [ provider_class_z ] }
1129
+ before { Chef.set_provider_priority_array two_classes_one_dsl, [ provider_class ] }
1130
+
1131
+ it "two_classes_one_dsl resolves to B (the one in the next priority map)" do
1132
+ two_classes_one_dsl = self.two_classes_one_dsl
1133
+ recipe = converge {
1134
+ instance_eval("#{two_classes_one_dsl} 'blah'")
1135
+ }
1136
+ expect(recipe.logged_warnings).to eq ''
1137
+ expect(BaseThingy.created_provider).to eq provider_class
1138
+ end
1139
+ end
1140
+ end
1141
+ end
1142
+ end
1143
+
1144
+ context "and another resource Blarghle with provides :two_classes_one_dsl, os: 'blarghle'" do
1145
+ let(:resource_class_blarghle) {
1146
+ result = Class.new(BaseThingy) do
1147
+ def self.name
1148
+ "Blarghle"
1149
+ end
1150
+ def self.to_s; name; end
1151
+ def self.inspect; name.inspect; end
1152
+ end
1153
+ result.resource_name two_classes_one_dsl
1154
+ result.provides two_classes_one_dsl, os: 'blarghle'
1155
+ result
1156
+ }
1157
+ before { resource_class_blarghle } # pull on it so it gets defined before the recipe runs
1158
+
1159
+ it "on os = blarghle, two_classes_one_dsl resolves to Blarghle" do
1160
+ two_classes_one_dsl = self.two_classes_one_dsl
1161
+ recipe = converge {
1162
+ # this is an ugly way to test, make Cheffish expose node attrs
1163
+ run_context.node.automatic[:os] = 'blarghle'
1164
+ instance_eval("#{two_classes_one_dsl} 'blah' do; end")
1165
+ }
1166
+ expect(recipe.logged_warnings).to eq ''
1167
+ expect(BaseThingy.created_resource).to eq resource_class_blarghle
1168
+ end
1169
+
1170
+ it "on os = linux, two_classes_one_dsl resolves to B" do
1171
+ two_classes_one_dsl = self.two_classes_one_dsl
1172
+ recipe = converge {
1173
+ # this is an ugly way to test, make Cheffish expose node attrs
1174
+ run_context.node.automatic[:os] = 'linux'
1175
+ instance_eval("#{two_classes_one_dsl} 'blah' do; end")
1176
+ }
1177
+ expect(recipe.logged_warnings).to eq ''
1178
+ expect(BaseThingy.created_resource).to eq resource_class
1179
+ end
1180
+ end
1181
+ end
1182
+
1183
+ context "with a resource MyResource" do
1184
+ let(:resource_class) { Class.new(BaseThingy) do
1185
+ def self.called_provides
1186
+ @called_provides
1187
+ end
1188
+ def to_s
1189
+ "MyResource"
1190
+ end
1191
+ end }
1192
+ let(:my_resource) { :"my_resource#{Namer.current_index}" }
1193
+ let(:blarghle_blarghle_little_star) { :"blarghle_blarghle_little_star#{Namer.current_index}" }
1194
+
1195
+ context "with resource_name :my_resource" do
1196
+ before {
1197
+ resource_class.resource_name my_resource
1198
+ }
1199
+
1200
+ context "with provides? returning true to my_resource" do
1201
+ before {
1202
+ my_resource = self.my_resource
1203
+ resource_class.define_singleton_method(:provides?) do |node, resource_name|
1204
+ @called_provides = true
1205
+ resource_name == my_resource
1206
+ end
1207
+ }
1208
+
1209
+ it "my_resource returns the resource and calls provides?, but does not emit a warning" do
1210
+ dsl_name = self.my_resource
1211
+ recipe = converge {
1212
+ instance_eval("#{dsl_name} 'foo'")
1213
+ }
1214
+ expect(recipe.logged_warnings).to eq ''
1215
+ expect(BaseThingy.created_resource).to eq resource_class
1216
+ expect(resource_class.called_provides).to be_truthy
1217
+ end
1218
+ end
1219
+
1220
+ context "with provides? returning true to blarghle_blarghle_little_star and not resource_name" do
1221
+ before do
1222
+ blarghle_blarghle_little_star = self.blarghle_blarghle_little_star
1223
+ resource_class.define_singleton_method(:provides?) do |node, resource_name|
1224
+ @called_provides = true
1225
+ resource_name == blarghle_blarghle_little_star
1226
+ end
1227
+ end
1228
+
1229
+ it "my_resource does not return the resource" do
1230
+ dsl_name = self.my_resource
1231
+ expect_converge {
1232
+ instance_eval("#{dsl_name} 'foo'")
1233
+ }.to raise_error(Chef::Exceptions::NoSuchResourceType)
1234
+ expect(resource_class.called_provides).to be_truthy
1235
+ end
1236
+
1237
+ it "blarghle_blarghle_little_star 'foo' returns the resource and emits a warning" do
1238
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
1239
+ dsl_name = self.blarghle_blarghle_little_star
1240
+ recipe = converge {
1241
+ instance_eval("#{dsl_name} 'foo'")
1242
+ }
1243
+ expect(recipe.logged_warnings).to include "WARN: #{resource_class}.provides? returned true when asked if it provides DSL #{dsl_name}, but provides :#{dsl_name} was never called!"
1244
+ expect(BaseThingy.created_resource).to eq resource_class
1245
+ expect(resource_class.called_provides).to be_truthy
1246
+ end
1247
+ end
1248
+
1249
+ context "and a provider" do
1250
+ let(:provider_class) do
1251
+ Class.new(BaseThingy::Provider) do
1252
+ def self.name
1253
+ "MyProvider"
1254
+ end
1255
+ def self.to_s; name; end
1256
+ def self.inspect; name.inspect; end
1257
+ def self.called_provides
1258
+ @called_provides
1259
+ end
1260
+ end
1261
+ end
1262
+
1263
+ before do
1264
+ resource_class.send(:define_method, :provider) { nil }
1265
+ end
1266
+
1267
+ context "that provides :my_resource" do
1268
+ before do
1269
+ provider_class.provides my_resource
1270
+ end
1271
+
1272
+ context "with supports? returning true" do
1273
+ before do
1274
+ provider_class.define_singleton_method(:supports?) { |resource,action| true }
1275
+ end
1276
+
1277
+ it "my_resource runs the provider and does not emit a warning" do
1278
+ my_resource = self.my_resource
1279
+ recipe = converge {
1280
+ instance_eval("#{my_resource} 'foo'")
1281
+ }
1282
+ expect(recipe.logged_warnings).to eq ''
1283
+ expect(BaseThingy.created_provider).to eq provider_class
1284
+ end
1285
+
1286
+ context "and another provider supporting :my_resource with supports? false" do
1287
+ let(:provider_class2) do
1288
+ Class.new(BaseThingy::Provider) do
1289
+ def self.name
1290
+ "MyProvider2"
1291
+ end
1292
+ def self.to_s; name; end
1293
+ def self.inspect; name.inspect; end
1294
+ def self.called_provides
1295
+ @called_provides
1296
+ end
1297
+ provides my_resource
1298
+ def self.supports?(resource, action)
1299
+ false
1300
+ end
1301
+ end
1302
+ end
1303
+
1304
+ it "my_resource runs the first provider" do
1305
+ my_resource = self.my_resource
1306
+ recipe = converge {
1307
+ instance_eval("#{my_resource} 'foo'")
1308
+ }
1309
+ expect(recipe.logged_warnings).to eq ''
1310
+ expect(BaseThingy.created_provider).to eq provider_class
1311
+ end
1312
+ end
1313
+ end
1314
+
1315
+ context "with supports? returning false" do
1316
+ before do
1317
+ provider_class.define_singleton_method(:supports?) { |resource,action| false }
1318
+ end
1319
+
1320
+ # TODO no warning? ick
1321
+ it "my_resource runs the provider anyway" do
1322
+ my_resource = self.my_resource
1323
+ recipe = converge {
1324
+ instance_eval("#{my_resource} 'foo'")
1325
+ }
1326
+ expect(recipe.logged_warnings).to eq ''
1327
+ expect(BaseThingy.created_provider).to eq provider_class
1328
+ end
1329
+
1330
+ context "and another provider supporting :my_resource with supports? true" do
1331
+ let(:provider_class2) do
1332
+ my_resource = self.my_resource
1333
+ Class.new(BaseThingy::Provider) do
1334
+ def self.name
1335
+ "MyProvider2"
1336
+ end
1337
+ def self.to_s; name; end
1338
+ def self.inspect; name.inspect; end
1339
+ def self.called_provides
1340
+ @called_provides
1341
+ end
1342
+ provides my_resource
1343
+ def self.supports?(resource, action)
1344
+ true
1345
+ end
1346
+ end
1347
+ end
1348
+ before { provider_class2 } # make sure the provider class shows up
1349
+
1350
+ it "my_resource runs the other provider" do
1351
+ my_resource = self.my_resource
1352
+ recipe = converge {
1353
+ instance_eval("#{my_resource} 'foo'")
1354
+ }
1355
+ expect(recipe.logged_warnings).to eq ''
1356
+ expect(BaseThingy.created_provider).to eq provider_class2
1357
+ end
1358
+ end
1359
+ end
1360
+ end
1361
+
1362
+ context "with provides? returning true" do
1363
+ before {
1364
+ my_resource = self.my_resource
1365
+ provider_class.define_singleton_method(:provides?) do |node, resource|
1366
+ @called_provides = true
1367
+ resource.declared_type == my_resource
1368
+ end
1369
+ }
1370
+
1371
+ context "that provides :my_resource" do
1372
+ before {
1373
+ provider_class.provides my_resource
1374
+ }
1375
+
1376
+ it "my_resource calls the provider (and calls provides?), but does not emit a warning" do
1377
+ my_resource = self.my_resource
1378
+ recipe = converge {
1379
+ instance_eval("#{my_resource} 'foo'")
1380
+ }
1381
+ expect(recipe.logged_warnings).to eq ''
1382
+ expect(BaseThingy.created_provider).to eq provider_class
1383
+ expect(provider_class.called_provides).to be_truthy
1384
+ end
1385
+ end
1386
+
1387
+ context "that does not call provides :my_resource" do
1388
+ it "my_resource calls the provider (and calls provides?), and emits a warning" do
1389
+ Chef::Config[:treat_deprecation_warnings_as_errors] = false
1390
+ my_resource = self.my_resource
1391
+ recipe = converge {
1392
+ instance_eval("#{my_resource} 'foo'")
1393
+ }
1394
+ expect(recipe.logged_warnings).to include("WARN: #{provider_class}.provides? returned true when asked if it provides DSL #{my_resource}, but provides :#{my_resource} was never called!")
1395
+ expect(BaseThingy.created_provider).to eq provider_class
1396
+ expect(provider_class.called_provides).to be_truthy
1397
+ end
1398
+ end
1399
+ end
1400
+
1401
+ context "with provides? returning false to my_resource" do
1402
+ before {
1403
+ my_resource = self.my_resource
1404
+ provider_class.define_singleton_method(:provides?) do |node, resource|
1405
+ @called_provides = true
1406
+ false
1407
+ end
1408
+ }
1409
+
1410
+ context "that provides :my_resource" do
1411
+ before {
1412
+ provider_class.provides my_resource
1413
+ }
1414
+
1415
+ it "my_resource fails to find a provider (and calls provides)" do
1416
+ my_resource = self.my_resource
1417
+ expect_converge {
1418
+ instance_eval("#{my_resource} 'foo'")
1419
+ }.to raise_error(Chef::Exceptions::ProviderNotFound)
1420
+ expect(provider_class.called_provides).to be_truthy
1421
+ end
1422
+ end
1423
+
1424
+ context "that does not provide :my_resource" do
1425
+ it "my_resource fails to find a provider (and calls provides)" do
1426
+ my_resource = self.my_resource
1427
+ expect_converge {
1428
+ instance_eval("#{my_resource} 'foo'")
1429
+ }.to raise_error(Chef::Exceptions::ProviderNotFound)
1430
+ expect(provider_class.called_provides).to be_truthy
1431
+ end
1432
+ end
1433
+ end
1434
+ end
1435
+ end
1436
+ end
927
1437
  end
928
1438
 
929
1439
  before(:all) { Namer.current_index = 0 }
@@ -969,4 +1479,29 @@ describe "Recipe DSL methods" do
969
1479
  end
970
1480
  end
971
1481
  end
1482
+
1483
+ context "with a dynamically defined resource and regular provider" do
1484
+ before(:context) do
1485
+ Class.new(Chef::Resource) do
1486
+ resource_name :lw_resource_with_hw_provider_test_case
1487
+ default_action :create
1488
+ attr_accessor :created_provider
1489
+ end
1490
+ class Chef::Provider::LwResourceWithHwProviderTestCase < Chef::Provider
1491
+ def load_current_resource
1492
+ end
1493
+ def action_create
1494
+ new_resource.created_provider = self.class
1495
+ end
1496
+ end
1497
+ end
1498
+
1499
+ it "looks up the provider in Chef::Provider converting the resource name from snake case to camel case" do
1500
+ resource = nil
1501
+ recipe = converge {
1502
+ resource = lw_resource_with_hw_provider_test_case 'blah' do; end
1503
+ }
1504
+ expect(resource.created_provider).to eq(Chef::Provider::LwResourceWithHwProviderTestCase)
1505
+ end
1506
+ end
972
1507
  end