summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAliasgar16 <aliasgar.batterywala@msystechnologies.com>2017-01-23 21:12:37 +0530
committerBryan McLellan <btm@loftninjas.org>2017-01-23 10:42:37 -0500
commit0d7aac70c39aae2456ca5eba76af2f80057324ad (patch)
treee7559232dbd5886d70c1630847e0739712253248
parent85a6e0f72ef098b6ef47dac3b2833ea66e51f3e1 (diff)
downloadchef-0d7aac70c39aae2456ca5eba76af2f80057324ad.tar.gz
Added module_version attribute for dsc_resource. (#5701)
* Added module_version attribute for dsc_resource. Signed-off-by: aliasgar16 <aliasgar.batterywala@msystechnologies.com>
-rw-r--r--lib/chef/exceptions.rb3
-rw-r--r--lib/chef/provider/dsc_resource.rb18
-rw-r--r--lib/chef/resource/dsc_resource.rb8
-rw-r--r--spec/unit/provider/dsc_resource_spec.rb175
-rw-r--r--spec/unit/resource/dsc_resource_spec.rb6
5 files changed, 209 insertions, 1 deletions
diff --git a/lib/chef/exceptions.rb b/lib/chef/exceptions.rb
index 2d6dcef17e..864268a85e 100644
--- a/lib/chef/exceptions.rb
+++ b/lib/chef/exceptions.rb
@@ -525,5 +525,8 @@ This error is most often caused by network issues (proxies, etc) outside of chef
super "Found multiple matching resources. #{matches_info.join("\n")}"
end
end
+
+ # exception specific to invalid usage of 'dsc_resource' resource
+ class DSCModuleNameMissing < ArgumentError; end
end
end
diff --git a/lib/chef/provider/dsc_resource.rb b/lib/chef/provider/dsc_resource.rb
index 0f25065925..026d2ef104 100644
--- a/lib/chef/provider/dsc_resource.rb
+++ b/lib/chef/provider/dsc_resource.rb
@@ -29,6 +29,7 @@ class Chef
super
@new_resource = new_resource
@module_name = new_resource.module_name
+ @module_version = new_resource.module_version
@reboot_resource = nil
end
@@ -65,6 +66,13 @@ class Chef
a.whyrun err + ["Assuming a previous resource sets the RefreshMode."]
a.block_action!
end
+ requirements.assert(:run) do |a|
+ a.assertion { module_usage_valid? }
+ err = ["module_name must be supplied along with module_version."]
+ a.failure_message Chef::Exceptions::DSCModuleNameMissing,
+ err
+ a.block_action!
+ end
end
protected
@@ -92,6 +100,10 @@ class Chef
Chef::Platform.supports_refresh_mode_enabled?(node)
end
+ def module_usage_valid?
+ !(!@module_name && @module_version)
+ end
+
def generate_description
@converge_description
end
@@ -148,10 +160,14 @@ class Chef
end
end
+ def module_info_object
+ @module_version.nil? ? module_name : "@{ModuleName='#{module_name}';ModuleVersion='#{@module_version}'}"
+ end
+
def invoke_resource(method, output_format = :object)
properties = translate_type(@new_resource.properties)
switches = "-Method #{method} -Name #{@new_resource.resource}"\
- " -Property #{properties} -Module #{module_name} -Verbose"
+ " -Property #{properties} -Module #{module_info_object} -Verbose"
cmdlet = Chef::Util::Powershell::Cmdlet.new(
node,
"Invoke-DscResource #{switches}",
diff --git a/lib/chef/resource/dsc_resource.rb b/lib/chef/resource/dsc_resource.rb
index 58594cce7b..f55f8d2c8c 100644
--- a/lib/chef/resource/dsc_resource.rb
+++ b/lib/chef/resource/dsc_resource.rb
@@ -68,6 +68,14 @@ class Chef
end
end
+ def module_version(arg = nil)
+ set_or_return(
+ :module_version,
+ arg,
+ :kind_of => [ String ]
+ )
+ end
+
def property(property_name, value = nil)
if not property_name.is_a?(Symbol)
raise TypeError, "A property name of type Symbol must be specified, '#{property_name}' of type #{property_name.class} was given"
diff --git a/spec/unit/provider/dsc_resource_spec.rb b/spec/unit/provider/dsc_resource_spec.rb
index 34eb9727f8..96356e5d73 100644
--- a/spec/unit/provider/dsc_resource_spec.rb
+++ b/spec/unit/provider/dsc_resource_spec.rb
@@ -165,4 +165,179 @@ describe Chef::Provider::DscResource do
end
end
end
+
+ describe "define_resource_requirements" do
+ let (:node) do
+ set_node_object
+ end
+
+ context "module usage is valid" do
+ before do
+ allow(provider).to receive(:module_usage_valid?).and_return(true)
+ allow(provider).to receive(:action_run)
+ end
+
+ [:run].each do |action|
+ context "action #{action}" do
+ it "does not raise the exception" do
+ expect { provider.run_action(action) }.not_to raise_error
+ end
+ end
+ end
+ end
+
+ context "module usage is invalid" do
+ before do
+ allow(provider).to receive(:module_usage_valid?).and_return(false)
+ allow(provider).to receive(:action_run)
+ end
+
+ [:run].each do |action|
+ context "action #{action}" do
+ it "raises the exception" do
+ expect { provider.run_action(action) }.to raise_error(
+ Chef::Exceptions::DSCModuleNameMissing
+ )
+ end
+ end
+ end
+ end
+ end
+
+ describe "module_usage_valid?" do
+ let (:node) do
+ set_node_object
+ end
+
+ context "module_name and module_version both are not provided" do
+ before do
+ provider.instance_variable_set(:@module_name, nil)
+ provider.instance_variable_set(:@module_version, nil)
+ end
+
+ it "returns true" do
+ response = provider.send(:module_usage_valid?)
+ expect(response).to be == true
+ end
+ end
+
+ context "module_name and module_version both are provided" do
+ before do
+ provider.instance_variable_set(:@module_name, "my_module")
+ provider.instance_variable_set(:@module_version, "1.3")
+ end
+
+ it "returns true" do
+ response = provider.send(:module_usage_valid?)
+ expect(response).to be == true
+ end
+ end
+
+ context "module_name is given but module_version is not given" do
+ before do
+ provider.instance_variable_set(:@module_name, "my_module")
+ provider.instance_variable_set(:@module_version, nil)
+ end
+
+ it "returns true" do
+ response = provider.send(:module_usage_valid?)
+ expect(response).to be == true
+ end
+ end
+
+ context "module_name is not given but module_version is given" do
+ before do
+ provider.instance_variable_set(:@module_name, nil)
+ provider.instance_variable_set(:@module_version, "1.4.0.1")
+ end
+
+ it "returns false" do
+ response = provider.send(:module_usage_valid?)
+ expect(response).to be == false
+ end
+ end
+ end
+
+ describe "module_info_object" do
+ let (:node) do
+ set_node_object
+ end
+
+ context "module_version is not given" do
+ before do
+ provider.instance_variable_set(:@module_version, nil)
+ allow(provider).to receive(:module_name).and_return("my_module")
+ end
+
+ it "returns only name of the module" do
+ response = provider.send(:module_info_object)
+ expect(response).to be == "my_module"
+ end
+ end
+
+ context "module_version is given" do
+ before do
+ provider.instance_variable_set(:@module_version, "1.3.1")
+ allow(provider).to receive(:module_name).and_return("my_module")
+ end
+
+ it "returns the module info object" do
+ response = provider.send(:module_info_object)
+ expect(response).to be == "@{ModuleName='my_module';ModuleVersion='1.3.1'}"
+ end
+ end
+ end
+
+ describe "invoke_resource" do
+ let (:node) do
+ set_node_object
+ end
+
+ let(:cmdlet) { double(:run! => nil) }
+
+ before(:each) do
+ allow(provider).to receive(:translate_type).and_return("my_properties")
+ provider.instance_variable_set(:@new_resource, double(
+ :properties => "my_properties", :resource => "my_resource", :timeout => 123
+ ))
+ end
+
+ context "when module_version is not given" do
+ before do
+ allow(provider).to receive(:module_info_object).and_return("my_module")
+ end
+
+ it "invokes Invoke-DscResource command with module name" do
+ expect(Chef::Util::Powershell::Cmdlet).to receive(:new).with(
+ node,
+ "Invoke-DscResource -Method my_method -Name my_resource -Property my_properties -Module my_module -Verbose",
+ "my_output_format"
+ ).and_return(cmdlet)
+ provider.send(:invoke_resource, "my_method", "my_output_format")
+ end
+ end
+
+ context "when module_version is given" do
+ before do
+ allow(provider).to receive(:module_info_object).and_return(
+ "@{ModuleName='my_module';ModuleVersion='my_module_version'}"
+ )
+ end
+
+ it "invokes Invoke-DscResource command with module info object" do
+ expect(Chef::Util::Powershell::Cmdlet).to receive(:new).with(
+ node,
+ "Invoke-DscResource -Method my_method -Name my_resource -Property my_properties -Module @{ModuleName='my_module';ModuleVersion='my_module_version'} -Verbose",
+ "my_output_format"
+ ).and_return(cmdlet)
+ provider.send(:invoke_resource, "my_method", "my_output_format")
+ end
+ end
+ end
+end
+
+def set_node_object
+ node = Chef::Node.new
+ node.automatic[:languages][:powershell][:version] = "5.0.10586.0"
+ node
end
diff --git a/spec/unit/resource/dsc_resource_spec.rb b/spec/unit/resource/dsc_resource_spec.rb
index b610c262cc..b687811392 100644
--- a/spec/unit/resource/dsc_resource_spec.rb
+++ b/spec/unit/resource/dsc_resource_spec.rb
@@ -18,6 +18,7 @@
require "spec_helper"
describe Chef::Resource::DscResource do
let(:dsc_test_resource_name) { "DSCTest" }
+ let(:dsc_test_resource_module_version) { "2.7.2" }
let(:dsc_test_property_name) { :DSCTestProperty }
let(:dsc_test_property_value) { "DSCTestValue" }
let(:dsc_test_reboot_action) { :reboot_now }
@@ -53,6 +54,11 @@ describe Chef::Resource::DscResource do
expect(dsc_test_resource.module_name).to eq(dsc_test_resource_name)
end
+ it "allows the module_version attribute to be set" do
+ dsc_test_resource.module_version(dsc_test_resource_module_version)
+ expect(dsc_test_resource.module_version).to eq(dsc_test_resource_module_version)
+ end
+
it "allows the reboot_action attribute to be set" do
dsc_test_resource.reboot_action(dsc_test_reboot_action)
expect(dsc_test_resource.reboot_action).to eq(dsc_test_reboot_action)