1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
require "support/shared/integration/integration_helper"
require "chef/mixin/shell_out"
describe "LWRPs with inline resources" do
include IntegrationSupport
include Chef::Mixin::ShellOut
let(:chef_dir) { File.expand_path("../../../../bin", __FILE__) }
# Invoke `chef-client` as `ruby PATH/TO/chef-client`. This ensures the
# following constraints are satisfied:
# * Windows: windows can only run batch scripts as bare executables. Rubygems
# creates batch wrappers for installed gems, but we don't have batch wrappers
# in the source tree.
# * Other `chef-client` in PATH: A common case is running the tests on a
# machine that has omnibus chef installed. In that case we need to ensure
# we're running `chef-client` from the source tree and not the external one.
# cf. CHEF-4914
let(:chef_client) { "bundle exec chef-client --minimal-ohai" }
context "with a use_inline_resources provider with 'def action_a' instead of action :a" do
class LwrpInlineResourcesTest < Chef::Resource
resource_name :lwrp_inline_resources_test
allowed_actions :a, :nothing
default_action :a
property :ran_a
class Provider < Chef::Provider::LWRPBase
provides :lwrp_inline_resources_test
def action_a
r = new_resource
ruby_block "run a" do
block { r.ran_a "ran a" }
end
end
end
end
it "this is totally a bug, but for backcompat purposes, it adds the resources to the main resource collection and does not get marked updated" do
r = nil
expect_recipe do
r = lwrp_inline_resources_test "hi"
end.to have_updated("ruby_block[run a]", :run)
expect(r.ran_a).to eq "ran a"
end
end
context "with an inline resource with a property that shadows the enclosing provider's property" do
class LwrpShadowedPropertyTest < Chef::Resource
PATH = ::File.join(Dir.tmpdir, "shadow-property.txt")
use_automatic_resource_name
allowed_actions :fiddle
property :content
action :fiddle do
file PATH do
content new_resource.content
action %i{create delete}
end
end
end
after { File.delete(LwrpShadowedPropertyTest::PATH) if File.exists?(LwrpShadowedPropertyTest::PATH) }
# https://github.com/chef/chef/issues/4334
it "does not warn spuriously" do
expect(Chef::Log).to_not receive(:warn).with(/is declared in both/)
expect_recipe do
lwrp_shadowed_property_test "fnord" do
action :fiddle
end
end
end
end
context "with an inline_resources provider with two actions, one calling the other" do
class LwrpInlineResourcesTest2 < Chef::Resource
resource_name :lwrp_inline_resources_test2
allowed_actions :a, :b, :nothing
default_action :b
property :ran_a
property :ran_b
class Provider < Chef::Provider::LWRPBase
provides :lwrp_inline_resources_test2
action :a do
r = new_resource
ruby_block "run a" do
block { r.ran_a "ran a" }
end
end
action :b do
action_a
r = new_resource
# Grab ran_a right now, before we converge
ran_a = r.ran_a
ruby_block "run b" do
block { r.ran_b "ran b: ran_a value was #{ran_a.inspect}" }
end
end
end
end
it "resources declared in b are executed immediately inline" do
r = nil
expect_recipe do
r = lwrp_inline_resources_test2 "hi" do
action :b
end
end.to have_updated("lwrp_inline_resources_test2[hi]", :b)
.and have_updated("ruby_block[run a]", :run)
.and have_updated("ruby_block[run b]", :run)
expect(r.ran_b).to eq "ran b: ran_a value was \"ran a\""
end
end
when_the_repository "has a cookbook with a nested LWRP" do
before do
directory "cookbooks/x" do
file "resources/do_nothing.rb", <<-EOM
actions :create, :nothing
default_action :create
EOM
file "providers/do_nothing.rb", <<-EOM
action :create do
end
EOM
file "resources/my_machine.rb", <<-EOM
actions :create, :nothing
default_action :create
EOM
file "providers/my_machine.rb", <<-EOM
action :create do
x_do_nothing 'a'
x_do_nothing 'b'
end
EOM
file "recipes/default.rb", <<-EOM
x_my_machine "me"
x_my_machine "you"
EOM
end # directory 'cookbooks/x'
end
it "should complete with success" do
file "config/client.rb", <<~EOM
local_mode true
cookbook_path "#{path_to("cookbooks")}"
log_level :warn
EOM
result = shell_out("#{chef_client} -c \"#{path_to("config/client.rb")}\" --no-color -F doc -o 'x::default'", cwd: chef_dir)
actual = result.stdout.lines.map { |l| l.chomp }.join("\n")
expected = <<EOM
* x_my_machine[me] action create
* x_do_nothing[a] action create (up to date)
* x_do_nothing[b] action create (up to date)
(up to date)
* x_my_machine[you] action create
* x_do_nothing[a] action create (up to date)
* x_do_nothing[b] action create (up to date)
(up to date)
EOM
expected = expected.lines.map { |l| l.chomp }.join("\n")
expect(actual).to include(expected)
result.error!
end
end
end
|