summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/chef/property.rb8
-rw-r--r--lib/chef/provider.rb11
-rw-r--r--spec/unit/property/validation_spec.rb26
3 files changed, 41 insertions, 4 deletions
diff --git a/lib/chef/property.rb b/lib/chef/property.rb
index eaf1a66e86..d65545c138 100644
--- a/lib/chef/property.rb
+++ b/lib/chef/property.rb
@@ -303,8 +303,12 @@ class Chef
#
# @return [Boolean]
#
- def required?
- options[:required]
+ def required?(action = nil)
+ if !action.nil? && options[:required].is_a?(Array)
+ options[:required].include?(action)
+ else
+ !!options[:required]
+ end
end
#
diff --git a/lib/chef/provider.rb b/lib/chef/provider.rb
index 40bd5a48a1..947a890806 100644
--- a/lib/chef/provider.rb
+++ b/lib/chef/provider.rb
@@ -152,6 +152,7 @@ class Chef
new_resource.cookbook_name
end
+ # hook that subclasses can use to do lazy validation for where properties aren't flexibile enough
def check_resource_semantics!; end
# a simple placeholder method that will be called / raise if a resource tries to
@@ -181,12 +182,20 @@ class Chef
run_context.events
end
+ def validate_required_properties!
+ # all we do is run through all the required properties for this action and vivify them
+ new_resource.class.properties.each { |name, property| property.required?(action) && property.get(new_resource) }
+ end
+
def run_action(action = nil)
@action = action unless action.nil?
- # @todo it would be preferable to get the action to be executed in the constructor...
+ # hook that subclasses can use to do lazy validation for where properties aren't flexibile enough
check_resource_semantics!
+ # force the validation of required properties
+ validate_required_properties!
+
# user-defined LWRPs may include unsafe load_current_resource methods that cannot be run in whyrun mode
if whyrun_mode? && !whyrun_supported?
events.resource_current_state_load_bypassed(@new_resource, @action, @current_resource)
diff --git a/spec/unit/property/validation_spec.rb b/spec/unit/property/validation_spec.rb
index dab2be8000..c8daee1580 100644
--- a/spec/unit/property/validation_spec.rb
+++ b/spec/unit/property/validation_spec.rb
@@ -45,11 +45,22 @@ describe "Chef::Resource.property validation" do
def self.blah
"class#{Namer.next_index}"
end
+
+ action :doit do
+ # this needs to not reference any properties
+ end
+
+ action :doit2 do
+ # this needs to not reference any properties
+ end
end
end
+ let(:node) { Chef::Node.new }
+ let(:events) { Chef::EventDispatch::Dispatcher.new }
+ let(:run_context) { Chef::RunContext.new(node, {}, events) }
let(:resource) do
- resource_class.new("blah")
+ resource_class.new("blah", run_context)
end
def self.english_join(values)
@@ -576,6 +587,19 @@ describe "Chef::Resource.property validation" do
it "value nil emits a validation failed error because it must have a value" do
expect { resource.x nil }.to raise_error Chef::Exceptions::ValidationFailed
end
+ it "fails if it is not specified, on running the action, even if it is not referenced" do
+ expect { resource.run_action(:doit) }.to raise_error Chef::Exceptions::ValidationFailed
+ end
+ end
+
+ with_property ":x, required: %i{doit}" do
+ it "fails if it is not specified, on running the doit action, even if it is not referenced" do
+ expect { resource.run_action(:doit) }.to raise_error Chef::Exceptions::ValidationFailed
+ end
+
+ it "does not fail if it is not specified, on running the doit2 action" do
+ expect { resource.run_action(:doit2) }.not_to raise_error
+ end
end
with_property ":x, String, required: true" do