chef 17.3.48-universal-mingw32 → 17.4.25-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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/lib/chef/application.rb +3 -1
  3. data/lib/chef/compliance/default_attributes.rb +5 -3
  4. data/lib/chef/compliance/runner.rb +15 -1
  5. data/lib/chef/dsl/secret.rb +3 -3
  6. data/lib/chef/exceptions.rb +0 -2
  7. data/lib/chef/formatters/error_mapper.rb +2 -2
  8. data/lib/chef/provider/execute.rb +1 -1
  9. data/lib/chef/provider/group/dscl.rb +1 -1
  10. data/lib/chef/provider/launchd.rb +6 -6
  11. data/lib/chef/provider/subversion.rb +4 -4
  12. data/lib/chef/provider/support/yum_repo.erb +1 -1
  13. data/lib/chef/provider/systemd_unit.rb +17 -16
  14. data/lib/chef/provider/user/mac.rb +3 -3
  15. data/lib/chef/provider/yum_repository.rb +27 -43
  16. data/lib/chef/provider/zypper_repository.rb +3 -3
  17. data/lib/chef/provider.rb +26 -1
  18. data/lib/chef/provider_resolver.rb +8 -2
  19. data/lib/chef/resource/homebrew_cask.rb +1 -1
  20. data/lib/chef/resource/inspec_waiver_file_entry.rb +2 -2
  21. data/lib/chef/resource/launchd.rb +3 -3
  22. data/lib/chef/resource/remote_file.rb +1 -1
  23. data/lib/chef/resource/rhsm_subscription.rb +5 -5
  24. data/lib/chef/resource/ruby_block.rb +100 -0
  25. data/lib/chef/resource/scm/subversion.rb +1 -1
  26. data/lib/chef/resource/sysctl.rb +2 -2
  27. data/lib/chef/resource/systemd_unit.rb +3 -3
  28. data/lib/chef/resource/yum_package.rb +1 -5
  29. data/lib/chef/resource.rb +14 -18
  30. data/lib/chef/resource_inspector.rb +6 -2
  31. data/lib/chef/secret_fetcher/aws_secrets_manager.rb +16 -4
  32. data/lib/chef/secret_fetcher/azure_key_vault.rb +31 -9
  33. data/lib/chef/secret_fetcher/base.rb +5 -1
  34. data/lib/chef/secret_fetcher.rb +5 -4
  35. data/lib/chef/version.rb +1 -1
  36. data/spec/integration/compliance/compliance_spec.rb +1 -0
  37. data/spec/integration/recipes/resource_action_spec.rb +2 -2
  38. data/spec/unit/compliance/runner_spec.rb +46 -2
  39. data/spec/unit/dsl/secret_spec.rb +8 -2
  40. data/spec/unit/provider_spec.rb +23 -0
  41. data/spec/unit/resource/homebrew_cask_spec.rb +29 -11
  42. data/spec/unit/resource/rhsm_subscription_spec.rb +50 -3
  43. data/spec/unit/resource/systemd_unit_spec.rb +1 -1
  44. data/spec/unit/resource_spec.rb +19 -8
  45. data/spec/unit/secret_fetcher/aws_secrets_manager_spec.rb +70 -0
  46. data/spec/unit/secret_fetcher/azure_key_vault_spec.rb +23 -16
  47. data/spec/unit/secret_fetcher_spec.rb +9 -9
  48. metadata +7 -6
@@ -8,23 +8,30 @@ class Chef
8
8
  # In this initial iteration this authenticates via token obtained from the OAuth2 /token
9
9
  # endpoint.
10
10
  #
11
- # Usage Example:
11
+ # Validation of required configuration (vault name) is not performed until
12
+ # `fetch` time, to allow for embedding the vault name in with the secret
13
+ # name, such as "my_vault/secretkey1".
12
14
  #
13
- # fetcher = SecretFetcher.for_service(:azure_key_vault)
15
+ # @example
16
+ #
17
+ # fetcher = SecretFetcher.for_service(:azure_key_vault, { vault: "my_vault" }, run_context )
14
18
  # fetcher.fetch("secretkey1", "v1")
19
+ #
20
+ # @example
21
+ #
22
+ # fetcher = SecretFetcher.for_service(:azure_key_vault, {}, run_context )
23
+ # fetcher.fetch("my_vault/secretkey1", "v1")
15
24
  class AzureKeyVault < Base
16
- def validate!
17
- @vault = config[:vault]
18
- if @vault.nil?
19
- raise Chef::Exceptions::Secret::MissingVaultName.new("You must provide a vault name to service options as vault: 'vault_name'")
20
- end
21
- end
22
25
 
23
26
  def do_fetch(name, version)
24
27
  token = fetch_token
28
+ vault, name = resolve_vault_and_secret_name(name)
29
+ if vault.nil?
30
+ raise Chef::Exceptions::Secret::ConfigurationInvalid.new("You must provide a vault name to fetcher options as vault: 'vault_name' or in the secret name as 'vault_name/secret_name'")
31
+ end
25
32
 
26
33
  # Note that `version` is optional after the final `/`. If nil/"", the latest secret version will be fetched.
27
- secret_uri = URI.parse("https://#{@vault}.vault.azure.net/secrets/#{name}/#{version}?api-version=7.2")
34
+ secret_uri = URI.parse("https://#{vault}.vault.azure.net/secrets/#{name}/#{version}?api-version=7.2")
28
35
  http = Net::HTTP.new(secret_uri.host, secret_uri.port)
29
36
  http.use_ssl = true
30
37
 
@@ -41,6 +48,21 @@ class Chef
41
48
  end
42
49
  end
43
50
 
51
+ # Determine the vault name and secret name from the provided name.
52
+ # If it is not in the provided name in the form "vault_name/secret_name"
53
+ # it will determine the vault name from `config[:vault]`.
54
+ # @param name [String] the secret name or vault and secret name in the form "vault_name/secret_name"
55
+ # @return Array[String, String] vault and secret name respectively
56
+ def resolve_vault_and_secret_name(name)
57
+ # We support a simplified approach where the vault name is not passed i
58
+ # into configuration, but
59
+ if name.include?("/")
60
+ name.split("/", 2)
61
+ else
62
+ [config[:vault], name]
63
+ end
64
+ end
65
+
44
66
  def fetch_token
45
67
  token_uri = URI.parse("http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net")
46
68
  http = Net::HTTP.new(token_uri.host, token_uri.port)
@@ -25,13 +25,17 @@ class Chef
25
25
  class SecretFetcher
26
26
  class Base
27
27
  attr_reader :config
28
+ # Note that this is only available in the context of a recipe.
29
+ # Since that's the only place it's intended to be used, that's probably OK.
30
+ attr_reader :run_context
28
31
 
29
32
  # Initialize a new SecretFetcher::Base
30
33
  #
31
34
  # @param config [Hash] Configuration hash. Expected configuration keys and values
32
35
  # will vary based on implementation, and are validated in `validate!`.
33
- def initialize(config)
36
+ def initialize(config, run_context)
34
37
  @config = config
38
+ @run_context = run_context
35
39
  end
36
40
 
37
41
  # Fetch the named secret by invoking implementation-specific [Chef::SecretFetcher::Base#do_fetch]
@@ -30,17 +30,18 @@ class Chef
30
30
  # @param service [Symbol] the identifier for the service that will support this request. Must be in
31
31
  # SECRET_FETCHERS
32
32
  # @param config [Hash] configuration that the secrets service requires
33
- def self.for_service(service, config)
33
+ # @param run_context [Chef::RunContext] the run context this is being invoked from
34
+ def self.for_service(service, config, run_context)
34
35
  fetcher = case service
35
36
  when :example
36
37
  require_relative "secret_fetcher/example"
37
- Chef::SecretFetcher::Example.new(config)
38
+ Chef::SecretFetcher::Example.new(config, run_context)
38
39
  when :aws_secrets_manager
39
40
  require_relative "secret_fetcher/aws_secrets_manager"
40
- Chef::SecretFetcher::AWSSecretsManager.new(config)
41
+ Chef::SecretFetcher::AWSSecretsManager.new(config, run_context)
41
42
  when :azure_key_vault
42
43
  require_relative "secret_fetcher/azure_key_vault"
43
- Chef::SecretFetcher::AzureKeyVault.new(config)
44
+ Chef::SecretFetcher::AzureKeyVault.new(config, run_context)
44
45
  when nil, ""
45
46
  raise Chef::Exceptions::Secret::MissingFetcher.new(SECRET_FETCHERS)
46
47
  else
data/lib/chef/version.rb CHANGED
@@ -23,7 +23,7 @@ require_relative "version_string"
23
23
 
24
24
  class Chef
25
25
  CHEF_ROOT = File.expand_path("..", __dir__)
26
- VERSION = Chef::VersionString.new("17.3.48")
26
+ VERSION = Chef::VersionString.new("17.4.25")
27
27
  end
28
28
 
29
29
  #
@@ -47,6 +47,7 @@ describe "chef-client with compliance phase" do
47
47
  {
48
48
  "audit": {
49
49
  "compliance_phase": true,
50
+ "reporter": "json-file",
50
51
  "json_file": {
51
52
  "location": "#{report_file}"
52
53
  },
@@ -354,8 +354,8 @@ module ResourceActionSpec
354
354
  end
355
355
 
356
356
  it "allows overridden action to have a description separate from the action defined in the base resource" do
357
- expect(ActionJackson.action_description(:test1)).to eql "Original description"
358
- expect(ActionJackalope.action_description(:test1)).to eql "An old action with a new description"
357
+ expect(ActionJackson.new("ActionJackson", nil).action_description(:test1)).to eql "Original description"
358
+ expect(ActionJackalope.new("ActionJackalope", nil).action_description(:test1)).to eql "An old action with a new description"
359
359
  end
360
360
 
361
361
  it "non-overridden actions run and can access overridden and non-overridden variables (but not necessarily new ones)" do
@@ -202,6 +202,16 @@ describe Chef::Compliance::Runner do
202
202
  expect { runner.load_and_validate! }.to raise_error(/^CMPL002:/)
203
203
  end
204
204
 
205
+ it "raises CMPL004 if both the inputs and attributes node attributes are set" do
206
+ node.normal["audit"]["attributes"] = {
207
+ "tacos" => "lunch",
208
+ }
209
+ node.normal["audit"]["inputs"] = {
210
+ "tacos" => "lunch",
211
+ }
212
+ expect { runner.load_and_validate! }.to raise_error(/^CMPL011:/)
213
+ end
214
+
205
215
  it "validates configured reporters" do
206
216
  node.normal["audit"]["reporter"] = [ "chef-automate" ]
207
217
  reporter_double = double("reporter", validate_config!: nil)
@@ -212,6 +222,40 @@ describe Chef::Compliance::Runner do
212
222
  end
213
223
 
214
224
  describe "#inspec_opts" do
225
+ it "pulls inputs from the attributes setting" do
226
+ node.normal["audit"]["attributes"] = {
227
+ "tacos" => "lunch",
228
+ }
229
+
230
+ inputs = runner.inspec_opts[:inputs]
231
+
232
+ expect(inputs["tacos"]).to eq("lunch")
233
+ end
234
+
235
+ it "pulls inputs from the inputs setting" do
236
+ node.normal["audit"]["inputs"] = {
237
+ "tacos" => "lunch",
238
+ }
239
+
240
+ inputs = runner.inspec_opts[:inputs]
241
+
242
+ expect(inputs["tacos"]).to eq("lunch")
243
+ end
244
+
245
+ it "favors inputs over attributes" do
246
+ node.normal["audit"]["attributes"] = {
247
+ "tacos" => "dinner",
248
+ }
249
+
250
+ node.normal["audit"]["inputs"] = {
251
+ "tacos" => "lunch",
252
+ }
253
+
254
+ inputs = runner.inspec_opts[:inputs]
255
+
256
+ expect(inputs["tacos"]).to eq("lunch")
257
+ end
258
+
215
259
  it "does not include chef_node in inputs by default" do
216
260
  node.normal["audit"]["attributes"] = {
217
261
  "tacos" => "lunch",
@@ -221,7 +265,7 @@ describe Chef::Compliance::Runner do
221
265
  inputs = runner.inspec_opts[:inputs]
222
266
 
223
267
  expect(inputs["tacos"]).to eq("lunch")
224
- expect(inputs.key?("chef_node")).to eq(false)
268
+ expect(inputs.key?("chef_node")).to eq(true)
225
269
  end
226
270
 
227
271
  it "includes chef_node in inputs with chef_node_attribute_enabled set" do
@@ -234,7 +278,7 @@ describe Chef::Compliance::Runner do
234
278
  inputs = runner.inspec_opts[:inputs]
235
279
 
236
280
  expect(inputs["tacos"]).to eq("lunch")
237
- expect(inputs["chef_node"]["audit"]["reporter"]).to eq(%w{json-file cli})
281
+ expect(inputs["chef_node"]["audit"]["reporter"]).to eq("cli")
238
282
  expect(inputs["chef_node"]["chef_environment"]).to eq("_default")
239
283
  end
240
284
  end
@@ -21,6 +21,12 @@ require "chef/dsl/secret"
21
21
  require "chef/secret_fetcher/base"
22
22
  class SecretDSLTester
23
23
  include Chef::DSL::Secret
24
+ # Because DSL is invoked in the context of a recipe,
25
+ # we expect run_context to always be available when SecretFetcher::Base
26
+ # requests it - making it safe to mock here
27
+ def run_context
28
+ nil
29
+ end
24
30
  end
25
31
 
26
32
  class SecretFetcherImpl < Chef::SecretFetcher::Base
@@ -36,8 +42,8 @@ describe Chef::DSL::Secret do
36
42
  end
37
43
 
38
44
  it "uses SecretFetcher.for_service to find the fetcher" do
39
- substitute_fetcher = SecretFetcherImpl.new({})
40
- expect(Chef::SecretFetcher).to receive(:for_service).with(:example, {}).and_return(substitute_fetcher)
45
+ substitute_fetcher = SecretFetcherImpl.new({}, nil)
46
+ expect(Chef::SecretFetcher).to receive(:for_service).with(:example, {}, nil).and_return(substitute_fetcher)
41
47
  expect(substitute_fetcher).to receive(:fetch).with("key1", nil)
42
48
  dsl.secret(name: "key1", service: :example, config: {})
43
49
  end
@@ -32,6 +32,21 @@ class NoWhyrunDemonstrator < Chef::Provider
32
32
  end
33
33
  end
34
34
 
35
+ class ActionDescriptionDemonstrator < Chef::Provider
36
+ def load_current_resource; end
37
+
38
+ action :foo, description: "foo described" do
39
+ true
40
+ end
41
+
42
+ action :foo2 do
43
+ true
44
+ end
45
+
46
+ end
47
+
48
+ context "blah" do
49
+ end
35
50
  class ConvergeActionDemonstrator < Chef::Provider
36
51
  attr_reader :system_state_altered
37
52
 
@@ -98,6 +113,14 @@ describe Chef::Provider do
98
113
  expect(@provider.action_nothing).to eql(true)
99
114
  end
100
115
 
116
+ it "should return an action description for action_description when one is available" do
117
+ expect(ActionDescriptionDemonstrator.action_description(:foo)).to eq "foo described"
118
+ end
119
+
120
+ it "should return nil for action_description when no description is available" do
121
+ expect(ActionDescriptionDemonstrator.action_description(:none)).to eq nil
122
+ end
123
+
101
124
  it "evals embedded recipes with a pristine resource collection" do
102
125
  @provider.run_context.instance_variable_set(:@resource_collection, "doesn't matter what this is")
103
126
  temporary_collection = nil
@@ -19,22 +19,40 @@ require "spec_helper"
19
19
 
20
20
  describe Chef::Resource::HomebrewCask do
21
21
 
22
- let(:resource) { Chef::Resource::HomebrewCask.new("fakey_fakerton") }
22
+ context "name with under bar" do
23
+ let(:resource) { Chef::Resource::HomebrewCask.new("fakey_fakerton") }
23
24
 
24
- it "has a resource name of :homebrew_cask" do
25
- expect(resource.resource_name).to eql(:homebrew_cask)
26
- end
25
+ it "has a resource name of :homebrew_cask" do
26
+ expect(resource.resource_name).to eql(:homebrew_cask)
27
+ end
28
+
29
+ it "the cask_name property is the name_property" do
30
+ expect(resource.cask_name).to eql("fakey_fakerton")
31
+ end
32
+
33
+ it "sets the default action as :install" do
34
+ expect(resource.action).to eql([:install])
35
+ end
27
36
 
28
- it "the cask_name property is the name_property" do
29
- expect(resource.cask_name).to eql("fakey_fakerton")
37
+ it "supports :install, :remove actions" do
38
+ expect { resource.action :install }.not_to raise_error
39
+ expect { resource.action :remove }.not_to raise_error
40
+ end
30
41
  end
31
42
 
32
- it "sets the default action as :install" do
33
- expect(resource.action).to eql([:install])
43
+ context "name with high fun" do
44
+ let(:resource) { Chef::Resource::HomebrewCask.new("fakey-fakerton") }
45
+
46
+ it "the cask_name property is the name_property" do
47
+ expect(resource.cask_name).to eql("fakey-fakerton")
48
+ end
34
49
  end
35
50
 
36
- it "supports :install, :remove actions" do
37
- expect { resource.action :install }.not_to raise_error
38
- expect { resource.action :remove }.not_to raise_error
51
+ context "name with at mark" do
52
+ let(:resource) { Chef::Resource::HomebrewCask.new("fakey-fakerton@10") }
53
+
54
+ it "the cask_name property is the name_property" do
55
+ expect(resource.cask_name).to eql("fakey-fakerton@10")
56
+ end
39
57
  end
40
58
  end
@@ -18,15 +18,24 @@
18
18
  require "spec_helper"
19
19
 
20
20
  describe Chef::Resource::RhsmSubscription do
21
- let(:resource) { Chef::Resource::RhsmSubscription.new("fakey_fakerton") }
22
- let(:provider) { resource.provider_for_action(:attach) }
21
+ let(:event_dispatch) { Chef::EventDispatch::Dispatcher.new }
22
+ let(:node) { Chef::Node.new }
23
+ let(:run_context) { Chef::RunContext.new(node, {}, event_dispatch) }
24
+
25
+ let(:pool_id) { "8a8dd78c766232550226b46e59404aba" }
26
+ let(:resource) { Chef::Resource::RhsmSubscription.new(pool_id, run_context) }
27
+ let(:provider) { resource.provider_for_action(Array(resource.action).first) }
28
+
29
+ before do
30
+ allow(resource).to receive(:provider_for_action).with(:attach).and_return(provider)
31
+ end
23
32
 
24
33
  it "has a resource name of :rhsm_subscription" do
25
34
  expect(resource.resource_name).to eql(:rhsm_subscription)
26
35
  end
27
36
 
28
37
  it "the pool_id property is the name_property" do
29
- expect(resource.pool_id).to eql("fakey_fakerton")
38
+ expect(resource.pool_id).to eql(pool_id)
30
39
  end
31
40
 
32
41
  it "sets the default action as :attach" do
@@ -38,6 +47,44 @@ describe Chef::Resource::RhsmSubscription do
38
47
  expect { resource.action :remove }.not_to raise_error
39
48
  end
40
49
 
50
+ describe "#action_attach" do
51
+ let(:yum_package_double) { instance_double("Chef::Resource::YumPackage") }
52
+ let(:so_double) { instance_double("Mixlib::ShellOut", stdout: "Successfully attached a subscription for: My Subscription", exitstatus: 0, error?: false) }
53
+
54
+ before do
55
+ allow(provider).to receive(:shell_out!).with("subscription-manager attach --pool=#{resource.pool_id}").and_return(so_double)
56
+ allow(provider).to receive(:build_resource).with(:package, "rhsm_subscription-#{pool_id}-flush_cache").and_return(yum_package_double)
57
+ allow(yum_package_double).to receive(:run_action).with(:flush_cache)
58
+ end
59
+
60
+ context "when already attached to pool" do
61
+ before do
62
+ allow(provider).to receive(:subscription_attached?).with(resource.pool_id).and_return(true)
63
+ end
64
+
65
+ it "does not attach to pool" do
66
+ expect(provider).not_to receive(:shell_out!)
67
+ resource.run_action(:attach)
68
+ end
69
+ end
70
+
71
+ context "when not attached to pool" do
72
+ before do
73
+ allow(provider).to receive(:subscription_attached?).with(resource.pool_id).and_return(false)
74
+ end
75
+
76
+ it "attaches to pool" do
77
+ expect(provider).to receive(:shell_out!).with("subscription-manager attach --pool=#{resource.pool_id}")
78
+ resource.run_action(:attach)
79
+ end
80
+
81
+ it "flushes package provider cache" do
82
+ expect(yum_package_double).to receive(:run_action).with(:flush_cache)
83
+ resource.run_action(:attach)
84
+ end
85
+ end
86
+ end
87
+
41
88
  describe "#subscription_attached?" do
42
89
  let(:cmd) { double("cmd") }
43
90
  let(:output) { "Pool ID: pool123" }
@@ -20,7 +20,7 @@ require "spec_helper"
20
20
 
21
21
  describe Chef::Resource::SystemdUnit do
22
22
  let(:resource) { Chef::Resource::SystemdUnit.new("sysstat-collect.timer") }
23
- let(:unit_content_string) { "[Unit]\nDescription = Run system activity accounting tool every 10 minutes\nDocumentation = foo\nDocumentation = bar\n\n[Timer]\nOnCalendar = *:00/10\n\n[Install]\nWantedBy = sysstat.service\n" }
23
+ let(:unit_content_string) { "[Unit]\nDescription=Run system activity accounting tool every 10 minutes\nDocumentation=foo\nDocumentation=bar\n\n[Timer]\nOnCalendar=*:00/10\n\n[Install]\nWantedBy=sysstat.service\n" }
24
24
  let(:unit_content_hash) do
25
25
  {
26
26
  "Unit" => {
@@ -1172,21 +1172,23 @@ describe Chef::Resource do
1172
1172
  action :base_action3, description: "unmodified base action 3 desc" do; end
1173
1173
  end
1174
1174
 
1175
+ let(:resource_inst) { TestResource.new("TestResource", nil) }
1176
+
1175
1177
  it "returns nil when no description was provided for the action" do
1176
- expect(TestResource.action_description(:base_action0)).to eql(nil)
1178
+ expect(resource_inst.action_description(:base_action0)).to eql(nil)
1177
1179
  end
1178
1180
 
1179
1181
  context "when action definition is a string" do
1180
1182
  it "returns the description whether a symbol or string is used to look it up" do
1181
- expect(TestResource.action_description("string_action")).to eql("a string test")
1182
- expect(TestResource.action_description(:string_action)).to eql("a string test")
1183
+ expect(resource_inst.action_description("string_action")).to eql("a string test")
1184
+ expect(resource_inst.action_description(:string_action)).to eql("a string test")
1183
1185
  end
1184
1186
  end
1185
1187
 
1186
1188
  context "when action definition is a symbol" do
1187
1189
  it "returns the description whether a symbol or string is used to look up" do
1188
- expect(TestResource.action_description("symbol_action")).to eql("a symbol test")
1189
- expect(TestResource.action_description(:symbol_action)).to eql("a symbol test")
1190
+ expect(resource_inst.action_description("symbol_action")).to eql("a symbol test")
1191
+ expect(resource_inst.action_description(:symbol_action)).to eql("a symbol test")
1190
1192
  end
1191
1193
  end
1192
1194
 
@@ -1196,14 +1198,23 @@ describe Chef::Resource do
1196
1198
  action :base_action3 do; end
1197
1199
  end
1198
1200
 
1201
+ class TestResourceChild2 < TestResource
1202
+ # We should never see this description
1203
+ action :base_action2, description: "if you see this in an error, TestResourceChild was polluted with this description" do; end
1204
+ end
1205
+ let(:resource_inst) { TestResourceChild.new("TestResource", nil) }
1206
+
1199
1207
  it "returns original description when a described action is not overridden in child resource" do
1200
- expect(TestResourceChild.action_description(:base_action1)).to eq "unmodified base action 1 desc"
1208
+ expect(resource_inst.action_description(:base_action1)).to eq "unmodified base action 1 desc"
1201
1209
  end
1202
1210
  it "returns original description when the child resource overrides an inherited action but NOT its description" do
1203
- expect(TestResourceChild.action_description(:base_action3)).to eq "unmodified base action 3 desc"
1211
+ expect(resource_inst.action_description(:base_action3)).to eq "unmodified base action 3 desc"
1212
+ end
1213
+ it "returns new description when the child resource overrides an inherited action and its description" do
1214
+ expect(resource_inst.action_description(:base_action2)).to eq "modified base action 2 desc"
1204
1215
  end
1205
1216
  it "returns new description when the child resource overrides an inherited action and its description" do
1206
- expect(TestResourceChild.action_description(:base_action2)).to eq "modified base action 2 desc"
1217
+ expect(resource_inst.action_description(:base_action2)).to eq "modified base action 2 desc"
1207
1218
  end
1208
1219
  end
1209
1220
  end